Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1076)

Unified Diff: content/renderer/webcrypto/webcrypto_impl_nss.cc

Issue 68303009: [webcrypto] Add RSASSA-PKCS1-v1_5 sign and verify for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | content/renderer/webcrypto/webcrypto_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 73319df1a78b837fa4c7a93a762d6307cd06e3f8..43f9c2527a94a1c9dd0e32668a8a94bdcd378314 100644
--- a/content/renderer/webcrypto/webcrypto_impl_nss.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc
@@ -80,6 +80,24 @@ HASH_HashType WebCryptoAlgorithmToNSSHashType(
}
}
+SECOidTag WebCryptoAlgorithmToNssSecOidShaTag(
+ const blink::WebCryptoAlgorithm& algorithm) {
+ 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()) {
@@ -239,6 +257,31 @@ bool BigIntegerToLong(const uint8* data,
return true;
}
+// TODO(padolph): Move to webcrypto_util
eroman 2013/12/06 02:20:42 This can be done as part of this changelist.
padolph 2013/12/06 18:52:52 Done.
+blink::WebCryptoAlgorithm GetInnerHashAlgorithm(
+ const blink::WebCryptoAlgorithm& algorithm) {
+ DCHECK(!algorithm.isNull());
+ switch (algorithm.id()) {
+ case blink::WebCryptoAlgorithmIdHmac:
+ if (algorithm.hmacParams())
+ return algorithm.hmacParams()->hash();
+ else if (algorithm.hmacKeyParams())
+ return algorithm.hmacKeyParams()->hash();
+ break;
+ case blink::WebCryptoAlgorithmIdRsaOaep:
+ if (algorithm.rsaOaepParams())
+ return algorithm.rsaOaepParams()->hash();
+ break;
+ case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
+ if (algorithm.rsaSsaParams())
+ return algorithm.rsaSsaParams()->hash();
+ break;
+ default:
+ break;
+ }
+ return blink::WebCryptoAlgorithm::createNull();
+}
+
bool IsAlgorithmRsa(const blink::WebCryptoAlgorithm& algorithm) {
return algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep ||
@@ -845,6 +888,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()) {
@@ -858,7 +907,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 = {
@@ -896,6 +944,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 =
+ 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);
+ 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 = blink::WebArrayBuffer::create(signature_item->len, 1);
+ memcpy(result.data(), signature_item->data, signature_item->len);
eroman 2013/12/06 02:20:42 I believe there is now a helper for this checked i
padolph 2013/12/06 18:52:52 Done.
+
+ break;
+ }
default:
return false;
}
@@ -912,6 +1002,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;
@@ -929,6 +1024,36 @@ bool WebCryptoImpl::VerifySignatureInternal(
break;
}
+ case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
+
+ // Only public key signature verification is supported.
+ 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
+ };
+
+ *signature_match =
+ VFY_VerifyDataDirect(
+ data,
+ data_size,
+ public_key->key(),
+ &signature_item,
+ SEC_OID_PKCS1_RSA_ENCRYPTION,
+ SEC_OID_UNKNOWN,
eroman 2013/12/06 02:20:42 Forgive my crypto ignorance, but is this safe? Th
padolph 2013/12/06 18:52:52 We know at this callsite that we have an RSA key,
padolph 2013/12/07 00:41:04 Added explicit setting of the hash algorithm, and
+ NULL,
+ NULL) == SECSuccess;
+
+ break;
+ }
default:
return false;
}
« no previous file with comments | « no previous file | content/renderer/webcrypto/webcrypto_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698