| 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 42dfc334d6907bbafad0c49c234f912b25352cb4..73319df1a78b837fa4c7a93a762d6307cd06e3f8 100644
|
| --- a/content/renderer/webcrypto/webcrypto_impl_nss.cc
|
| +++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc
|
| @@ -936,4 +936,62 @@ bool WebCryptoImpl::VerifySignatureInternal(
|
| return true;
|
| }
|
|
|
| +bool WebCryptoImpl::ImportRsaPublicKeyInternal(
|
| + const unsigned char* modulus_data,
|
| + unsigned modulus_size,
|
| + const unsigned char* exponent_data,
|
| + unsigned exponent_size,
|
| + const blink::WebCryptoAlgorithm& algorithm,
|
| + bool extractable,
|
| + blink::WebCryptoKeyUsageMask usage_mask,
|
| + blink::WebCryptoKey* key) {
|
| +
|
| + if (!modulus_size || !exponent_size)
|
| + return false;
|
| + DCHECK(modulus_data);
|
| + DCHECK(exponent_data);
|
| +
|
| + // NSS does not provide a way to create an RSA public key directly from the
|
| + // modulus and exponent values, but it can import an DER-encoded ASN.1 blob
|
| + // with these values and create the public key from that. The code below
|
| + // follows the recommendation described in
|
| + // https://developer.mozilla.org/en-US/docs/NSS/NSS_Tech_Notes/nss_tech_note7
|
| +
|
| + // Pack the input values into a struct compatible with NSS ASN.1 encoding, and
|
| + // set up an ASN.1 encoder template for it.
|
| + struct RsaPublicKeyData {
|
| + SECItem modulus;
|
| + SECItem exponent;
|
| + };
|
| + const RsaPublicKeyData pubkey_in = {
|
| + {siUnsignedInteger, const_cast<unsigned char*>(modulus_data),
|
| + modulus_size},
|
| + {siUnsignedInteger, const_cast<unsigned char*>(exponent_data),
|
| + exponent_size}};
|
| + const SEC_ASN1Template rsa_public_key_template[] = {
|
| + {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RsaPublicKeyData)},
|
| + {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, modulus), },
|
| + {SEC_ASN1_INTEGER, offsetof(RsaPublicKeyData, exponent), },
|
| + {0, }};
|
| +
|
| + // DER-encode the public key.
|
| + crypto::ScopedSECItem pubkey_der(SEC_ASN1EncodeItem(
|
| + NULL, NULL, &pubkey_in, rsa_public_key_template));
|
| + if (!pubkey_der)
|
| + return false;
|
| +
|
| + // Import the DER-encoded public key to create an RSA SECKEYPublicKey.
|
| + crypto::ScopedSECKEYPublicKey pubkey(
|
| + SECKEY_ImportDERPublicKey(pubkey_der.get(), CKK_RSA));
|
| + if (!pubkey)
|
| + return false;
|
| +
|
| + *key = blink::WebCryptoKey::create(new PublicKeyHandle(pubkey.Pass()),
|
| + blink::WebCryptoKeyTypePublic,
|
| + extractable,
|
| + algorithm,
|
| + usage_mask);
|
| + return true;
|
| +}
|
| +
|
| } // namespace content
|
|
|