Bug 1460617 - land NSS 3d3e34bb7517 UPGRADE_NSS_RELEASE, r=me
authorFranziskus Kiefer <franziskuskiefer@gmail.com>
Mon, 28 May 2018 15:45:28 +0200
changeset 420148 f1af1b6d0b11
parent 420147 1d53c55e96df
child 420149 7272c909b033
push id34065
push useraciure@mozilla.com
push dateMon, 28 May 2018 21:54:18 +0000
treeherdermozilla-central@35aa0dde259f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1460617
milestone62.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 1460617 - land NSS 3d3e34bb7517 UPGRADE_NSS_RELEASE, r=me
security/nss/TAG-INFO
security/nss/cmd/certutil/certutil.c
security/nss/coreconf/coreconf.dep
security/nss/lib/freebl/Makefile
security/nss/lib/freebl/freebl.gyp
security/nss/lib/freebl/freebl_base.gypi
security/nss/lib/freebl/unix_urandom.c
security/nss/tests/cert/cert.sh
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-328d235fc7ee
+3d3e34bb7517
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -31,16 +31,18 @@
 #include "pk11func.h"
 #include "secasn1.h"
 #include "cert.h"
 #include "cryptohi.h"
 #include "secoid.h"
 #include "certdb.h"
 #include "nss.h"
 #include "certutil.h"
+#include "basicutil.h"
+#include "ssl.h"
 
 #define MIN_KEY_BITS 512
 /* MAX_KEY_BITS should agree with RSA_MAX_MODULUS_BITS in freebl */
 #define MAX_KEY_BITS 8192
 #define DEFAULT_KEY_BITS 2048
 
 #define GEN_BREAK(e) \
     rv = e;          \
@@ -442,27 +444,36 @@ ChangeTrustAttributes(CERTCertDBHandle *
     }
     CERT_DestroyCertificate(cert);
     PORT_Free(trust);
 
     return SECSuccess;
 }
 
 static SECStatus
-DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii)
+DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii,
+          PRBool simpleSelfSigned)
 {
     CERTCertificate *the_cert;
     CERTCertificateList *chain;
     int i, j;
     the_cert = SECU_FindCertByNicknameOrFilename(handle, name,
                                                  ascii, NULL);
     if (!the_cert) {
         SECU_PrintError(progName, "Could not find: %s\n", name);
         return SECFailure;
     }
+    if (simpleSelfSigned &&
+        SECEqual == SECITEM_CompareItem(&the_cert->derIssuer,
+                                        &the_cert->derSubject)) {
+        printf("\"%s\" [%s]\n\n", the_cert->nickname, the_cert->subjectName);
+        CERT_DestroyCertificate(the_cert);
+        return SECSuccess;
+    }
+
     chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE);
     CERT_DestroyCertificate(the_cert);
     if (!chain) {
         SECU_PrintError(progName, "Could not obtain chain for: %s\n", name);
         return SECFailure;
     }
     for (i = chain->len - 1; i >= 0; i--) {
         CERTCertificate *c;
@@ -1110,17 +1121,19 @@ PrintSyntax()
     FPS "\t\t [-P targetDBPrefix] [--source-prefix sourceDBPrefix]\n");
     FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n");
     FPS "\t%s -L [-n cert-name] [-h token-name] [--email email-address]\n",
         progName);
     FPS "\t\t [-X] [-r] [-a] [--dump-ext-val OID] [-d certdir] [-P dbprefix]\n");
     FPS "\t%s --build-flags\n", progName);
     FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
         progName);
-    FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName);
+    FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n"
+        "\t\t [--simple-self-signed]\n",
+        progName);
     FPS "\t%s -R -s subj -o cert-request-file [-d certdir] [-P dbprefix] [-p phone] [-a]\n"
         "\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile]\n"
         "\t\t [-g key-size] [-Z hashAlg]\n",
         progName);
     FPS "\t%s -V -n cert-name -u usage [-b time] [-e] [-a]\n"
         "\t\t[-X] [-d certdir] [-P dbprefix]\n",
         progName);
     FPS "Usage:  %s -W [-d certdir] [-f pwfile] [-@newpwfile]\n",
@@ -1537,16 +1550,18 @@ luO(enum usage_level ul, const char *com
     FPS "%-20s Cert database directory (default is ~/.netscape)\n",
         "   -d certdir");
     FPS "%-20s Input the certificate in ASCII (RFC1113); default is binary\n",
         "   -a");
     FPS "%-20s Cert & Key database prefix\n",
         "   -P dbprefix");
     FPS "%-20s force the database to open R/W\n",
         "   -X");
