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

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: fixes for eroman Created 7 years, 1 month 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 1590a09961558af8bc8d14fd7f28b86ea432e7aa..fa4e5c70384e23afb4056e3d3fbad8ae612535fa 100644
--- a/content/renderer/webcrypto/webcrypto_impl_nss.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc
@@ -238,6 +238,31 @@ bool BigIntegerToLong(const uint8* data,
return true;
}
+// TODO(padolph): Move to webcrypto_util
+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();
+}
+
} // namespace
void WebCryptoImpl::Init() {
@@ -557,6 +582,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()) {
@@ -570,7 +601,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 = {
@@ -608,6 +638,46 @@ bool WebCryptoImpl::SignInternal(
break;
}
+ case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
+ // Only private key signing is supported.
+ if (key.type() != blink::WebCryptoKeyTypePrivate)
+ return false;
+
+ const blink::WebCryptoAlgorithm hash_algorithm =
+ GetInnerHashAlgorithm(algorithm);
+ if (hash_algorithm.isNull()) // TODO(padolph): DCHECK instead?
+ return false;
+ blink::WebArrayBuffer digest;
+ if (!DigestInternal(hash_algorithm, data, data_size, &digest))
Ryan Sleevi 2013/11/21 01:45:57 I'm not sure this is the right approach. Why not
padolph 2013/11/28 02:29:09 Done. Rewrote to use SEC_SignData (a sequence of S
+ return false;
+ const SECItem digest_item = {
+ siBuffer,
+ reinterpret_cast<unsigned char*>(digest.data()),
+ digest.byteLength()
+ };
+
+ PrivateKeyHandle* const private_key =
+ reinterpret_cast<PrivateKeyHandle*>(key.handle());
+ DCHECK(private_key);
+ DCHECK(private_key->key());
+ const int signature_length = PK11_SignatureLen(private_key->key());
+ if (signature_length <= 0)
+ return false;
+ result = blink::WebArrayBuffer::create(signature_length, 1);
+ SECItem signature_item = {
+ siBuffer,
+ reinterpret_cast<unsigned char*>(result.data()),
+ signature_length
+ };
+ if (PK11_Sign(private_key->key(),
+ &signature_item,
+ &digest_item) != SECSuccess ) {
+ return false;
+ }
+ DCHECK_EQ(result.byteLength(), signature_item.len);
+
+ break;
+ }
default:
return false;
}
@@ -641,6 +711,40 @@ bool WebCryptoImpl::VerifySignatureInternal(
break;
}
+ case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
+ // Only public key signature verification is supported.
+ if (key.type() != blink::WebCryptoKeyTypePublic)
+ return false;
+
+ const blink::WebCryptoAlgorithm hash_algorithm =
+ GetInnerHashAlgorithm(algorithm);
+ if (hash_algorithm.isNull()) // TODO(padolph): DCHECK instead?
+ return false;
+ blink::WebArrayBuffer digest;
+ if (!DigestInternal(hash_algorithm, data, data_size, &digest))
+ return false;
+ const SECItem digest_item = {
+ siBuffer,
+ reinterpret_cast<unsigned char*>(digest.data()),
+ digest.byteLength()
+ };
+
+ 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 = PK11_Verify(public_key->key(),
+ &signature_item,
+ &digest_item,
+ 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