Bug 1105689 - use SHA384 certificates to sign app update mar files. Part 1 - convert the libmar code from SHA1 to SHA384. r=mhowell, r=spohl, a=app_update_sha384
authorRobert Strong <robert.bugzilla@gmail.com>
Sun, 30 Jul 2017 23:27:27 -0700
changeset 420624 f72832cc0480c8ec0cd19df26e5e6c31fe725c3e
parent 420623 620ff920d6664cc3a69aea692eb865bc8c7cef30
child 420625 a0469afc3098e528ec1a85b403cd65f2c8f0cab7
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhowell, spohl, app_update_sha384
bugs1105689
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1105689 - use SHA384 certificates to sign app update mar files. Part 1 - convert the libmar code from SHA1 to SHA384. r=mhowell, r=spohl, a=app_update_sha384
modules/libmar/sign/mar_sign.c
modules/libmar/verify/MacVerifyCrypto.cpp
modules/libmar/verify/cryptox.c
modules/libmar/verify/mar_verify.c
--- a/modules/libmar/sign/mar_sign.c
+++ b/modules/libmar/sign/mar_sign.c
@@ -90,17 +90,17 @@ NSSSignBegin(const char *certName,
 
   /* Check that the key length is large enough for our requirements */
   if (*signatureLength < XP_MIN_SIGNATURE_LEN_IN_BYTES) {
     fprintf(stderr, "ERROR: Key length must be >= %d bytes\n", 
             XP_MIN_SIGNATURE_LEN_IN_BYTES);
     return -1;
   }
 
-  *ctx = SGN_NewContext (SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, *privKey);
+  *ctx = SGN_NewContext(SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION, *privKey);
   if (!*ctx) {
     fprintf(stderr, "ERROR: Could not create signature context\n");
     return -1;
   }
   
   if (SGN_Begin(*ctx) != SECSuccess) {
     fprintf(stderr, "ERROR: Could not begin signature\n");
     return -1;
@@ -988,18 +988,18 @@ mar_repackage_and_sign(const char *NSSCo
                                "num signatures")) {
     goto failure;
   }
   numSignatures = ntohl(numSignatures);
 
   signaturePlaceholderOffset = ftello(fpDest);
 
   for (k = 0; k < certCount; k++) {
-    /* Write out the signature algorithm ID, Only an ID of 1 is supported */
-    signatureAlgorithmID = htonl(1);
+    /* Write out the signature algorithm ID, Only an ID of 2 is supported */
+    signatureAlgorithmID = htonl(2);
     if (WriteAndUpdateSignatures(fpDest, &signatureAlgorithmID,
                                  sizeof(signatureAlgorithmID),
                                  ctxs, certCount, "num signatures")) {
       goto failure;
     }
     signatureAlgorithmID = ntohl(signatureAlgorithmID);
 
     /* Write out the signature length */
--- a/modules/libmar/verify/MacVerifyCrypto.cpp
+++ b/modules/libmar/verify/MacVerifyCrypto.cpp
@@ -151,33 +151,63 @@ CryptoMac_VerifySignature(CryptoX_Signat
   }
 
   CFErrorRef error;
   SecTransformRef verifier =
     SecVerifyTransformCreatePtr((SecKeyRef)*aPublicKey,
                                 signatureData,
                                 &error);
   if (!verifier || error) {
+    if (error) {
+      CFRelease(error);
+    }
     CFRelease(signatureData);
     return CryptoX_Error;
   }
 
   SecTransformSetAttributePtr(verifier,
+                              kSecDigestTypeAttribute,
+                              kSecDigestSHA2,
+                              &error);
+  if (error) {
+    CFRelease(error);
+    CFRelease(signatureData);
+    CFRelease(verifier);
+    return CryptoX_Error;
+  }
+
+  int digestLength = 384;
+  CFNumberRef dLen = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &digestLength);
+  SecTransformSetAttributePtr(verifier,
+                              kSecDigestLengthAttribute,
+                              dLen,
+                              &error);
+  CFRelease(dLen);
+  if (error) {
+    CFRelease(error);
+    CFRelease(signatureData);
+    CFRelease(verifier);
+    return CryptoX_Error;
+  }
+
+  SecTransformSetAttributePtr(verifier,
                               kSecTransformInputAttributeName,
                               (CFDataRef)*aInputData,
                               &error);
   if (error) {
+    CFRelease(error);
     CFRelease(signatureData);
     CFRelease(verifier);
     return CryptoX_Error;
   }
 
   CryptoX_Result result = CryptoX_Error;
   CFTypeRef rv = SecTransformExecutePtr(verifier, &error);
   if (error) {
+    CFRelease(error);
     CFRelease(signatureData);
     CFRelease(verifier);
     return CryptoX_Error;
   }
 
   if (CFGetTypeID(rv) == CFBooleanGetTypeID() &&
       CFBooleanGetValue((CFBooleanRef)rv) == true) {
     result = CryptoX_Success;
--- a/modules/libmar/verify/cryptox.c
+++ b/modules/libmar/verify/cryptox.c
@@ -4,16 +4,17 @@
 
 #ifdef XP_WIN
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #endif
 #endif
 
 #include <stdlib.h>
+#include <stdio.h>
 #include "cryptox.h"
 
 #if defined(MAR_NSS)
 
 /** 
  * Loads the public key for the specified cert name from the NSS store.
  * 
  * @param certData  The DER-encoded X509 certificate to extract the key from.
@@ -60,17 +61,17 @@ NSS_VerifyBegin(VFYContext **ctx,
   if ((SECKEY_PublicKeyStrength(*publicKey) * 8) < 
       XP_MIN_SIGNATURE_LEN_IN_BYTES) {
     fprintf(stderr, "ERROR: Key length must be >= %d bytes\n", 
             XP_MIN_SIGNATURE_LEN_IN_BYTES);
     return CryptoX_Error;
   }
 
   *ctx = VFY_CreateContext(*publicKey, NULL, 
-                           SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE, NULL);
+                           SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION, NULL);
   if (*ctx == NULL) {
     return CryptoX_Error;
   }
 
   status = VFY_Begin(*ctx);
   return SECSuccess == status ? CryptoX_Success : CryptoX_Error;
 }
 
@@ -194,33 +195,33 @@ CryptoAPI_LoadPublicKey(HCRYPTPROV provi
   * @param provider Out parameter containing the provider handle.
   * @return CryptoX_Success on success, CryptoX_Error on error.
  */
 CryptoX_Result
 CryptoAPI_InitCryptoContext(HCRYPTPROV *provider)
 {
   if (!CryptAcquireContext(provider, 
                            NULL, 
-                           MS_ENHANCED_PROV, 
-                           PROV_RSA_FULL, 
+                           MS_ENH_RSA_AES_PROV, 
+                           PROV_RSA_AES, 
                            CRYPT_VERIFYCONTEXT)) {
     if (!CryptAcquireContext(provider, 
                              NULL, 
-                             MS_ENHANCED_PROV, 
-                             PROV_RSA_FULL, 
+                             MS_ENH_RSA_AES_PROV, 
+                             PROV_RSA_AES, 
                              CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) {
       if (!CryptAcquireContext(provider, 
                                NULL, 
                                NULL, 
-                               PROV_RSA_FULL, 
+                               PROV_RSA_AES, 
                                CRYPT_VERIFYCONTEXT)) {
         if (!CryptAcquireContext(provider, 
                                  NULL, 
                                  NULL, 
-                                 PROV_RSA_FULL, 
+                                 PROV_RSA_AES, 
                                  CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT)) {
           *provider = CryptoX_InvalidHandleValue;
           return CryptoX_Error;
         }
       }
     }
   }
   return CryptoX_Success;
@@ -237,17 +238,17 @@ CryptoX_Result
 CryptoAPI_VerifyBegin(HCRYPTPROV provider, HCRYPTHASH* hash)
 {
   BOOL result;
   if (!provider || !hash) {
     return CryptoX_Error;
   }
 
   *hash = (HCRYPTHASH)NULL;
-  result = CryptCreateHash(provider, CALG_SHA1,
+  result = CryptCreateHash(provider, CALG_SHA_384,
                            0, 0, hash);
   return result ? CryptoX_Success : CryptoX_Error;
 }
 
 /** 
   * Updates a signature verification hash context
   *
   * @param hash The hash context to udpate
@@ -263,11 +264,8 @@ CryptoAPI_VerifyUpdate(HCRYPTHASH* hash,
     return CryptoX_Error;
   }
 
   result = CryptHashData(*hash, buf, len, 0);
   return result ? CryptoX_Success : CryptoX_Error;
 }
 
 #endif
-
-
-
--- a/modules/libmar/verify/mar_verify.c
+++ b/modules/libmar/verify/mar_verify.c
@@ -269,17 +269,17 @@ mar_extract_and_verify_signatures_fp(FIL
       fprintf(stderr, "ERROR: Could not read extracted signature.\n");
       for (i = 0; i < signatureCount; ++i) {
         free(extractedSignatures[i]);
       }
       return CryptoX_Error;
     }
 
     /* We don't try to verify signatures we don't know about */
-    if (signatureAlgorithmIDs[i] != 1) {
+    if (signatureAlgorithmIDs[i] != 2) {
       fprintf(stderr, "ERROR: Unknown signature algorithm ID.\n");
       for (i = 0; i < signatureCount; ++i) {
         free(extractedSignatures[i]);
       }
       return CryptoX_Error;
     }
   }