| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/webcrypto/webcrypto_impl.h" | 5 #include "content/renderer/webcrypto/webcrypto_impl.h" |
| 6 | 6 |
| 7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
| 8 #include <pk11pub.h> | 8 #include <pk11pub.h> |
| 9 #include <sechash.h> | 9 #include <sechash.h> |
| 10 | 10 |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "crypto/nss_util.h" | 14 #include "crypto/nss_util.h" |
| 15 #include "crypto/scoped_nss_types.h" | 15 #include "crypto/scoped_nss_types.h" |
| 16 #include "crypto/secure_util.h" | 16 #include "crypto/secure_util.h" |
| 17 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 17 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
| 18 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 18 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
| 19 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 19 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
| 20 | 20 |
| 21 namespace content { | 21 namespace content { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 class SymKeyHandle : public WebKit::WebCryptoKeyHandle { | 25 class SymKeyHandle : public blink::WebCryptoKeyHandle { |
| 26 public: | 26 public: |
| 27 explicit SymKeyHandle(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {} | 27 explicit SymKeyHandle(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {} |
| 28 | 28 |
| 29 PK11SymKey* key() { return key_.get(); } | 29 PK11SymKey* key() { return key_.get(); } |
| 30 | 30 |
| 31 private: | 31 private: |
| 32 crypto::ScopedPK11SymKey key_; | 32 crypto::ScopedPK11SymKey key_; |
| 33 | 33 |
| 34 DISALLOW_COPY_AND_ASSIGN(SymKeyHandle); | 34 DISALLOW_COPY_AND_ASSIGN(SymKeyHandle); |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 class PublicKeyHandle : public WebKit::WebCryptoKeyHandle { | 37 class PublicKeyHandle : public blink::WebCryptoKeyHandle { |
| 38 public: | 38 public: |
| 39 explicit PublicKeyHandle(crypto::ScopedSECKEYPublicKey key) | 39 explicit PublicKeyHandle(crypto::ScopedSECKEYPublicKey key) |
| 40 : key_(key.Pass()) {} | 40 : key_(key.Pass()) {} |
| 41 | 41 |
| 42 SECKEYPublicKey* key() { return key_.get(); } | 42 SECKEYPublicKey* key() { return key_.get(); } |
| 43 | 43 |
| 44 private: | 44 private: |
| 45 crypto::ScopedSECKEYPublicKey key_; | 45 crypto::ScopedSECKEYPublicKey key_; |
| 46 | 46 |
| 47 DISALLOW_COPY_AND_ASSIGN(PublicKeyHandle); | 47 DISALLOW_COPY_AND_ASSIGN(PublicKeyHandle); |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 class PrivateKeyHandle : public WebKit::WebCryptoKeyHandle { | 50 class PrivateKeyHandle : public blink::WebCryptoKeyHandle { |
| 51 public: | 51 public: |
| 52 explicit PrivateKeyHandle(crypto::ScopedSECKEYPrivateKey key) | 52 explicit PrivateKeyHandle(crypto::ScopedSECKEYPrivateKey key) |
| 53 : key_(key.Pass()) {} | 53 : key_(key.Pass()) {} |
| 54 | 54 |
| 55 SECKEYPrivateKey* key() { return key_.get(); } | 55 SECKEYPrivateKey* key() { return key_.get(); } |
| 56 | 56 |
| 57 private: | 57 private: |
| 58 crypto::ScopedSECKEYPrivateKey key_; | 58 crypto::ScopedSECKEYPrivateKey key_; |
| 59 | 59 |
| 60 DISALLOW_COPY_AND_ASSIGN(PrivateKeyHandle); | 60 DISALLOW_COPY_AND_ASSIGN(PrivateKeyHandle); |
| 61 }; | 61 }; |
| 62 | 62 |
| 63 HASH_HashType WebCryptoAlgorithmToNSSHashType( | 63 HASH_HashType WebCryptoAlgorithmToNSSHashType( |
| 64 const WebKit::WebCryptoAlgorithm& algorithm) { | 64 const blink::WebCryptoAlgorithm& algorithm) { |
| 65 switch (algorithm.id()) { | 65 switch (algorithm.id()) { |
| 66 case WebKit::WebCryptoAlgorithmIdSha1: | 66 case blink::WebCryptoAlgorithmIdSha1: |
| 67 return HASH_AlgSHA1; | 67 return HASH_AlgSHA1; |
| 68 case WebKit::WebCryptoAlgorithmIdSha224: | 68 case blink::WebCryptoAlgorithmIdSha224: |
| 69 return HASH_AlgSHA224; | 69 return HASH_AlgSHA224; |
| 70 case WebKit::WebCryptoAlgorithmIdSha256: | 70 case blink::WebCryptoAlgorithmIdSha256: |
| 71 return HASH_AlgSHA256; | 71 return HASH_AlgSHA256; |
| 72 case WebKit::WebCryptoAlgorithmIdSha384: | 72 case blink::WebCryptoAlgorithmIdSha384: |
| 73 return HASH_AlgSHA384; | 73 return HASH_AlgSHA384; |
| 74 case WebKit::WebCryptoAlgorithmIdSha512: | 74 case blink::WebCryptoAlgorithmIdSha512: |
| 75 return HASH_AlgSHA512; | 75 return HASH_AlgSHA512; |
| 76 default: | 76 default: |
| 77 // Not a digest algorithm. | 77 // Not a digest algorithm. |
| 78 return HASH_AlgNULL; | 78 return HASH_AlgNULL; |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| 82 CK_MECHANISM_TYPE WebCryptoAlgorithmToHMACMechanism( | 82 CK_MECHANISM_TYPE WebCryptoAlgorithmToHMACMechanism( |
| 83 const WebKit::WebCryptoAlgorithm& algorithm) { | 83 const blink::WebCryptoAlgorithm& algorithm) { |
| 84 switch (algorithm.id()) { | 84 switch (algorithm.id()) { |
| 85 case WebKit::WebCryptoAlgorithmIdSha1: | 85 case blink::WebCryptoAlgorithmIdSha1: |
| 86 return CKM_SHA_1_HMAC; | 86 return CKM_SHA_1_HMAC; |
| 87 case WebKit::WebCryptoAlgorithmIdSha256: | 87 case blink::WebCryptoAlgorithmIdSha256: |
| 88 return CKM_SHA256_HMAC; | 88 return CKM_SHA256_HMAC; |
| 89 default: | 89 default: |
| 90 // Not a supported algorithm. | 90 // Not a supported algorithm. |
| 91 return CKM_INVALID_MECHANISM; | 91 return CKM_INVALID_MECHANISM; |
| 92 } | 92 } |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool AesCbcEncryptDecrypt( | 95 bool AesCbcEncryptDecrypt( |
| 96 CK_ATTRIBUTE_TYPE operation, | 96 CK_ATTRIBUTE_TYPE operation, |
| 97 const WebKit::WebCryptoAlgorithm& algorithm, | 97 const blink::WebCryptoAlgorithm& algorithm, |
| 98 const WebKit::WebCryptoKey& key, | 98 const blink::WebCryptoKey& key, |
| 99 const unsigned char* data, | 99 const unsigned char* data, |
| 100 unsigned data_size, | 100 unsigned data_size, |
| 101 WebKit::WebArrayBuffer* buffer) { | 101 blink::WebArrayBuffer* buffer) { |
| 102 DCHECK_EQ(WebKit::WebCryptoAlgorithmIdAesCbc, algorithm.id()); | 102 DCHECK_EQ(blink::WebCryptoAlgorithmIdAesCbc, algorithm.id()); |
| 103 DCHECK_EQ(algorithm.id(), key.algorithm().id()); | 103 DCHECK_EQ(algorithm.id(), key.algorithm().id()); |
| 104 DCHECK_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); | 104 DCHECK_EQ(blink::WebCryptoKeyTypeSecret, key.type()); |
| 105 DCHECK(operation == CKA_ENCRYPT || operation == CKA_DECRYPT); | 105 DCHECK(operation == CKA_ENCRYPT || operation == CKA_DECRYPT); |
| 106 | 106 |
| 107 SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); | 107 SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); |
| 108 | 108 |
| 109 const WebKit::WebCryptoAesCbcParams* params = algorithm.aesCbcParams(); | 109 const blink::WebCryptoAesCbcParams* params = algorithm.aesCbcParams(); |
| 110 if (params->iv().size() != AES_BLOCK_SIZE) | 110 if (params->iv().size() != AES_BLOCK_SIZE) |
| 111 return false; | 111 return false; |
| 112 | 112 |
| 113 SECItem iv_item; | 113 SECItem iv_item; |
| 114 iv_item.type = siBuffer; | 114 iv_item.type = siBuffer; |
| 115 iv_item.data = const_cast<unsigned char*>(params->iv().data()); | 115 iv_item.data = const_cast<unsigned char*>(params->iv().data()); |
| 116 iv_item.len = params->iv().size(); | 116 iv_item.len = params->iv().size(); |
| 117 | 117 |
| 118 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); | 118 crypto::ScopedSECItem param(PK11_ParamFromIV(CKM_AES_CBC_PAD, &iv_item)); |
| 119 if (!param) | 119 if (!param) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 141 if (operation == CKA_DECRYPT && | 141 if (operation == CKA_DECRYPT && |
| 142 (data_size == 0 || (data_size % AES_BLOCK_SIZE != 0))) { | 142 (data_size == 0 || (data_size % AES_BLOCK_SIZE != 0))) { |
| 143 return false; | 143 return false; |
| 144 } | 144 } |
| 145 | 145 |
| 146 // TODO(eroman): Refine the output buffer size. It can be computed exactly for | 146 // TODO(eroman): Refine the output buffer size. It can be computed exactly for |
| 147 // encryption, and can be smaller for decryption. | 147 // encryption, and can be smaller for decryption. |
| 148 unsigned output_max_len = data_size + AES_BLOCK_SIZE; | 148 unsigned output_max_len = data_size + AES_BLOCK_SIZE; |
| 149 CHECK_GT(output_max_len, data_size); | 149 CHECK_GT(output_max_len, data_size); |
| 150 | 150 |
| 151 *buffer = WebKit::WebArrayBuffer::create(output_max_len, 1); | 151 *buffer = blink::WebArrayBuffer::create(output_max_len, 1); |
| 152 | 152 |
| 153 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); | 153 unsigned char* buffer_data = reinterpret_cast<unsigned char*>(buffer->data()); |
| 154 | 154 |
| 155 int output_len; | 155 int output_len; |
| 156 if (SECSuccess != PK11_CipherOp(context.get(), | 156 if (SECSuccess != PK11_CipherOp(context.get(), |
| 157 buffer_data, | 157 buffer_data, |
| 158 &output_len, | 158 &output_len, |
| 159 buffer->byteLength(), | 159 buffer->byteLength(), |
| 160 data, | 160 data, |
| 161 data_size)) { | 161 data_size)) { |
| 162 return false; | 162 return false; |
| 163 } | 163 } |
| 164 | 164 |
| 165 unsigned int final_output_chunk_len; | 165 unsigned int final_output_chunk_len; |
| 166 if (SECSuccess != PK11_DigestFinal(context.get(), | 166 if (SECSuccess != PK11_DigestFinal(context.get(), |
| 167 buffer_data + output_len, | 167 buffer_data + output_len, |
| 168 &final_output_chunk_len, | 168 &final_output_chunk_len, |
| 169 output_max_len - output_len)) { | 169 output_max_len - output_len)) { |
| 170 return false; | 170 return false; |
| 171 } | 171 } |
| 172 | 172 |
| 173 WebCryptoImpl::ShrinkBuffer(buffer, final_output_chunk_len + output_len); | 173 WebCryptoImpl::ShrinkBuffer(buffer, final_output_chunk_len + output_len); |
| 174 return true; | 174 return true; |
| 175 } | 175 } |
| 176 | 176 |
| 177 CK_MECHANISM_TYPE HmacAlgorithmToGenMechanism( | 177 CK_MECHANISM_TYPE HmacAlgorithmToGenMechanism( |
| 178 const WebKit::WebCryptoAlgorithm& algorithm) { | 178 const blink::WebCryptoAlgorithm& algorithm) { |
| 179 DCHECK_EQ(algorithm.id(), WebKit::WebCryptoAlgorithmIdHmac); | 179 DCHECK_EQ(algorithm.id(), blink::WebCryptoAlgorithmIdHmac); |
| 180 const WebKit::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); | 180 const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); |
| 181 DCHECK(params); | 181 DCHECK(params); |
| 182 switch (params->hash().id()) { | 182 switch (params->hash().id()) { |
| 183 case WebKit::WebCryptoAlgorithmIdSha1: | 183 case blink::WebCryptoAlgorithmIdSha1: |
| 184 return CKM_SHA_1_HMAC; | 184 return CKM_SHA_1_HMAC; |
| 185 case WebKit::WebCryptoAlgorithmIdSha256: | 185 case blink::WebCryptoAlgorithmIdSha256: |
| 186 return CKM_SHA256_HMAC; | 186 return CKM_SHA256_HMAC; |
| 187 default: | 187 default: |
| 188 return CKM_INVALID_MECHANISM; | 188 return CKM_INVALID_MECHANISM; |
| 189 } | 189 } |
| 190 } | 190 } |
| 191 | 191 |
| 192 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( | 192 CK_MECHANISM_TYPE WebCryptoAlgorithmToGenMechanism( |
| 193 const WebKit::WebCryptoAlgorithm& algorithm) { | 193 const blink::WebCryptoAlgorithm& algorithm) { |
| 194 switch (algorithm.id()) { | 194 switch (algorithm.id()) { |
| 195 case WebKit::WebCryptoAlgorithmIdAesCbc: | 195 case blink::WebCryptoAlgorithmIdAesCbc: |
| 196 return CKM_AES_KEY_GEN; | 196 return CKM_AES_KEY_GEN; |
| 197 case WebKit::WebCryptoAlgorithmIdHmac: | 197 case blink::WebCryptoAlgorithmIdHmac: |
| 198 return HmacAlgorithmToGenMechanism(algorithm); | 198 return HmacAlgorithmToGenMechanism(algorithm); |
| 199 default: | 199 default: |
| 200 return CKM_INVALID_MECHANISM; | 200 return CKM_INVALID_MECHANISM; |
| 201 } | 201 } |
| 202 } | 202 } |
| 203 | 203 |
| 204 unsigned int WebCryptoHmacAlgorithmToBlockSize( | 204 unsigned int WebCryptoHmacAlgorithmToBlockSize( |
| 205 const WebKit::WebCryptoAlgorithm& algorithm) { | 205 const blink::WebCryptoAlgorithm& algorithm) { |
| 206 DCHECK_EQ(algorithm.id(), WebKit::WebCryptoAlgorithmIdHmac); | 206 DCHECK_EQ(algorithm.id(), blink::WebCryptoAlgorithmIdHmac); |
| 207 const WebKit::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); | 207 const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); |
| 208 DCHECK(params); | 208 DCHECK(params); |
| 209 switch (params->hash().id()) { | 209 switch (params->hash().id()) { |
| 210 case WebKit::WebCryptoAlgorithmIdSha1: | 210 case blink::WebCryptoAlgorithmIdSha1: |
| 211 return 512; | 211 return 512; |
| 212 case WebKit::WebCryptoAlgorithmIdSha256: | 212 case blink::WebCryptoAlgorithmIdSha256: |
| 213 return 512; | 213 return 512; |
| 214 default: | 214 default: |
| 215 return 0; | 215 return 0; |
| 216 } | 216 } |
| 217 } | 217 } |
| 218 | 218 |
| 219 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, | 219 // Converts a (big-endian) WebCrypto BigInteger, with or without leading zeros, |
| 220 // to unsigned long. | 220 // to unsigned long. |
| 221 bool BigIntegerToLong(const uint8* data, | 221 bool BigIntegerToLong(const uint8* data, |
| 222 unsigned data_size, | 222 unsigned data_size, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 238 return true; | 238 return true; |
| 239 } | 239 } |
| 240 | 240 |
| 241 } // namespace | 241 } // namespace |
| 242 | 242 |
| 243 void WebCryptoImpl::Init() { | 243 void WebCryptoImpl::Init() { |
| 244 crypto::EnsureNSSInit(); | 244 crypto::EnsureNSSInit(); |
| 245 } | 245 } |
| 246 | 246 |
| 247 bool WebCryptoImpl::EncryptInternal( | 247 bool WebCryptoImpl::EncryptInternal( |
| 248 const WebKit::WebCryptoAlgorithm& algorithm, | 248 const blink::WebCryptoAlgorithm& algorithm, |
| 249 const WebKit::WebCryptoKey& key, | 249 const blink::WebCryptoKey& key, |
| 250 const unsigned char* data, | 250 const unsigned char* data, |
| 251 unsigned data_size, | 251 unsigned data_size, |
| 252 WebKit::WebArrayBuffer* buffer) { | 252 blink::WebArrayBuffer* buffer) { |
| 253 if (algorithm.id() == WebKit::WebCryptoAlgorithmIdAesCbc) { | 253 if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { |
| 254 return AesCbcEncryptDecrypt( | 254 return AesCbcEncryptDecrypt( |
| 255 CKA_ENCRYPT, algorithm, key, data, data_size, buffer); | 255 CKA_ENCRYPT, algorithm, key, data, data_size, buffer); |
| 256 } | 256 } |
| 257 | 257 |
| 258 return false; | 258 return false; |
| 259 } | 259 } |
| 260 | 260 |
| 261 bool WebCryptoImpl::DecryptInternal( | 261 bool WebCryptoImpl::DecryptInternal( |
| 262 const WebKit::WebCryptoAlgorithm& algorithm, | 262 const blink::WebCryptoAlgorithm& algorithm, |
| 263 const WebKit::WebCryptoKey& key, | 263 const blink::WebCryptoKey& key, |
| 264 const unsigned char* data, | 264 const unsigned char* data, |
| 265 unsigned data_size, | 265 unsigned data_size, |
| 266 WebKit::WebArrayBuffer* buffer) { | 266 blink::WebArrayBuffer* buffer) { |
| 267 if (algorithm.id() == WebKit::WebCryptoAlgorithmIdAesCbc) { | 267 if (algorithm.id() == blink::WebCryptoAlgorithmIdAesCbc) { |
| 268 return AesCbcEncryptDecrypt( | 268 return AesCbcEncryptDecrypt( |
| 269 CKA_DECRYPT, algorithm, key, data, data_size, buffer); | 269 CKA_DECRYPT, algorithm, key, data, data_size, buffer); |
| 270 } | 270 } |
| 271 | 271 |
| 272 return false; | 272 return false; |
| 273 } | 273 } |
| 274 | 274 |
| 275 bool WebCryptoImpl::DigestInternal( | 275 bool WebCryptoImpl::DigestInternal( |
| 276 const WebKit::WebCryptoAlgorithm& algorithm, | 276 const blink::WebCryptoAlgorithm& algorithm, |
| 277 const unsigned char* data, | 277 const unsigned char* data, |
| 278 unsigned data_size, | 278 unsigned data_size, |
| 279 WebKit::WebArrayBuffer* buffer) { | 279 blink::WebArrayBuffer* buffer) { |
| 280 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); | 280 HASH_HashType hash_type = WebCryptoAlgorithmToNSSHashType(algorithm); |
| 281 if (hash_type == HASH_AlgNULL) { | 281 if (hash_type == HASH_AlgNULL) { |
| 282 return false; | 282 return false; |
| 283 } | 283 } |
| 284 | 284 |
| 285 HASHContext* context = HASH_Create(hash_type); | 285 HASHContext* context = HASH_Create(hash_type); |
| 286 if (!context) { | 286 if (!context) { |
| 287 return false; | 287 return false; |
| 288 } | 288 } |
| 289 | 289 |
| 290 HASH_Begin(context); | 290 HASH_Begin(context); |
| 291 | 291 |
| 292 HASH_Update(context, data, data_size); | 292 HASH_Update(context, data, data_size); |
| 293 | 293 |
| 294 unsigned hash_result_length = HASH_ResultLenContext(context); | 294 unsigned hash_result_length = HASH_ResultLenContext(context); |
| 295 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); | 295 DCHECK_LE(hash_result_length, static_cast<size_t>(HASH_LENGTH_MAX)); |
| 296 | 296 |
| 297 *buffer = WebKit::WebArrayBuffer::create(hash_result_length, 1); | 297 *buffer = blink::WebArrayBuffer::create(hash_result_length, 1); |
| 298 | 298 |
| 299 unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data()); | 299 unsigned char* digest = reinterpret_cast<unsigned char*>(buffer->data()); |
| 300 | 300 |
| 301 unsigned result_length = 0; | 301 unsigned result_length = 0; |
| 302 HASH_End(context, digest, &result_length, hash_result_length); | 302 HASH_End(context, digest, &result_length, hash_result_length); |
| 303 | 303 |
| 304 HASH_Destroy(context); | 304 HASH_Destroy(context); |
| 305 | 305 |
| 306 return result_length == hash_result_length; | 306 return result_length == hash_result_length; |
| 307 } | 307 } |
| 308 | 308 |
| 309 bool WebCryptoImpl::GenerateKeyInternal( | 309 bool WebCryptoImpl::GenerateKeyInternal( |
| 310 const WebKit::WebCryptoAlgorithm& algorithm, | 310 const blink::WebCryptoAlgorithm& algorithm, |
| 311 bool extractable, | 311 bool extractable, |
| 312 WebKit::WebCryptoKeyUsageMask usage_mask, | 312 blink::WebCryptoKeyUsageMask usage_mask, |
| 313 WebKit::WebCryptoKey* key) { | 313 blink::WebCryptoKey* key) { |
| 314 | 314 |
| 315 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); | 315 CK_MECHANISM_TYPE mech = WebCryptoAlgorithmToGenMechanism(algorithm); |
| 316 unsigned int keylen_bytes = 0; | 316 unsigned int keylen_bytes = 0; |
| 317 WebKit::WebCryptoKeyType key_type = WebKit::WebCryptoKeyTypeSecret; | 317 blink::WebCryptoKeyType key_type = blink::WebCryptoKeyTypeSecret; |
| 318 | 318 |
| 319 if (mech == CKM_INVALID_MECHANISM) { | 319 if (mech == CKM_INVALID_MECHANISM) { |
| 320 return false; | 320 return false; |
| 321 } | 321 } |
| 322 | 322 |
| 323 switch (algorithm.id()) { | 323 switch (algorithm.id()) { |
| 324 case WebKit::WebCryptoAlgorithmIdAesCbc: { | 324 case blink::WebCryptoAlgorithmIdAesCbc: { |
| 325 const WebKit::WebCryptoAesKeyGenParams* params = | 325 const blink::WebCryptoAesKeyGenParams* params = |
| 326 algorithm.aesKeyGenParams(); | 326 algorithm.aesKeyGenParams(); |
| 327 DCHECK(params); | 327 DCHECK(params); |
| 328 keylen_bytes = params->length() / 8; | 328 keylen_bytes = params->length() / 8; |
| 329 if (params->length() % 8) | 329 if (params->length() % 8) |
| 330 return false; | 330 return false; |
| 331 key_type = WebKit::WebCryptoKeyTypeSecret; | 331 key_type = blink::WebCryptoKeyTypeSecret; |
| 332 break; | 332 break; |
| 333 } | 333 } |
| 334 case WebKit::WebCryptoAlgorithmIdHmac: { | 334 case blink::WebCryptoAlgorithmIdHmac: { |
| 335 const WebKit::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); | 335 const blink::WebCryptoHmacKeyParams* params = algorithm.hmacKeyParams(); |
| 336 DCHECK(params); | 336 DCHECK(params); |
| 337 if (!params->getLength(keylen_bytes)) { | 337 if (!params->getLength(keylen_bytes)) { |
| 338 keylen_bytes = WebCryptoHmacAlgorithmToBlockSize(algorithm) / 8; | 338 keylen_bytes = WebCryptoHmacAlgorithmToBlockSize(algorithm) / 8; |
| 339 } | 339 } |
| 340 | 340 |
| 341 key_type = WebKit::WebCryptoKeyTypeSecret; | 341 key_type = blink::WebCryptoKeyTypeSecret; |
| 342 break; | 342 break; |
| 343 } | 343 } |
| 344 | 344 |
| 345 default: { | 345 default: { |
| 346 return false; | 346 return false; |
| 347 } | 347 } |
| 348 } | 348 } |
| 349 | 349 |
| 350 if (keylen_bytes == 0) { | 350 if (keylen_bytes == 0) { |
| 351 return false; | 351 return false; |
| 352 } | 352 } |
| 353 | 353 |
| 354 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 354 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| 355 if (!slot) { | 355 if (!slot) { |
| 356 return false; | 356 return false; |
| 357 } | 357 } |
| 358 | 358 |
| 359 crypto::ScopedPK11SymKey pk11_key( | 359 crypto::ScopedPK11SymKey pk11_key( |
| 360 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); | 360 PK11_KeyGen(slot.get(), mech, NULL, keylen_bytes, NULL)); |
| 361 | 361 |
| 362 if (!pk11_key) { | 362 if (!pk11_key) { |
| 363 return false; | 363 return false; |
| 364 } | 364 } |
| 365 | 365 |
| 366 *key = WebKit::WebCryptoKey::create( | 366 *key = blink::WebCryptoKey::create( |
| 367 new SymKeyHandle(pk11_key.Pass()), | 367 new SymKeyHandle(pk11_key.Pass()), |
| 368 key_type, extractable, algorithm, usage_mask); | 368 key_type, extractable, algorithm, usage_mask); |
| 369 return true; | 369 return true; |
| 370 } | 370 } |
| 371 | 371 |
| 372 bool WebCryptoImpl::GenerateKeyPairInternal( | 372 bool WebCryptoImpl::GenerateKeyPairInternal( |
| 373 const WebKit::WebCryptoAlgorithm& algorithm, | 373 const blink::WebCryptoAlgorithm& algorithm, |
| 374 bool extractable, | 374 bool extractable, |
| 375 WebKit::WebCryptoKeyUsageMask usage_mask, | 375 blink::WebCryptoKeyUsageMask usage_mask, |
| 376 WebKit::WebCryptoKey* public_key, | 376 blink::WebCryptoKey* public_key, |
| 377 WebKit::WebCryptoKey* private_key) { | 377 blink::WebCryptoKey* private_key) { |
| 378 | 378 |
| 379 // TODO(padolph): Handle other asymmetric algorithm key generation. | 379 // TODO(padolph): Handle other asymmetric algorithm key generation. |
| 380 switch (algorithm.id()) { | 380 switch (algorithm.id()) { |
| 381 case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 381 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 382 case WebKit::WebCryptoAlgorithmIdRsaOaep: | 382 case blink::WebCryptoAlgorithmIdRsaOaep: |
| 383 case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: { | 383 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: { |
| 384 const WebKit::WebCryptoRsaKeyGenParams* const params = | 384 const blink::WebCryptoRsaKeyGenParams* const params = |
| 385 algorithm.rsaKeyGenParams(); | 385 algorithm.rsaKeyGenParams(); |
| 386 DCHECK(params); | 386 DCHECK(params); |
| 387 | 387 |
| 388 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); | 388 crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot()); |
| 389 unsigned long public_exponent; | 389 unsigned long public_exponent; |
| 390 if (!slot || !params->modulusLength() || | 390 if (!slot || !params->modulusLength() || |
| 391 !BigIntegerToLong(params->publicExponent().data(), | 391 !BigIntegerToLong(params->publicExponent().data(), |
| 392 params->publicExponent().size(), | 392 params->publicExponent().size(), |
| 393 &public_exponent) || | 393 &public_exponent) || |
| 394 !public_exponent) { | 394 !public_exponent) { |
| 395 return false; | 395 return false; |
| 396 } | 396 } |
| 397 | 397 |
| 398 PK11RSAGenParams rsa_gen_params; | 398 PK11RSAGenParams rsa_gen_params; |
| 399 rsa_gen_params.keySizeInBits = params->modulusLength(); | 399 rsa_gen_params.keySizeInBits = params->modulusLength(); |
| 400 rsa_gen_params.pe = public_exponent; | 400 rsa_gen_params.pe = public_exponent; |
| 401 | 401 |
| 402 // Flags are verified at the Blink layer; here the flags are set to all | 402 // Flags are verified at the Blink layer; here the flags are set to all |
| 403 // possible operations for the given key type. | 403 // possible operations for the given key type. |
| 404 CK_FLAGS operation_flags; | 404 CK_FLAGS operation_flags; |
| 405 switch (algorithm.id()) { | 405 switch (algorithm.id()) { |
| 406 case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: | 406 case blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5: |
| 407 case WebKit::WebCryptoAlgorithmIdRsaOaep: | 407 case blink::WebCryptoAlgorithmIdRsaOaep: |
| 408 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; | 408 operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP; |
| 409 break; | 409 break; |
| 410 case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | 410 case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: |
| 411 operation_flags = CKF_SIGN | CKF_VERIFY; | 411 operation_flags = CKF_SIGN | CKF_VERIFY; |
| 412 break; | 412 break; |
| 413 default: | 413 default: |
| 414 NOTREACHED(); | 414 NOTREACHED(); |
| 415 return false; | 415 return false; |
| 416 } | 416 } |
| 417 const CK_FLAGS operation_flags_mask = CKF_ENCRYPT | CKF_DECRYPT | | 417 const CK_FLAGS operation_flags_mask = CKF_ENCRYPT | CKF_DECRYPT | |
| 418 CKF_SIGN | CKF_VERIFY | CKF_WRAP | | 418 CKF_SIGN | CKF_VERIFY | CKF_WRAP | |
| 419 CKF_UNWRAP; | 419 CKF_UNWRAP; |
| 420 const PK11AttrFlags attribute_flags = 0; // Default all PK11_ATTR_ flags. | 420 const PK11AttrFlags attribute_flags = 0; // Default all PK11_ATTR_ flags. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 434 if (!private_key) { | 434 if (!private_key) { |
| 435 return false; | 435 return false; |
| 436 } | 436 } |
| 437 | 437 |
| 438 // One extractable input parameter is provided, and the Web Crypto API | 438 // One extractable input parameter is provided, and the Web Crypto API |
| 439 // spec at this time says it applies to both members of the key pair. | 439 // spec at this time says it applies to both members of the key pair. |
| 440 // This is probably not correct: it makes more operational sense to have | 440 // This is probably not correct: it makes more operational sense to have |
| 441 // extractable apply only to the private key and make the public key | 441 // extractable apply only to the private key and make the public key |
| 442 // always extractable. For now implement what the spec says and track the | 442 // always extractable. For now implement what the spec says and track the |
| 443 // spec bug here: https://www.w3.org/Bugs/Public/show_bug.cgi?id=23695 | 443 // spec bug here: https://www.w3.org/Bugs/Public/show_bug.cgi?id=23695 |
| 444 *public_key = WebKit::WebCryptoKey::create( | 444 *public_key = blink::WebCryptoKey::create( |
| 445 new PublicKeyHandle(crypto::ScopedSECKEYPublicKey(sec_public_key)), | 445 new PublicKeyHandle(crypto::ScopedSECKEYPublicKey(sec_public_key)), |
| 446 WebKit::WebCryptoKeyTypePublic, | 446 blink::WebCryptoKeyTypePublic, |
| 447 extractable, // probably should be 'true' always | 447 extractable, // probably should be 'true' always |
| 448 algorithm, | 448 algorithm, |
| 449 usage_mask); | 449 usage_mask); |
| 450 *private_key = WebKit::WebCryptoKey::create( | 450 *private_key = blink::WebCryptoKey::create( |
| 451 new PrivateKeyHandle(scoped_sec_private_key.Pass()), | 451 new PrivateKeyHandle(scoped_sec_private_key.Pass()), |
| 452 WebKit::WebCryptoKeyTypePrivate, | 452 blink::WebCryptoKeyTypePrivate, |
| 453 extractable, | 453 extractable, |
| 454 algorithm, | 454 algorithm, |
| 455 usage_mask); | 455 usage_mask); |
| 456 | 456 |
| 457 return true; | 457 return true; |
| 458 } | 458 } |
| 459 default: | 459 default: |
| 460 return false; | 460 return false; |
| 461 } | 461 } |
| 462 } | 462 } |
| 463 | 463 |
| 464 bool WebCryptoImpl::ImportKeyInternal( | 464 bool WebCryptoImpl::ImportKeyInternal( |
| 465 WebKit::WebCryptoKeyFormat format, | 465 blink::WebCryptoKeyFormat format, |
| 466 const unsigned char* key_data, | 466 const unsigned char* key_data, |
| 467 unsigned key_data_size, | 467 unsigned key_data_size, |
| 468 const WebKit::WebCryptoAlgorithm& algorithm_or_null, | 468 const blink::WebCryptoAlgorithm& algorithm_or_null, |
| 469 bool extractable, | 469 bool extractable, |
| 470 WebKit::WebCryptoKeyUsageMask usage_mask, | 470 blink::WebCryptoKeyUsageMask usage_mask, |
| 471 WebKit::WebCryptoKey* key) { | 471 blink::WebCryptoKey* key) { |
| 472 // TODO(eroman): Currently expects algorithm to always be specified, as it is | 472 // TODO(eroman): Currently expects algorithm to always be specified, as it is |
| 473 // required for raw format. | 473 // required for raw format. |
| 474 if (algorithm_or_null.isNull()) | 474 if (algorithm_or_null.isNull()) |
| 475 return false; | 475 return false; |
| 476 const WebKit::WebCryptoAlgorithm& algorithm = algorithm_or_null; | 476 const blink::WebCryptoAlgorithm& algorithm = algorithm_or_null; |
| 477 | 477 |
| 478 WebKit::WebCryptoKeyType type; | 478 blink::WebCryptoKeyType type; |
| 479 switch (algorithm.id()) { | 479 switch (algorithm.id()) { |
| 480 case WebKit::WebCryptoAlgorithmIdHmac: | 480 case blink::WebCryptoAlgorithmIdHmac: |
| 481 case WebKit::WebCryptoAlgorithmIdAesCbc: | 481 case blink::WebCryptoAlgorithmIdAesCbc: |
| 482 type = WebKit::WebCryptoKeyTypeSecret; | 482 type = blink::WebCryptoKeyTypeSecret; |
| 483 break; | 483 break; |
| 484 // TODO(bryaneyler): Support more key types. | 484 // TODO(bryaneyler): Support more key types. |
| 485 default: | 485 default: |
| 486 return false; | 486 return false; |
| 487 } | 487 } |
| 488 | 488 |
| 489 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. | 489 // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. |
| 490 // Currently only supporting symmetric. | 490 // Currently only supporting symmetric. |
| 491 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; | 491 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
| 492 // Flags are verified at the Blink layer; here the flags are set to all | 492 // Flags are verified at the Blink layer; here the flags are set to all |
| 493 // possible operations for this key type. | 493 // possible operations for this key type. |
| 494 CK_FLAGS flags = 0; | 494 CK_FLAGS flags = 0; |
| 495 | 495 |
| 496 switch(algorithm.id()) { | 496 switch(algorithm.id()) { |
| 497 case WebKit::WebCryptoAlgorithmIdHmac: { | 497 case blink::WebCryptoAlgorithmIdHmac: { |
| 498 const WebKit::WebCryptoHmacParams* params = algorithm.hmacParams(); | 498 const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); |
| 499 if (!params) { | 499 if (!params) { |
| 500 return false; | 500 return false; |
| 501 } | 501 } |
| 502 | 502 |
| 503 mechanism = WebCryptoAlgorithmToHMACMechanism(params->hash()); | 503 mechanism = WebCryptoAlgorithmToHMACMechanism(params->hash()); |
| 504 if (mechanism == CKM_INVALID_MECHANISM) { | 504 if (mechanism == CKM_INVALID_MECHANISM) { |
| 505 return false; | 505 return false; |
| 506 } | 506 } |
| 507 | 507 |
| 508 flags |= CKF_SIGN | CKF_VERIFY; | 508 flags |= CKF_SIGN | CKF_VERIFY; |
| 509 | 509 |
| 510 break; | 510 break; |
| 511 } | 511 } |
| 512 case WebKit::WebCryptoAlgorithmIdAesCbc: { | 512 case blink::WebCryptoAlgorithmIdAesCbc: { |
| 513 mechanism = CKM_AES_CBC; | 513 mechanism = CKM_AES_CBC; |
| 514 flags |= CKF_ENCRYPT | CKF_DECRYPT; | 514 flags |= CKF_ENCRYPT | CKF_DECRYPT; |
| 515 break; | 515 break; |
| 516 } | 516 } |
| 517 default: | 517 default: |
| 518 return false; | 518 return false; |
| 519 } | 519 } |
| 520 | 520 |
| 521 DCHECK_NE(CKM_INVALID_MECHANISM, mechanism); | 521 DCHECK_NE(CKM_INVALID_MECHANISM, mechanism); |
| 522 DCHECK_NE(0ul, flags); | 522 DCHECK_NE(0ul, flags); |
| 523 | 523 |
| 524 SECItem key_item = { siBuffer, NULL, 0 }; | 524 SECItem key_item = { siBuffer, NULL, 0 }; |
| 525 | 525 |
| 526 switch (format) { | 526 switch (format) { |
| 527 case WebKit::WebCryptoKeyFormatRaw: | 527 case blink::WebCryptoKeyFormatRaw: |
| 528 key_item.data = const_cast<unsigned char*>(key_data); | 528 key_item.data = const_cast<unsigned char*>(key_data); |
| 529 key_item.len = key_data_size; | 529 key_item.len = key_data_size; |
| 530 break; | 530 break; |
| 531 // TODO(bryaneyler): Handle additional formats. | 531 // TODO(bryaneyler): Handle additional formats. |
| 532 default: | 532 default: |
| 533 return false; | 533 return false; |
| 534 } | 534 } |
| 535 | 535 |
| 536 crypto::ScopedPK11SymKey pk11_sym_key( | 536 crypto::ScopedPK11SymKey pk11_sym_key( |
| 537 PK11_ImportSymKeyWithFlags(PK11_GetInternalSlot(), | 537 PK11_ImportSymKeyWithFlags(PK11_GetInternalSlot(), |
| 538 mechanism, | 538 mechanism, |
| 539 PK11_OriginUnwrap, | 539 PK11_OriginUnwrap, |
| 540 CKA_FLAGS_ONLY, | 540 CKA_FLAGS_ONLY, |
| 541 &key_item, | 541 &key_item, |
| 542 flags, | 542 flags, |
| 543 false, | 543 false, |
| 544 NULL)); | 544 NULL)); |
| 545 if (!pk11_sym_key.get()) { | 545 if (!pk11_sym_key.get()) { |
| 546 return false; | 546 return false; |
| 547 } | 547 } |
| 548 | 548 |
| 549 *key = WebKit::WebCryptoKey::create(new SymKeyHandle(pk11_sym_key.Pass()), | 549 *key = blink::WebCryptoKey::create(new SymKeyHandle(pk11_sym_key.Pass()), |
| 550 type, extractable, algorithm, usage_mask); | 550 type, extractable, algorithm, usage_mask); |
| 551 return true; | 551 return true; |
| 552 } | 552 } |
| 553 | 553 |
| 554 bool WebCryptoImpl::SignInternal( | 554 bool WebCryptoImpl::SignInternal( |
| 555 const WebKit::WebCryptoAlgorithm& algorithm, | 555 const blink::WebCryptoAlgorithm& algorithm, |
| 556 const WebKit::WebCryptoKey& key, | 556 const blink::WebCryptoKey& key, |
| 557 const unsigned char* data, | 557 const unsigned char* data, |
| 558 unsigned data_size, | 558 unsigned data_size, |
| 559 WebKit::WebArrayBuffer* buffer) { | 559 blink::WebArrayBuffer* buffer) { |
| 560 WebKit::WebArrayBuffer result; | 560 blink::WebArrayBuffer result; |
| 561 | 561 |
| 562 switch (algorithm.id()) { | 562 switch (algorithm.id()) { |
| 563 case WebKit::WebCryptoAlgorithmIdHmac: { | 563 case blink::WebCryptoAlgorithmIdHmac: { |
| 564 const WebKit::WebCryptoHmacParams* params = algorithm.hmacParams(); | 564 const blink::WebCryptoHmacParams* params = algorithm.hmacParams(); |
| 565 if (!params) { | 565 if (!params) { |
| 566 return false; | 566 return false; |
| 567 } | 567 } |
| 568 | 568 |
| 569 SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); | 569 SymKeyHandle* sym_key = reinterpret_cast<SymKeyHandle*>(key.handle()); |
| 570 | 570 |
| 571 DCHECK_EQ(PK11_GetMechanism(sym_key->key()), | 571 DCHECK_EQ(PK11_GetMechanism(sym_key->key()), |
| 572 WebCryptoAlgorithmToHMACMechanism(params->hash())); | 572 WebCryptoAlgorithmToHMACMechanism(params->hash())); |
| 573 DCHECK_NE(0, key.usages() & WebKit::WebCryptoKeyUsageSign); | 573 DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign); |
| 574 | 574 |
| 575 SECItem param_item = { siBuffer, NULL, 0 }; | 575 SECItem param_item = { siBuffer, NULL, 0 }; |
| 576 SECItem data_item = { | 576 SECItem data_item = { |
| 577 siBuffer, | 577 siBuffer, |
| 578 const_cast<unsigned char*>(data), | 578 const_cast<unsigned char*>(data), |
| 579 data_size | 579 data_size |
| 580 }; | 580 }; |
| 581 // First call is to figure out the length. | 581 // First call is to figure out the length. |
| 582 SECItem signature_item = { siBuffer, NULL, 0 }; | 582 SECItem signature_item = { siBuffer, NULL, 0 }; |
| 583 | 583 |
| 584 if (PK11_SignWithSymKey(sym_key->key(), | 584 if (PK11_SignWithSymKey(sym_key->key(), |
| 585 PK11_GetMechanism(sym_key->key()), | 585 PK11_GetMechanism(sym_key->key()), |
| 586 ¶m_item, | 586 ¶m_item, |
| 587 &signature_item, | 587 &signature_item, |
| 588 &data_item) != SECSuccess) { | 588 &data_item) != SECSuccess) { |
| 589 NOTREACHED(); | 589 NOTREACHED(); |
| 590 return false; | 590 return false; |
| 591 } | 591 } |
| 592 | 592 |
| 593 DCHECK_NE(0u, signature_item.len); | 593 DCHECK_NE(0u, signature_item.len); |
| 594 | 594 |
| 595 result = WebKit::WebArrayBuffer::create(signature_item.len, 1); | 595 result = blink::WebArrayBuffer::create(signature_item.len, 1); |
| 596 signature_item.data = reinterpret_cast<unsigned char*>(result.data()); | 596 signature_item.data = reinterpret_cast<unsigned char*>(result.data()); |
| 597 | 597 |
| 598 if (PK11_SignWithSymKey(sym_key->key(), | 598 if (PK11_SignWithSymKey(sym_key->key(), |
| 599 PK11_GetMechanism(sym_key->key()), | 599 PK11_GetMechanism(sym_key->key()), |
| 600 ¶m_item, | 600 ¶m_item, |
| 601 &signature_item, | 601 &signature_item, |
| 602 &data_item) != SECSuccess) { | 602 &data_item) != SECSuccess) { |
| 603 NOTREACHED(); | 603 NOTREACHED(); |
| 604 return false; | 604 return false; |
| 605 } | 605 } |
| 606 | 606 |
| 607 DCHECK_EQ(result.byteLength(), signature_item.len); | 607 DCHECK_EQ(result.byteLength(), signature_item.len); |
| 608 | 608 |
| 609 break; | 609 break; |
| 610 } | 610 } |
| 611 default: | 611 default: |
| 612 return false; | 612 return false; |
| 613 } | 613 } |
| 614 | 614 |
| 615 *buffer = result; | 615 *buffer = result; |
| 616 return true; | 616 return true; |
| 617 } | 617 } |
| 618 | 618 |
| 619 bool WebCryptoImpl::VerifySignatureInternal( | 619 bool WebCryptoImpl::VerifySignatureInternal( |
| 620 const WebKit::WebCryptoAlgorithm& algorithm, | 620 const blink::WebCryptoAlgorithm& algorithm, |
| 621 const WebKit::WebCryptoKey& key, | 621 const blink::WebCryptoKey& key, |
| 622 const unsigned char* signature, | 622 const unsigned char* signature, |
| 623 unsigned signature_size, | 623 unsigned signature_size, |
| 624 const unsigned char* data, | 624 const unsigned char* data, |
| 625 unsigned data_size, | 625 unsigned data_size, |
| 626 bool* signature_match) { | 626 bool* signature_match) { |
| 627 switch (algorithm.id()) { | 627 switch (algorithm.id()) { |
| 628 case WebKit::WebCryptoAlgorithmIdHmac: { | 628 case blink::WebCryptoAlgorithmIdHmac: { |
| 629 WebKit::WebArrayBuffer result; | 629 blink::WebArrayBuffer result; |
| 630 if (!SignInternal(algorithm, key, data, data_size, &result)) { | 630 if (!SignInternal(algorithm, key, data, data_size, &result)) { |
| 631 return false; | 631 return false; |
| 632 } | 632 } |
| 633 | 633 |
| 634 // Handling of truncated signatures is underspecified in the WebCrypto | 634 // Handling of truncated signatures is underspecified in the WebCrypto |
| 635 // spec, so here we fail verification if a truncated signature is being | 635 // spec, so here we fail verification if a truncated signature is being |
| 636 // verified. | 636 // verified. |
| 637 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23097 | 637 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23097 |
| 638 *signature_match = | 638 *signature_match = |
| 639 result.byteLength() == signature_size && | 639 result.byteLength() == signature_size && |
| 640 crypto::SecureMemEqual(result.data(), signature, signature_size); | 640 crypto::SecureMemEqual(result.data(), signature, signature_size); |
| 641 | 641 |
| 642 break; | 642 break; |
| 643 } | 643 } |
| 644 default: | 644 default: |
| 645 return false; | 645 return false; |
| 646 } | 646 } |
| 647 | 647 |
| 648 return true; | 648 return true; |
| 649 } | 649 } |
| 650 | 650 |
| 651 } // namespace content | 651 } // namespace content |
| OLD | NEW |