+    FPS "%-20s don't search for a chain if issuer name equals subject name\n",
+        "   --simple-self-signed");
     FPS "\n");
 }
 
 static void
 luR(enum usage_level ul, const char *command)
 {
     int is_my_command = (command && 0 == strcmp(command, "R"));
     if (ul == usage_all || !command || is_my_command)
@@ -1555,17 +1570,17 @@ luR(enum usage_level ul, const char *com
     if (ul == usage_selected && !is_my_command)
         return;
     FPS "%-20s Specify the subject name (using RFC1485)\n",
         "   -s subject");
     FPS "%-20s Output the cert request to this file\n",
         "   -o output-req");
     FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
         "   -k key-type-or-id");
-    FPS "%-20s or nickname of the cert key to use \n",
+    FPS "%-20s or nickname of the cert key to use, or key id obtained using -K\n",
         "");
     FPS "%-20s Name of token in which to generate key (default is internal)\n",
         "   -h token-name");
     FPS "%-20s Key size in bits, RSA keys only (min %d, max %d, default %d)\n",
         "   -g key-size", MIN_KEY_BITS, MAX_KEY_BITS, DEFAULT_KEY_BITS);
     FPS "%-20s Create a certificate request restricted to RSA-PSS (rsa only)\n",
         "   --pss");
     FPS "%-20s Name of file containing PQG parameters (dsa only)\n",
@@ -2493,16 +2508,17 @@ enum certutilOpts {
     opt_EmptyPassword,
     opt_CertVersion,
     opt_AddSubjectAltNameExt,
     opt_DumpExtensionValue,
     opt_GenericExtensions,
     opt_NewNickname,
     opt_Pss,
     opt_PssSign,
+    opt_SimpleSelfSigned,
     opt_Help
 };
 
 static const secuCommandFlag commands_init[] =
     {
       { /* cmd_AddCert             */ 'A', PR_FALSE, 0, PR_FALSE },
       { /* cmd_CreateNewCert       */ 'C', PR_FALSE, 0, PR_FALSE },
       { /* cmd_DeleteCert          */ 'D', PR_FALSE, 0, PR_FALSE },
@@ -2617,16 +2633,18 @@ static const secuCommandFlag options_ini
       { /* opt_GenericExtensions   */ 0, PR_TRUE, 0, PR_FALSE,
         "extGeneric" },
       { /* opt_NewNickname         */ 0, PR_TRUE, 0, PR_FALSE,
         "new-n" },
       { /* opt_Pss                 */ 0, PR_FALSE, 0, PR_FALSE,
         "pss" },
       { /* opt_PssSign             */ 0, PR_FALSE, 0, PR_FALSE,
         "pss-sign" },
+      { /* opt_SimpleSelfSigned    */ 0, PR_FALSE, 0, PR_FALSE,
+        "simple-self-signed" },
     };
 #define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0]))
 
 static secuCommandFlag certutil_commands[NUM_COMMANDS];
 static secuCommandFlag certutil_options[NUM_OPTIONS];
 
 static const secuCommand certutil = {
     NUM_COMMANDS,
@@ -3117,16 +3135,18 @@ certutil_main(int argc, char **argv, PRB
         }
         if (rv != SECSuccess) {
             SECU_PrintPRandOSError(progName);
             rv = SECFailure;
             goto shutdown;
         }
         initialized = PR_TRUE;
         SECU_RegisterDynamicOids();
+        /* Ensure the SSL error code table has been registered. Bug 1460284. */
+        SSL_OptionSetDefault(-1, 0);
     }
     certHandle = CERT_GetDefaultCertDB();
 
     if (certutil.commands[cmd_Version].activated) {
         printf("Certificate database content version: command not implemented.\n");
     }
 
     if (PL_strcmp(slotname, "internal") == 0)
