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

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

Issue 34583010: [webcrypto] Add RSA key generation using NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes for rsleevi Created 7 years, 2 months 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
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 a20f72fb6bfd1bfe4336cb9a60deb8f15e3bd3f0..9638134fa6545532387e4e17b51f13b07057179b 100644
--- a/content/renderer/webcrypto/webcrypto_impl_nss.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc
@@ -24,10 +24,7 @@ namespace {
class SymKeyHandle : public WebKit::WebCryptoKeyHandle {
public:
- explicit SymKeyHandle(crypto::ScopedPK11SymKey key) {
- DCHECK(!key_.get());
- key_ = key.Pass();
- }
+ explicit SymKeyHandle(crypto::ScopedPK11SymKey key) : key_(key.Pass()) {}
PK11SymKey* key() { return key_.get(); }
@@ -37,6 +34,32 @@ class SymKeyHandle : public WebKit::WebCryptoKeyHandle {
DISALLOW_COPY_AND_ASSIGN(SymKeyHandle);
};
+class PublicKeyHandle : public WebKit::WebCryptoKeyHandle {
+ public:
+ explicit PublicKeyHandle(crypto::ScopedSECKEYPublicKey key)
+ : key_(key.Pass()) {}
+
+ SECKEYPublicKey* key() { return key_.get(); }
+
+ private:
+ crypto::ScopedSECKEYPublicKey key_;
+
+ DISALLOW_COPY_AND_ASSIGN(PublicKeyHandle);
+};
+
+class PrivateKeyHandle : public WebKit::WebCryptoKeyHandle {
+ public:
+ explicit PrivateKeyHandle(crypto::ScopedSECKEYPrivateKey key)
+ : key_(key.Pass()) {}
+
+ SECKEYPrivateKey* key() { return key_.get(); }
+
+ private:
+ crypto::ScopedSECKEYPrivateKey key_;
+
+ DISALLOW_COPY_AND_ASSIGN(PrivateKeyHandle);
+};
+
HASH_HashType WebCryptoAlgorithmToNSSHashType(
const WebKit::WebCryptoAlgorithm& algorithm) {
switch (algorithm.id()) {
@@ -323,6 +346,101 @@ bool WebCryptoImpl::GenerateKeyInternal(
return true;
}
+bool WebCryptoImpl::GenerateKeyPairInternal(
+ const WebKit::WebCryptoAlgorithm& algorithm,
+ scoped_ptr<WebKit::WebCryptoKeyHandle>* public_key_handle,
+ scoped_ptr<WebKit::WebCryptoKeyHandle>* private_key_handle) {
+
+ // TODO(padolph) Handle other asymmetric algorithm key generation
+ switch (algorithm.id()) {
+ case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
+ case WebKit::WebCryptoAlgorithmIdRsaOaep:
+ case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
+ const WebKit::WebCryptoRsaKeyGenParams* const params =
+ algorithm.rsaKeyGenParams();
+ DCHECK(params);
+
+ crypto::ScopedPK11Slot slot(PK11_GetInternalKeySlot());
+ if (!slot || !params->modulusLength() ||
+ !params->publicExponent().size()) {
eroman 2013/10/24 22:28:59 Sleevi: General question: In WebCrypto's "BigInteg
+ return false;
+ }
+
+ // The Web Crypto API says params->m_publicExponent is in big-endian
+ // order: the first element in the vector is the most significant digit.
+ // Leading zeros may or may not be present.
+
+ // First offset past any leading zeros in publicExponent.
eroman 2013/10/24 22:28:59 Could you please extract this block of code to a s
padolph 2013/10/25 01:21:46 Done.
+ size_t start_index;
+ for (start_index = 0; start_index < params->publicExponent().size();
eroman 2013/10/24 22:28:59 In my opinion this logic would be more readable as
padolph 2013/10/25 01:21:46 Done.
+ ++start_index) {
+ if (params->publicExponent()[start_index] != 0x0)
+ break;
+ }
+ const size_t exponent_size =
+ params->publicExponent().size() - start_index;
+ if (start_index == params->publicExponent().size() ||
+ exponent_size > sizeof(unsigned long)) {
+ return false;
+ }
+
+ // Then convert the remaining data to an unsigned long.
+ const size_t end_index = params->publicExponent().size() - 1;
+ unsigned long public_exponent = 0;
+ for (int i = end_index; i >= static_cast<int>(start_index); --i) {
+ public_exponent |= params->publicExponent()[i] << (8 * (end_index - i));
+ }
+
+ PK11RSAGenParams param;
+ param.keySizeInBits = params->modulusLength();
+ param.pe = public_exponent;
+
+ // Flags are verified at the Blink layer; here the flags are set to all
+ // possible operations for the given key type.
+ CK_FLAGS operation_flags;
+ switch (algorithm.id()) {
+ case WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5:
+ operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
+ break;
+ case WebKit::WebCryptoAlgorithmIdRsaOaep:
+ operation_flags = CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP;
+ break;
+ case WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5:
+ operation_flags = CKF_SIGN | CKF_VERIFY;
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+ const CK_FLAGS operation_flags_mask = CKF_ENCRYPT | CKF_DECRYPT |
+ CKF_SIGN | CKF_VERIFY | CKF_WRAP |
+ CKF_UNWRAP;
+ const PK11AttrFlags attribute_flags = 0; // default all PK11_ATTR_ flags
+
+ SECKEYPublicKey* sec_public_key;
+ crypto::ScopedSECKEYPrivateKey private_key(
+ PK11_GenerateKeyPairWithOpFlags(slot.get(),
+ CKM_RSA_PKCS_KEY_PAIR_GEN,
+ &param,
+ &sec_public_key,
+ attribute_flags,
+ operation_flags,
+ operation_flags_mask,
+ NULL));
+ if (!private_key) {
+ return false;
+ }
+ crypto::ScopedSECKEYPublicKey public_key(sec_public_key);
+
+ public_key_handle->reset(new PublicKeyHandle(public_key.Pass()));
+ private_key_handle->reset(new PrivateKeyHandle(private_key.Pass()));
+
+ return true;
+ }
+ default:
+ return false;
+ }
+}
bool WebCryptoImpl::ImportKeyInternal(
WebKit::WebCryptoKeyFormat format,

Powered by Google App Engine
This is Rietveld 408576698