webcrypto_impl.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/webcrypto/webcrypto_impl.h"
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/webcrypto/crypto_data.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/webcrypto/shared_crypto.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/child/webcrypto/webcrypto_util.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebString.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content {
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using webcrypto::Status;
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(status.IsError());
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.HasErrorDetails())
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result->completeWithError(blink::WebString::fromUTF8(status.ToString()));
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result->completeWithError();
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(padolph): include all other asymmetric algorithms once they are
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // defined, e.g. EC and DH.
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep);
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WebCryptoImpl::WebCryptoImpl() { webcrypto::Init(); }
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WebCryptoImpl::~WebCryptoImpl() {}
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            const blink::WebCryptoKey& key,
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            const unsigned char* data,
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            unsigned int data_size,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            blink::WebCryptoResult result) {
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!algorithm.isNull());
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebArrayBuffer buffer;
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Status status = webcrypto::Encrypt(
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.IsError())
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CompleteWithError(status, &result);
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result.completeWithBuffer(buffer);
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            const blink::WebCryptoKey& key,
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            const unsigned char* data,
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            unsigned int data_size,
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            blink::WebCryptoResult result) {
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!algorithm.isNull());
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebArrayBuffer buffer;
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Status status = webcrypto::Decrypt(
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.IsError())
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CompleteWithError(status, &result);
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result.completeWithBuffer(buffer);
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           const unsigned char* data,
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           unsigned int data_size,
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           blink::WebCryptoResult result) {
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!algorithm.isNull());
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebArrayBuffer buffer;
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Status status = webcrypto::Digest(
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      algorithm, webcrypto::CryptoData(data, data_size), &buffer);
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.IsError())
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CompleteWithError(status, &result);
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result.completeWithBuffer(buffer);
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                bool extractable,
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                blink::WebCryptoKeyUsageMask usage_mask,
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                blink::WebCryptoResult result) {
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!algorithm.isNull());
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (IsAlgorithmAsymmetric(algorithm)) {
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Status status = webcrypto::GenerateKeyPair(
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        algorithm, extractable, usage_mask, &public_key, &private_key);
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (status.IsError()) {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      CompleteWithError(status, &result);
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else {
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(public_key.handle());
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(private_key.handle());
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(algorithm.id(), public_key.algorithm().id());
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(algorithm.id(), private_key.algorithm().id());
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(true, public_key.extractable());
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(extractable, private_key.extractable());
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(usage_mask, public_key.usages());
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(usage_mask, private_key.usages());
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      result.completeWithKeyPair(public_key, private_key);
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Status status =
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        webcrypto::GenerateSecretKey(algorithm, extractable, usage_mask, &key);
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (status.IsError()) {
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      CompleteWithError(status, &result);
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else {
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK(key.handle());
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(algorithm.id(), key.algorithm().id());
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(extractable, key.extractable());
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ(usage_mask, key.usages());
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      result.completeWithKey(key);
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::importKey(
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebCryptoKeyFormat format,
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const unsigned char* key_data,
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    unsigned int key_data_size,
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const blink::WebCryptoAlgorithm& algorithm_or_null,
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool extractable,
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebCryptoKeyUsageMask usage_mask,
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebCryptoResult result) {
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Status status =
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      webcrypto::ImportKey(format,
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           webcrypto::CryptoData(key_data, key_data_size),
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           algorithm_or_null,
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           extractable,
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           usage_mask,
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           &key);
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.IsError()) {
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CompleteWithError(status, &result);
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(key.handle());
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!key.algorithm().isNull());
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(extractable, key.extractable());
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result.completeWithKey(key);
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format,
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              const blink::WebCryptoKey& key,
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              blink::WebCryptoResult result) {
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebArrayBuffer buffer;
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Status status = webcrypto::ExportKey(format, key, &buffer);
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.IsError())
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CompleteWithError(status, &result);
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result.completeWithBuffer(buffer);
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         const blink::WebCryptoKey& key,
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         const unsigned char* data,
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         unsigned int data_size,
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                         blink::WebCryptoResult result) {
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!algorithm.isNull());
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebArrayBuffer buffer;
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Status status = webcrypto::Sign(
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.IsError())
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CompleteWithError(status, &result);
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result.completeWithBuffer(buffer);
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    const blink::WebCryptoKey& key,
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    const unsigned char* signature,
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    unsigned int signature_size,
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    const unsigned char* data,
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    unsigned int data_size,
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    blink::WebCryptoResult result) {
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!algorithm.isNull());
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool signature_match = false;
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Status status = webcrypto::VerifySignature(
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      algorithm,
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      key,
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      webcrypto::CryptoData(signature, signature_size),
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      webcrypto::CryptoData(data, data_size),
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      &signature_match);
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (status.IsError())
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CompleteWithError(status, &result);
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result.completeWithBoolean(signature_match);
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool WebCryptoImpl::digestSynchronous(
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const blink::WebCryptoAlgorithmId algorithm_id,
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const unsigned char* data,
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    unsigned int data_size,
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    blink::WebArrayBuffer& result) {
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  blink::WebCryptoAlgorithm algorithm =
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      blink::WebCryptoAlgorithm::adoptParamsAndCreate(algorithm_id, NULL);
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return (webcrypto::Digest(
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              algorithm, webcrypto::CryptoData(data, data_size), &result))
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      .IsSuccess();
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace content
211