@@ -3343,17 +3363,18 @@ certutil_main(int argc, char **argv, PRB
                            certutil.options[opt_BinaryDER].activated,
                            certutil.options[opt_ASCIIForIO].activated,
                            NULL, outFile, &pwdata);
         }
         goto shutdown;
     }
     if (certutil.commands[cmd_DumpChain].activated) {
         rv = DumpChain(certHandle, name,
-                       certutil.options[opt_ASCIIForIO].activated);
+                       certutil.options[opt_ASCIIForIO].activated,
+                       certutil.options[opt_SimpleSelfSigned].activated);
         goto shutdown;
     }
     /*  XXX needs work  */
     /*  List keys (-K)  */
     if (certutil.commands[cmd_ListKeys].activated) {
         rv = ListKeys(slot, name, 0 /*keyindex*/, keytype, PR_FALSE /*dopriv*/,
                       &pwdata);
         goto shutdown;
@@ -3437,47 +3458,90 @@ certutil_main(int argc, char **argv, PRB
     if (certutil.commands[cmd_CertReq].activated ||
         certutil.commands[cmd_CreateAndAddCert].activated ||
         certutil.commands[cmd_GenKeyPair].activated) {
         if (keysource) {
             CERTCertificate *keycert;
             keycert = CERT_FindCertByNicknameOrEmailAddr(certHandle, keysource);
             if (!keycert) {
                 keycert = PK11_FindCertFromNickname(keysource, NULL);
-                if (!keycert) {
-                    SECU_PrintError(progName,
-                                    "%s is neither a key-type nor a nickname", keysource);
+            }
+
+            if (keycert) {
+                privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata);
+            } else {
+                PLArenaPool *arena = NULL;
+                SECItem keyidItem = { 0 };
+                char *keysourcePtr = keysource;
+                /* Interpret keysource as CKA_ID */
+                if (PK11_NeedLogin(slot)) {
+                    rv = PK11_Authenticate(slot, PR_TRUE, &pwdata);
+                    if (rv != SECSuccess) {
+                        SECU_PrintError(progName, "could not authenticate to token %s.",
+                                        PK11_GetTokenName(slot));
+                        return SECFailure;
+                    }
+                }
+                if (0 == PL_strncasecmp("0x", keysource, 2)) {
+                    keysourcePtr = keysource + 2; // skip leading "0x"
+                }
+                arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+                if (!arena) {
+                    SECU_PrintError(progName, "unable to allocate arena");
                     return SECFailure;
                 }
+                if (SECU_HexString2SECItem(arena, &keyidItem, keysourcePtr)) {
+                    privkey = PK11_FindKeyByKeyID(slot, &keyidItem, &pwdata);
+                }
+                PORT_FreeArena(arena, PR_FALSE);
             }
-            privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata);
-            if (privkey)
-                pubkey = CERT_ExtractPublicKey(keycert);
+
+            if (!privkey) {
+                SECU_PrintError(
+                    progName,
+                    "%s is neither a key-type nor a nickname nor a key-id", keysource);
+                return SECFailure;
+            }
+
+            pubkey = SECKEY_ConvertToPublicKey(privkey);
             if (!pubkey) {
                 SECU_PrintError(progName,
                                 "Could not get keys from cert %s", keysource);
+                if (keycert) {
+                    CERT_DestroyCertificate(keycert);
+                }
                 rv = SECFailure;
-                CERT_DestroyCertificate(keycert);
                 goto shutdown;
             }
             keytype = privkey->keyType;
+
             /* On CertReq for renewal if no subject has been
              * specified obtain it from the certificate.
              */
             if (certutil.commands[cmd_CertReq].activated && !subject) {
-                subject = CERT_AsciiToName(keycert->subjectName);
-                if (!subject) {
-                    SECU_PrintError(progName,
-                                    "Could not get subject from certificate %s", keysource);
-                    CERT_DestroyCertificate(keycert);
+                if (keycert) {
+                    subject = CERT_AsciiToName(keycert->subjectName);
+                    if (!subject) {
+                        SECU_PrintError(
+                            progName,
+                            "Could not get subject from certificate %s",
+                            keysource);
+                        CERT_DestroyCertificate(keycert);
+                        rv = SECFailure;
+                        goto shutdown;
+                    }
+                } else {
+                    SECU_PrintError(progName, "Subject name not provided");
                     rv = SECFailure;
                     goto shutdown;
                 }
             }
-            CERT_DestroyCertificate(keycert);
+            if (keycert) {
+                CERT_DestroyCertificate(keycert);
+            }
         } else {
             privkey =
                 CERTUTIL_GeneratePrivateKey(keytype, slot, keysize,
                                             publicExponent,
                                             certutil.options[opt_NoiseFile].arg,
                                             &pubkey,
                                             certutil.options[opt_PQGFile].arg,
                                             keyAttrFlags,
@@ -3530,16 +3594,24 @@ certutil_main(int argc, char **argv, PRB
         if (keytype != rsaKey) {
             PR_fprintf(PR_STDERR,
                        "%s -%c: --pss-sign only works with RSA keys.\n",
                        progName, commandToRun);
             return 255;
         }
     }
 
+    if (certutil.options[opt_SimpleSelfSigned].activated &&
+        !certutil.commands[cmd_DumpChain].activated) {
+        PR_fprintf(PR_STDERR,
+                   "%s -%c: --simple-self-signed only works with -O.\n",
+                   progName, commandToRun);
+        return 255;
+    }
+
     /* If we need a list of extensions convert the flags into list format */
     if (certutil.commands[cmd_CertReq].activated ||
         certutil.commands[cmd_CreateAndAddCert].activated ||
         certutil.commands[cmd_CreateNewCert].activated) {
         certutil_extns[ext_keyUsage].activated =
             certutil.options[opt_AddCmdKeyUsageExt].activated;
         if (!certutil_extns[ext_keyUsage].activated) {
             certutil_extns[ext_keyUsage].activated =
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/lib/freebl/Makefile
+++ b/security/nss/lib/freebl/Makefile
@@ -530,22 +530,26 @@ ifndef NSS_DISABLE_CHACHAPOLY
     VERIFIED_SRCS += Hacl_Chacha20.c
     VERIFIED_SRCS += Hacl_Chacha20_Vec128.c
 endif # NSS_DISABLE_CHACHAPOLY
 
 ifeq (,$(filter-out i386 x386 x86 x86_64 aarch64,$(CPU_ARCH)))
     # All intel architectures get the 64 bit version
     # With custom uint128 if necessary (faster than generic 32 bit version).
     ECL_SRCS += curve25519_64.c
-    VERIFIED_SRCS += Hacl_Curve25519.c FStar.c
+    VERIFIED_SRCS += Hacl_Curve25519.c
 else
     # All non intel architectures get the generic 32 bit implementation (slow!)
     ECL_SRCS += curve25519_32.c
 endif
 
+ifndef HAVE_INT128_SUPPORT
+    VERIFIED_SRCS += FStar.c
+endif
+
 #######################################################################
 # (5) Execute "global" rules. (OPTIONAL)                              #
 #######################################################################
 
 include $(CORE_DEPTH)/coreconf/rules.mk
 
 #######################################################################
 # (6) Execute "component" rules. (OPTIONAL)                           #
--- a/security/nss/lib/freebl/freebl.gyp
+++ b/security/nss/lib/freebl/freebl.gyp
@@ -272,28 +272,20 @@
         },
       }],
       [ 'cc_use_gnu_ld==1 and OS=="win" and target_arch=="x64"', {
         # mingw x64
         'defines': [
           'MP_IS_LITTLE_ENDIAN',
          ],
       }],
-      [ 'OS!="win"', {
-        'conditions': [
-          [ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
-            'defines': [
-              # The Makefile does version-tests on GCC, but we're not doing that here.
-              'HAVE_INT128_SUPPORT',
-            ],
-          }, {
-            'defines': [
-              'KRML_NOUINT128',
-            ],
-          }],
+      [ 'have_int128_support==1', {
+        'defines': [
+          # The Makefile does version-tests on GCC, but we're not doing that here.
+          'HAVE_INT128_SUPPORT',
         ],
       }, {
         'defines': [
           'KRML_NOUINT128',
         ],
       }],
       [ 'OS=="linux"', {
         'defines': [
@@ -345,10 +337,23 @@
             ],
           }],
         ],
       }],
     ],
   },
   'variables': {
     'module': 'nss',
+    'conditions': [
+      [ 'OS!="win"', {
+        'conditions': [
+          [ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
+            'have_int128_support%': 1,
+          }, {
+            'have_int128_support%': 0,
+          }],
+        ],
+      }, {
+        'have_int128_support%': 0,
+      }],
+    ],
   }
 }
