Bug 1034856 - Introduce DhKeyAlgorithm. r=rbarnes, r=smaug, a=lsblakk
☠☠ backed out by 86f3ce4cf56a ☠ ☠
authorTim Taubert <ttaubert@mozilla.com>
Sun, 20 Jul 2014 05:51:10 +0200
changeset 233529 526f7c0682e16ab194a16ef61f969ce5abf8ac92
parent 233528 5de40c8a968fe2dcd29cac1908fc2b1a83af164e
child 233530 ce89df7057f06e34d847de8f307eb91668de5857
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrbarnes, smaug, lsblakk
bugs1034856
milestone35.0a2
Bug 1034856 - Introduce DhKeyAlgorithm. r=rbarnes, r=smaug, a=lsblakk
dom/crypto/CryptoKey.cpp
dom/crypto/KeyAlgorithmProxy.cpp
dom/crypto/KeyAlgorithmProxy.h
dom/crypto/WebCryptoCommon.h
dom/webidl/KeyAlgorithm.webidl
--- a/dom/crypto/CryptoKey.cpp
+++ b/dom/crypto/CryptoKey.cpp
@@ -107,16 +107,22 @@ CryptoKey::GetAlgorithm(JSContext* cx, J
       RootedDictionary<RsaHashedKeyAlgorithm> rsa(cx);
       mAlgorithm.mRsa.ToKeyAlgorithm(cx, rsa);
       converted = ToJSValue(cx, rsa, &val);
       break;
     }
     case KeyAlgorithmProxy::EC:
       converted = ToJSValue(cx, mAlgorithm.mEc, &val);
       break;
+    case KeyAlgorithmProxy::DH: {
+      RootedDictionary<DhKeyAlgorithm> dh(cx);
+      mAlgorithm.mDh.ToKeyAlgorithm(cx, dh);
+      converted = ToJSValue(cx, dh, &val);
+      break;
+    }
   }
   if (!converted) {
     aRv.Throw(NS_ERROR_DOM_OPERATION_ERR);
     return;
   }
 
   aRetVal.set(&val.toObject());
 }
--- a/dom/crypto/KeyAlgorithmProxy.cpp
+++ b/dom/crypto/KeyAlgorithmProxy.cpp
@@ -26,16 +26,20 @@ KeyAlgorithmProxy::WriteStructuredClone(
              WriteString(aWriter, mHmac.mHash.mName);
     case RSA: {
       return JS_WriteUint32Pair(aWriter, mRsa.mModulusLength, 0) &&
              WriteBuffer(aWriter, mRsa.mPublicExponent) &&
              WriteString(aWriter, mRsa.mHash.mName);
     }
     case EC:
       return WriteString(aWriter, mEc.mNamedCurve);
+    case DH: {
+      return WriteBuffer(aWriter, mDh.mPrime) &&
+             WriteBuffer(aWriter, mDh.mGenerator);
+    }
   }
 
   return false;
 }
 
 bool
 KeyAlgorithmProxy::ReadStructuredClone(JSStructuredCloneReader* aReader)
 {
@@ -87,16 +91,25 @@ KeyAlgorithmProxy::ReadStructuredClone(J
       nsString namedCurve;
       if (!ReadString(aReader, mEc.mNamedCurve)) {
         return false;
       }
 
       mEc.mName = mName;
       return true;
     }
+    case DH: {
+      if (!ReadBuffer(aReader, mDh.mPrime) ||
+          !ReadBuffer(aReader, mDh.mGenerator)) {
+        return false;
+      }
+
+      mDh.mName = mName;
+      return true;
+    }
   }
 
   return false;
 }
 
 CK_MECHANISM_TYPE
 KeyAlgorithmProxy::Mechanism() const
 {
--- a/dom/crypto/KeyAlgorithmProxy.h
+++ b/dom/crypto/KeyAlgorithmProxy.h
@@ -31,35 +31,55 @@ struct RsaHashedKeyAlgorithmStorage {
     aRsa.mName = mName;
     aRsa.mModulusLength = mModulusLength;
     aRsa.mHash.mName = mHash.mName;
     aRsa.mPublicExponent.Init(mPublicExponent.ToUint8Array(aCx));
     aRsa.mPublicExponent.ComputeLengthAndData();
   }
 };
 
