Chromium Code Reviews| Index: content/renderer/webcrypto/webcrypto_impl_nss.cc |
| diff --git a/content/renderer/webcrypto/webcrypto_impl_nss.cc b/content/renderer/webcrypto/webcrypto_impl_nss.cc |
| index 1df84289b243df2018f9de3bcf4e1a7d15d523d5..372da0825d01910e0dc78f3a4c1be1a881ef7739 100644 |
| --- a/content/renderer/webcrypto/webcrypto_impl_nss.cc |
| +++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc |
| @@ -80,6 +80,25 @@ HASH_HashType WebCryptoAlgorithmToNSSHashType( |
| } |
| } |
| +SECOidTag WebCryptoAlgorithmToNssSecOidShaTag( |
| + const blink::WebCryptoAlgorithm& algorithm) { |
| + DCHECK(!algorithm.isNull()); |
| + switch (algorithm.id()) { |
| + case blink::WebCryptoAlgorithmIdSha1: |
| + return SEC_OID_SHA1; |
| + case blink::WebCryptoAlgorithmIdSha224: |
| + return SEC_OID_SHA224; |
| + case blink::WebCryptoAlgorithmIdSha256: |
| + return SEC_OID_SHA256; |
| + case blink::WebCryptoAlgorithmIdSha384: |
| + return SEC_OID_SHA384; |
| + case blink::WebCryptoAlgorithmIdSha512: |
| + return SEC_OID_SHA512; |
| + default: |
| + return SEC_OID_UNKNOWN; |
| + } |
| +} |
| + |
| CK_MECHANISM_TYPE WebCryptoAlgorithmToHMACMechanism( |
| const blink::WebCryptoAlgorithm& algorithm) { |
| switch (algorithm.id()) { |
| @@ -268,6 +287,8 @@ bool ImportKeyInternalRaw( |
| return false; |
| } |
| + // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys. |
| + // Currently only supporting symmetric. |
| CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; |
| // Flags are verified at the Blink layer; here the flags are set to all |
| // possible operations for this key type. |
| @@ -868,6 +889,12 @@ bool WebCryptoImpl::SignInternal( |
| const unsigned char* data, |
| unsigned data_size, |
| blink::WebArrayBuffer* buffer) { |
| + |
| + // Note: It is not an error to sign empty data. |
| + |
| + DCHECK(buffer); |
| + DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign); |
| + |
| blink::WebArrayBuffer result; |
| switch (algorithm.id()) { |
| @@ -881,7 +908,6 @@ bool WebCryptoImpl::SignInternal( |
| DCHECK_EQ(PK11_GetMechanism(sym_key->key()), |
| WebCryptoAlgorithmToHMACMechanism(params->hash())); |
| - DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign); |
| SECItem param_item = { siBuffer, NULL, 0 }; |
| SECItem data_item = { |
| @@ -919,6 +945,48 @@ bool WebCryptoImpl::SignInternal( |
| break; |
| } |
| + case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: { |
| + // Only private key signing is supported. |
| + if (key.type() != blink::WebCryptoKeyTypePrivate) |
| + return false; |
| + |
| + PrivateKeyHandle* const private_key = |
| + reinterpret_cast<PrivateKeyHandle*>(key.handle()); |
| + DCHECK(private_key); |
| + DCHECK(private_key->key()); |
| + |
| + // Get the inner hash algorithm and convert to an NSS SECOidTag |
| + const blink::WebCryptoAlgorithm hash_algorithm = |
| + webcrypto::GetInnerHashAlgorithm(algorithm); |
| + if (hash_algorithm.isNull()) // TODO(padolph): DCHECK instead? |
| + return false; |
| + const SECOidTag hash_alg_tag = |
| + WebCryptoAlgorithmToNssSecOidShaTag(hash_algorithm); |
| + if (hash_alg_tag == SEC_OID_UNKNOWN) |
| + return false; |
| + |
| + // Get the NSS signature algorithm SECOidTag corresponding to the key type |
| + // and inner hash algorithm SECOidTag. |
| + const SECOidTag sign_alg_tag = SEC_GetSignatureAlgorithmOidTag( |
| + private_key->key()->keyType, |
| + hash_alg_tag); |
|
Ryan Sleevi
2013/12/20 02:08:50
This is unnecessary. The design of this API was me
padolph
2013/12/21 02:44:17
Done.
|
| + if (sign_alg_tag == SEC_OID_UNKNOWN) |
| + return false; |
| + |
| + crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0)); |
| + if (SEC_SignData(signature_item.get(), |
| + data, |
| + data_size, |
| + private_key->key(), |
| + sign_alg_tag) != SECSuccess) { |
| + return false; |
| + } |
| + |
| + result = webcrypto::CreateArrayBuffer(signature_item->data, |
| + signature_item->len); |
| + |
| + break; |
| + } |
| default: |
| return false; |
| } |
| @@ -935,6 +1003,11 @@ bool WebCryptoImpl::VerifySignatureInternal( |
| const unsigned char* data, |
| unsigned data_size, |
| bool* signature_match) { |
| + |
| + if (!signature_size) |
| + return false; |
| + DCHECK(signature); |
| + |
| switch (algorithm.id()) { |
| case blink::WebCryptoAlgorithmIdHmac: { |
| blink::WebArrayBuffer result; |
| @@ -952,6 +1025,41 @@ bool WebCryptoImpl::VerifySignatureInternal( |
| break; |
| } |
| + case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: { |
| + |
|
Ryan Sleevi
2013/12/20 02:08:50
unnecessary newline
padolph
2013/12/21 02:44:17
Done.
|
| + // Only public key signature verification is supported. |
|
Ryan Sleevi
2013/12/20 02:08:50
This comment makes no sense, given the algorithm b
padolph
2013/12/21 02:44:17
Done.
|
| + if (key.type() != blink::WebCryptoKeyTypePublic) |
| + return false; |
| + |
| + PublicKeyHandle* const public_key = |
| + reinterpret_cast<PublicKeyHandle*>(key.handle()); |
| + DCHECK(public_key); |
| + DCHECK(public_key->key()); |
| + |
| + const SECItem signature_item = { |
| + siBuffer, |
| + const_cast<unsigned char*>(signature), |
| + signature_size |
| + }; |
| + |
| + const SECOidTag hash_alg_tag = WebCryptoAlgorithmToNssSecOidShaTag( |
| + webcrypto::GetInnerHashAlgorithm(algorithm)); |
| + if (hash_alg_tag == SEC_OID_UNKNOWN) |
| + return false; |
| + |
| + *signature_match = |
| + VFY_VerifyDataDirect( |
| + data, |
| + data_size, |
| + public_key->key(), |
| + &signature_item, |
| + SEC_OID_PKCS1_RSA_ENCRYPTION, |
| + hash_alg_tag, |
| + NULL, |
| + NULL) == SECSuccess; |
|
Ryan Sleevi
2013/12/20 02:08:50
Was this run through git cl format? The formatting
padolph
2013/12/21 02:44:17
Rewrote yoda style and reformatted, and ran throug
|
| + |
| + break; |
| + } |
| default: |
| return false; |
| } |