--- a/security/nss/lib/freebl/freebl_base.gypi
+++ b/security/nss/lib/freebl/freebl_base.gypi
@@ -55,17 +55,16 @@
     'rsa.c',
     'rsapkcs.c',
     'seed.c',
     'sha512.c',
     'sha_fast.c',
     'shvfy.c',
     'sysrand.c',
     'tlsprfalg.c',
-    'verified/FStar.c',
   ],
   'conditions': [
     [ 'OS=="linux" or OS=="android"', {
       'conditions': [
         [ 'target_arch=="x64"', {
           'sources': [
             'arcfour-amd64-gas.s',
             'intel-aes.s',
@@ -215,13 +214,16 @@
             'MP_USE_UINT_DIGIT',
             'MP_ASSEMBLY_MULTIPLY',
             'MP_ASSEMBLY_SQUARE',
             'MP_ASSEMBLY_DIV_2DX1D',
           ],
         }],
       ],
     }],
+    [ 'have_int128_support==0', {
+        'sources': [ 'verified/FStar.c' ],
+    }],
   ],
  'ldflags': [
    '-Wl,-Bsymbolic'
  ],
 }
--- a/security/nss/lib/freebl/unix_urandom.c
+++ b/security/nss/lib/freebl/unix_urandom.c
@@ -27,17 +27,17 @@ RNG_SystemInfoForRNG(void)
 size_t
 RNG_SystemRNG(void *dest, size_t maxLen)
 {
     int fd;
     int bytes;
     size_t fileBytes = 0;
     unsigned char *buffer = dest;
 
-#if defined(LINUX) && defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25)))
+#if defined(__OpenBSD__) || (defined(LINUX) && defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25))))
     int result;
 
     while (fileBytes < maxLen) {
         size_t getBytes = maxLen - fileBytes;
         if (getBytes > GETENTROPY_MAX_BYTES) {
             getBytes = GETENTROPY_MAX_BYTES;
         }
         result = getentropy(buffer, getBytes);
--- a/security/nss/tests/cert/cert.sh
+++ b/security/nss/tests/cert/cert.sh
@@ -2470,16 +2470,41 @@ EOF
 
   CU_ACTION="Sign ${CERTNAME}'s Request"
   RETEXPECTED=255
   certu -C -c "TestCA-rsa-pss-sha1" --pss-sign -Z SHA256 -m "${CERTSERIAL}" -v 60 -d "${P_R_CADIR}" \
         -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1
   RETEXPECTED=0
 }
 
+cert_test_orphan_key_reuse()
+{
+  CU_ACTION="Create orphan key in serverdir"
+  certu -G -f "${R_PWFILE}" -z ${R_NOISE_FILE} -d ${PROFILEDIR}
+  # Let's get the key ID of the first orphan key.
+  # The output of certutil -K (list keys) isn't well formatted.
+  # The initial <key-number> part may or may not contain white space, which
+  # makes the use of awk to filter the column unreliable.
+  # To fix that, we remove the initial <number> field using sed, then select the
+  # column that contains the key ID.
+  ORPHAN=`${BINDIR}/certutil -d ${PROFILEDIR} -K -f ${R_PWFILE} | \
+          sed 's/^<.*>//g' | grep -w orphan | head -1 | awk '{print $2}'`
+  CU_ACTION="Create cert request for orphan key"
+  certu -R -f "${R_PWFILE}" -k ${ORPHAN} -s "CN=orphan" -d ${PROFILEDIR} \
+        -o ${SERVERDIR}/orphan.req
+  # Ensure that creating the request really works by listing it, and check
+  # if listing was successful.
+  ${BINDIR}/pp -t certificate-request -i ${SERVERDIR}/orphan.req
+  RET=$?
+  if [ "$RET" -ne 0 ]; then
+    html_failed "Listing cert request for orphan key ($RET)"
+    cert_log "ERROR: Listing cert request for orphan key failed $RET"
+  fi
+}
+
 ############################## cert_cleanup ############################
 # local shell function to finish this script (no exit since it might be
 # sourced)
 ########################################################################
 cert_cleanup()
 {
   cert_log "$SCRIPTNAME: finished $SCRIPTNAME"
   html "</TABLE><BR>"
@@ -2489,16 +2514,17 @@ cert_cleanup()
 
 ################## main #################################################
 
 cert_init
 cert_all_CA
 cert_test_implicit_db_init
 cert_extended_ssl
 cert_ssl
+cert_test_orphan_key_reuse
 cert_smime_client
 IS_FIPS_DISABLED=`certutil --build-flags |grep -cw NSS_FIPS_DISABLED`
 if [ $IS_FIPS_DISABLED -ne 0 ]; then
   cert_rsa_exponent_nonfips
 else
   cert_fips
 fi
 cert_eccurves