+// A heap-safe variant of DhKeyAlgorithm
+// The only difference is that it uses CryptoBuffers instead of Uint8Arrays
+struct DhKeyAlgorithmStorage {
+  nsString mName;
+  CryptoBuffer mPrime;
+  CryptoBuffer mGenerator;
+
+  void
+  ToKeyAlgorithm(JSContext* aCx, DhKeyAlgorithm& aDh) const
+  {
+    aDh.mName = mName;
+    aDh.mPrime.Init(mPrime.ToUint8Array(aCx));
+    aDh.mPrime.ComputeLengthAndData();
+    aDh.mGenerator.Init(mGenerator.ToUint8Array(aCx));
+    aDh.mGenerator.ComputeLengthAndData();
+  }
+};
+
 // This class encapuslates a KeyAlgorithm object, and adds several
 // methods that make WebCrypto operations simpler.
 struct KeyAlgorithmProxy
 {
   enum KeyAlgorithmType {
     AES,
     HMAC,
     RSA,
-    EC
+    EC,
+    DH,
   };
   KeyAlgorithmType mType;
 
   // Plain is always populated with the algorithm name
   // Others are only populated for the corresponding key type
   nsString mName;
   AesKeyAlgorithm mAes;
   HmacKeyAlgorithm mHmac;
   RsaHashedKeyAlgorithmStorage mRsa;
   EcKeyAlgorithm mEc;
+  DhKeyAlgorithmStorage mDh;
 
   // Structured clone
   bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const;
   bool ReadStructuredClone(JSStructuredCloneReader* aReader);
 
   // Extract various forms of derived information
   CK_MECHANISM_TYPE Mechanism() const;
   nsString JwkAlg() const;
@@ -104,14 +124,25 @@ struct KeyAlgorithmProxy
   void
   MakeEc(const nsString& aName, const nsString& aNamedCurve)
   {
     mType = EC;
     mName = aName;
     mEc.mName = aName;
     mEc.mNamedCurve = aNamedCurve;
   }
+
+  void
+  MakeDh(const nsString& aName, const CryptoBuffer& aPrime,
+         const CryptoBuffer& aGenerator)
+  {
+    mType = DH;
+    mName = aName;
+    mDh.mName = aName;
+    mDh.mPrime.Assign(aPrime);
+    mDh.mGenerator.Assign(aGenerator);
+  }
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_KeyAlgorithmProxy_h
--- a/dom/crypto/WebCryptoCommon.h
+++ b/dom/crypto/WebCryptoCommon.h
@@ -23,16 +23,17 @@
 #define WEBCRYPTO_ALG_SHA384        "SHA-384"
 #define WEBCRYPTO_ALG_SHA512        "SHA-512"
 #define WEBCRYPTO_ALG_HMAC          "HMAC"
 #define WEBCRYPTO_ALG_PBKDF2        "PBKDF2"
 #define WEBCRYPTO_ALG_RSASSA_PKCS1  "RSASSA-PKCS1-v1_5"
 #define WEBCRYPTO_ALG_RSA_OAEP      "RSA-OAEP"
 #define WEBCRYPTO_ALG_ECDH          "ECDH"
 #define WEBCRYPTO_ALG_ECDSA         "ECDSA"
+#define WEBCRYPTO_ALG_DH            "DH"
 
 // WebCrypto key formats
 #define WEBCRYPTO_KEY_FORMAT_RAW    "raw"
 #define WEBCRYPTO_KEY_FORMAT_PKCS8  "pkcs8"
 #define WEBCRYPTO_KEY_FORMAT_SPKI   "spki"
 #define WEBCRYPTO_KEY_FORMAT_JWK    "jwk"
 
 // WebCrypto key types
@@ -186,16 +187,18 @@ MapAlgorithmNameToMechanism(const nsStri
   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_PBKDF2)) {
     mechanism = CKM_PKCS5_PBKD2;
   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1)) {
     mechanism = CKM_RSA_PKCS;
   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_RSA_OAEP)) {
     mechanism = CKM_RSA_PKCS_OAEP;
   } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_ECDH)) {
     mechanism = CKM_ECDH1_DERIVE;
+  } else if (aName.EqualsLiteral(WEBCRYPTO_ALG_DH)) {
+    mechanism = CKM_DH_PKCS_DERIVE;
   }
 
   return mechanism;
 }
 
 #define NORMALIZED_EQUALS(aTest, aConst) \
         nsContentUtils::EqualsIgnoreASCIICase(aTest, NS_LITERAL_STRING(aConst))
 
@@ -226,16 +229,18 @@ NormalizeToken(const nsString& aName, ns
   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSASSA_PKCS1)) {
     aDest.AssignLiteral(WEBCRYPTO_ALG_RSASSA_PKCS1);
   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_RSA_OAEP)) {
     aDest.AssignLiteral(WEBCRYPTO_ALG_RSA_OAEP);
   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_ECDH)) {
     aDest.AssignLiteral(WEBCRYPTO_ALG_ECDH);
   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_ECDSA)) {
     aDest.AssignLiteral(WEBCRYPTO_ALG_ECDSA);
+  } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_ALG_DH)) {
+    aDest.AssignLiteral(WEBCRYPTO_ALG_DH);
   // Named curve values
   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P256)) {
     aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P256);
   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P384)) {
     aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P384);
   } else if (NORMALIZED_EQUALS(aName, WEBCRYPTO_NAMED_CURVE_P521)) {
     aDest.AssignLiteral(WEBCRYPTO_NAMED_CURVE_P521);
   } else {
--- a/dom/webidl/KeyAlgorithm.webidl
+++ b/dom/webidl/KeyAlgorithm.webidl
@@ -25,8 +25,13 @@ dictionary HmacKeyAlgorithm : KeyAlgorit
 };
 
 dictionary RsaHashedKeyAlgorithm : KeyAlgorithm {
   required unsigned short modulusLength;
   required Uint8Array publicExponent;
   required KeyAlgorithm hash;
 };
 
+dictionary DhKeyAlgorithm : KeyAlgorithm {
+  required Uint8Array prime;
+  required Uint8Array generator;
+};
+