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