diff --git a/security/nss/Makefile b/security/nss/Makefile index 6d01a1da..655c4d31 100644 --- a/security/nss/Makefile +++ b/security/nss/Makefile @@ -73,6 +73,9 @@ endif ifdef USE_DEBUG_RTL NSPR_CONFIGURE_OPTS += --enable-debug-rtl endif +ifdef USE_STATIC_RTL +NSPR_CONFIGURE_OPTS += --enable-static-rtl +endif ifdef NS_USE_GCC NSPR_COMPILERS = CC=gcc CXX=g++ endif diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index b2f12f3f..55b6a0c3 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -2367,7 +2367,7 @@ secuCommandFlag options_init[] = "keyAttrFlags"}, { /* opt_EmptyPassword */ 0, PR_FALSE, 0, PR_FALSE, "empty-password"}, - { /* opt_CertVersion */ 0, PR_FALSE, 0, PR_FALSE, + { /* opt_CertVersion */ 0, PR_TRUE, 0, PR_FALSE, "certVersion"}, { /* opt_AddSubjectAltExt */ 0, PR_TRUE, 0, PR_FALSE, "extSAN"}, { /* opt_DumpExtensionValue */ 0, PR_TRUE, 0, PR_FALSE, diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index 0767be98..9f69f7fb 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -92,6 +92,7 @@ SECU_GetPasswordString(void *arg, char *prompt) output = fopen(consoleName, "w"); if (output == NULL) { fprintf(stderr, "Error opening output terminal for write\n"); + fclose(input); return NULL; } @@ -290,6 +291,9 @@ secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg) output = fopen(consoleName, "w"); if (output == NULL) { PR_fprintf(PR_STDERR, "Error opening output terminal for write\n"); +#ifndef _WINDOWS + fclose(input); +#endif return NULL; } diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c index c2f483c5..55503768 100644 --- a/security/nss/cmd/rsaperf/rsaperf.c +++ b/security/nss/cmd/rsaperf/rsaperf.c @@ -401,8 +401,6 @@ main(int argc, char **argv) Usage(progName); } - if (!doPriv && !doPub) doPriv = PR_TRUE; - if (doIters && doTime) Usage(progName); if (!doTime) { @@ -430,9 +428,7 @@ main(int argc, char **argv) if (useTokenKey) { CK_OBJECT_HANDLE kh = CK_INVALID_HANDLE; - CERTCertDBHandle* certdb = NULL; - certdb = CERT_GetDefaultCertDB(); - + cert = PK11_FindCertFromNickname(nickname, &pwData); if (cert == NULL) { fprintf(stderr, @@ -490,9 +486,7 @@ main(int argc, char **argv) exit(1); } - doKeyGen = PR_TRUE; /* Always do a keygen for session keys. - Import of hardcoded key is not supported */ - /* do a temporary keygen in selected slot */ + /* do a temporary keygen in selected slot */ if (!keybits) { keybits = DEFAULT_KEY_BITS; } diff --git a/security/nss/cmd/ssltap/ssltap.c b/security/nss/cmd/ssltap/ssltap.c index 9614f05f..170420a6 100644 --- a/security/nss/cmd/ssltap/ssltap.c +++ b/security/nss/cmd/ssltap/ssltap.c @@ -403,6 +403,7 @@ const char * V2CipherString(int cs_int) case 0x00009E: cs_str = "TLS/DHE-RSA/AES128-GCM/SHA256"; break; case 0x0000FF: cs_str = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; break; + case 0x005600: cs_str = "TLS_FALLBACK_SCSV"; break; case 0x00C001: cs_str = "TLS/ECDH-ECDSA/NULL/SHA"; break; case 0x00C002: cs_str = "TLS/ECDH-ECDSA/RC4-128/SHA"; break; diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index b92dcb1a..664c54f7 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -180,7 +180,7 @@ static void PrintUsageHeader(const char *progName) fprintf(stderr, "Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n" "[-d certdir] [-n nickname] [-Bafosvx] [-c ciphers] [-Y]\n" - "[-V [min-version]:[max-version]] [-T]\n" + "[-V [min-version]:[max-version]] [-K] [-T]\n" "[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]]\n", progName); } @@ -206,6 +206,7 @@ static void PrintParameterUsage(void) "%-20s Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n" "%-20s Example: \"-V ssl3:\" enables SSL 3 and newer.\n", "-V [min]:[max]", "", "", ""); + fprintf(stderr, "%-20s Send TLS_FALLBACK_SCSV\n", "-K"); fprintf(stderr, "%-20s Prints only payload data. Skips HTTP header.\n", "-S"); fprintf(stderr, "%-20s Client speaks first. \n", "-f"); fprintf(stderr, "%-20s Use synchronous certificate validation " @@ -807,6 +808,7 @@ int main(int argc, char **argv) int enableCompression = 0; int enableFalseStart = 0; int enableCertStatus = 0; + int forceFallbackSCSV = 0; PRSocketOptionData opt; PRNetAddr addr; PRPollDesc pollset[2]; @@ -852,7 +854,7 @@ int main(int argc, char **argv) SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions); optstate = PL_CreateOptState(argc, argv, - "46BFM:OSTV:W:Ya:c:d:fgh:m:n:op:qr:st:uvw:xz"); + "46BFKM:OSTV:W:Ya:c:d:fgh:m:n:op:qr:st:uvw:xz"); while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': @@ -874,6 +876,8 @@ int main(int argc, char **argv) case 'O': serverCertAuth.shouldPause = PR_FALSE; break; + case 'K': forceFallbackSCSV = PR_TRUE; break; + case 'M': switch (atoi(optstate->value)) { case 1: serverCertAuth.allowOCSPSideChannelData = PR_TRUE; @@ -1218,6 +1222,14 @@ int main(int argc, char **argv) return 1; } + if (forceFallbackSCSV) { + rv = SSL_OptionSet(s, SSL_ENABLE_FALLBACK_SCSV, PR_TRUE); + if (rv != SECSuccess) { + SECU_PrintError(progName, "error forcing fallback scsv"); + return 1; + } + } + /* enable cert status (OCSP stapling). */ rv = SSL_OptionSet(s, SSL_ENABLE_OCSP_STAPLING, enableCertStatus); if (rv != SECSuccess) { diff --git a/security/nss/coreconf/WIN32.mk b/security/nss/coreconf/WIN32.mk index afece499..bf46a83e 100644 --- a/security/nss/coreconf/WIN32.mk +++ b/security/nss/coreconf/WIN32.mk @@ -30,9 +30,16 @@ else BSDECHO = echo RC = rc.exe MT = mt.exe + # Check for clang-cl + CLANG_CL := $(shell expr `$(CC) -? 2>&1 | grep -w clang | wc -l` \> 0) # Determine compiler version - CC_VERSION := $(shell $(CC) 2>&1 | sed -ne \ + ifeq ($(CLANG_CL),1) + # clang-cl pretends to be MSVC 2012. + CC_VERSION := 17.00.00.00 + else + CC_VERSION := $(shell $(CC) 2>&1 | sed -ne \ 's|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p') + endif # Change the dots to spaces. _CC_VERSION_WORDS := $(subst ., ,$(CC_VERSION)) _CC_VMAJOR := $(word 1,$(_CC_VERSION_WORDS)) @@ -44,6 +51,8 @@ else # VC10 (2010) is 16.00.30319.01, VC10SP1 is 16.00.40219.01. _MSC_VER_GE_10SP1 := $(shell expr $(_MSC_VER) \> 1600 \| \ $(_MSC_VER) = 1600 \& $(_CC_RELEASE) \>= 40219) + # VC11 (2012). + _MSC_VER_GE_11 := $(shell expr $(_MSC_VER) \>= 1700) # VC12 (2013). _MSC_VER_GE_12 := $(shell expr $(_MSC_VER) \>= 1800) ifeq ($(_CC_VMAJOR),14) @@ -127,8 +136,26 @@ else # !NS_USE_GCC ifdef USE_DYNAMICBASE OS_DLLFLAGS += -DYNAMICBASE endif + # + # Define USE_DEBUG_RTL if you want to use the debug runtime library + # (RTL) in the debug build. + # Define USE_STATIC_RTL if you want to use the static RTL. + # + ifdef USE_DEBUG_RTL + ifdef USE_STATIC_RTL + OS_CFLAGS += -MTd + else + OS_CFLAGS += -MDd + endif + OS_CFLAGS += -D_CRTDBG_MAP_ALLOC + else + ifdef USE_STATIC_RTL + OS_CFLAGS += -MT + else + OS_CFLAGS += -MD + endif + endif ifdef BUILD_OPT - OS_CFLAGS += -MD ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE)) OPTIMIZER += -O1 else @@ -146,15 +173,6 @@ else # !NS_USE_GCC LDFLAGS += -DEBUG -OPT:REF endif else - # - # Define USE_DEBUG_RTL if you want to use the debug runtime library - # (RTL) in the debug build - # - ifdef USE_DEBUG_RTL - OS_CFLAGS += -MDd -D_CRTDBG_MAP_ALLOC - else - OS_CFLAGS += -MD - endif OPTIMIZER += -Zi -Fd$(OBJDIR)/ -Od NULLSTRING := SPACE := $(NULLSTRING) # end of the line @@ -194,6 +212,11 @@ ifdef USE_64 DEFINES += -D_AMD64_ else DEFINES += -D_X86_ + # VS2012 defaults to -arch:SSE2. Use -arch:IA32 to avoid requiring + # SSE2. + ifeq ($(_MSC_VER_GE_11),1) + OS_CFLAGS += -arch:IA32 + endif endif endif ifeq ($(CPU_ARCH), ALPHA) diff --git a/security/nss/doc/certutil.xml b/security/nss/doc/certutil.xml index 87280679..b89fa492 100644 --- a/security/nss/doc/certutil.xml +++ b/security/nss/doc/certutil.xml @@ -203,6 +203,11 @@ If this option is not used, the validity check defaults to the current system ti + + --dump-ext-val OID + For single cert, print binary DER encoding of extension OID. + + -e Check a certificate's signature during the process of validating a certificate. @@ -213,6 +218,26 @@ If this option is not used, the validity check defaults to the current system ti Specify the email address of a certificate to list. Used with the -L command option. + + --extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]... + + +Add one or multiple extensions that certutil cannot encode yet, by loading their encodings from external files. + + + +OID (example): 1.2.3.4 + + +critical-flag: critical or not-critical + + +filename: full path to a file containing an encoded extension + + + + + -f password-file Specify a file that will automatically supply the password to include in a certificate @@ -376,6 +401,15 @@ of the attribute codes: V (as an SSL server) +L (as an SSL CA) + + +A (as Any CA) + + +Y (Verify CA) + + S (as an email signer) @@ -648,6 +682,17 @@ of the attribute codes: Add a Name Constraint extension to the certificate. X.509 certificate extensions are described in RFC 5280. + + --extSAN type:name[,type:name]... + +Create a Subject Alt Name extension with one or multiple names. + + +-type: directory, dn, dns, edi, ediparty, email, ip, ipaddr, other, registerid, rfc822, uri, x400, x400addr + + + + --empty-password Use empty password when creating new certificate database with -N. diff --git a/security/nss/doc/html/certutil.html b/security/nss/doc/html/certutil.html index c99513fc..907f90be 100644 --- a/security/nss/doc/html/certutil.html +++ b/security/nss/doc/html/certutil.html @@ -1,4 +1,4 @@ -CERTUTIL

Name

certutil — Manage keys and certificate in both NSS databases and other NSS tokens

Synopsis

certutil [options] [[arguments]]

STATUS

This documentation is still work in progress. Please contribute to the initial review in Mozilla NSS bug 836477 +CERTUTIL

Name

certutil — Manage keys and certificate in both NSS databases and other NSS tokens

Synopsis

certutil [options] [[arguments]]

STATUS

This documentation is still work in progress. Please contribute to the initial review in Mozilla NSS bug 836477

Description

The Certificate Database Tool, certutil, is a command-line utility that can create and modify certificate and key databases. It can specifically list, generate, modify, or delete certificates, create or change the password, generate new public and private key pairs, display the contents of the key database, or delete key pairs within the key database.

Certificate issuance, part of the key and certificate management process, requires that keys and certificates be created in the key database. This document discusses certificate and key database management. For information on the security module database management, see the modutil manpage.

Command Options and Arguments

Running certutil always requires one and only one command option to specify the type of certificate operation. Each command option may take zero or more arguments. The command option -H will list all the command options and their relevant arguments.

Command Options

-A

Add an existing certificate to a certificate database. The certificate database should already exist; if one is not present, this command option will initialize one by default.

-B

Run a series of commands from the specified batch file. This requires the -i argument.

-C

Create a new binary certificate file from a binary certificate request file. Use the -i argument to specify the certificate request file. If this argument is not used, certutil prompts for a filename.

-D

Delete a certificate from the certificate database.

-E

Add an email certificate to the certificate database.

-F

Delete a private key from a key database. Specify the key to delete with the -n argument. Specify the database from which to delete the key with the -d argument. Use the -k argument to specify explicitly whether to delete a DSA, RSA, or ECC key. If you don't use the -k argument, the option looks for an RSA key matching the specified nickname.

@@ -10,7 +10,9 @@ For certificate requests, ASCII output defaults to standard output unless redire

If this option is not used, the validity check defaults to the current system time.

-c issuer

Identify the certificate of the CA from which a new certificate will derive its authenticity. Use the exact nickname or alias of the CA certificate, or use the CA's email address. Bracket the issuer string - with quotation marks if it contains spaces.

-d [prefix]directory

Specify the database directory containing the certificate and key database files.

certutil supports two types of databases: the legacy security databases (cert8.db, key3.db, and secmod.db) and new SQLite databases (cert9.db, key4.db, and pkcs11.txt).

NSS recognizes the following prefixes:

  • sql: requests the newer database

  • dbm: requests the legacy database

If no prefix is specified the default type is retrieved from NSS_DEFAULT_DB_TYPE. If NSS_DEFAULT_DB_TYPE is not set then dbm: is the default.

-e

Check a certificate's signature during the process of validating a certificate.

--email email-address

Specify the email address of a certificate to list. Used with the -L command option.

-f password-file

Specify a file that will automatically supply the password to include in a certificate + with quotation marks if it contains spaces.

-d [prefix]directory

Specify the database directory containing the certificate and key database files.

certutil supports two types of databases: the legacy security databases (cert8.db, key3.db, and secmod.db) and new SQLite databases (cert9.db, key4.db, and pkcs11.txt).

NSS recognizes the following prefixes:

  • sql: requests the newer database

  • dbm: requests the legacy database

If no prefix is specified the default type is retrieved from NSS_DEFAULT_DB_TYPE. If NSS_DEFAULT_DB_TYPE is not set then dbm: is the default.

--dump-ext-val OID

For single cert, print binary DER encoding of extension OID.

-e

Check a certificate's signature during the process of validating a certificate.

--email email-address

Specify the email address of a certificate to list. Used with the -L command option.

--extGeneric OID:critical-flag:filename[,OID:critical-flag:filename]...

+Add one or multiple extensions that certutil cannot encode yet, by loading their encodings from external files. +

  • OID (example): 1.2.3.4

  • critical-flag: critical or not-critical

  • filename: full path to a file containing an encoded extension

-f password-file

Specify a file that will automatically supply the password to include in a certificate or to access a certificate database. This is a plain-text file containing one password. Be sure to prevent unauthorized access to this file.

-g keysize

Set a key size to use when generating new public and private key pairs. The minimum is 512 bits and the maximum is 16384 bits. The default is 1024 bits. Any size between the minimum and maximum is allowed.

-h tokenname

Specify the name of a token to use or act on. If not specified the default token is the internal database slot.

-i input_file

Pass an input file to the command. Depending on the command option, an input file can be a specific certificate, a certificate request file, or a batch file of commands.

-k key-type-or-id

Specify the type or specific ID of a key.

The valid key type options are rsa, dsa, ec, or all. The default @@ -54,7 +56,7 @@ of the attribute codes:

The attribute codes for the categories are separated by commas, and the entire set of attributes enclosed by quotation marks. For example:

-t "TCu,Cu,Tu"

- Use the -L option to see a list of the current certificates and trust attributes in a certificate database.

-u certusage

Specify a usage context to apply when validating a certificate with the -V option.

The contexts are the following:

  • C (as an SSL client)

  • V (as an SSL server)

  • S (as an email signer)

  • R (as an email recipient)

  • O (as an OCSP status responder)

  • J (as an object signer)

-v valid-months

Set the number of months a new certificate will be valid. The validity period begins at the current system time unless an offset is added or subtracted with the -w option. If this argument is not used, the default validity period is three months.

-w offset-months

Set an offset from the current system time, in months, + Use the -L option to see a list of the current certificates and trust attributes in a certificate database.

-u certusage

Specify a usage context to apply when validating a certificate with the -V option.

The contexts are the following:

  • C (as an SSL client)

  • V (as an SSL server)

  • L (as an SSL CA)

  • A (as Any CA)

  • Y (Verify CA)

  • S (as an email signer)

  • R (as an email recipient)

  • O (as an OCSP status responder)

  • J (as an object signer)

-v valid-months

Set the number of months a new certificate will be valid. The validity period begins at the current system time unless an offset is added or subtracted with the -w option. If this argument is not used, the default validity period is three months.

-w offset-months

Set an offset from the current system time, in months, for the beginning of a certificate's validity period. Use when creating the certificate or adding it to a database. Express the offset in integers, using a minus sign (-) to indicate a negative offset. If this argument is @@ -109,7 +111,11 @@ of the attribute codes: msTrustListSign

  • critical -

  • X.509 certificate extensions are described in RFC 5280.

    -7 emailAddrs

    Add a comma-separated list of email addresses to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.

    -8 dns-names

    Add a comma-separated list of DNS names to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.

    --extAIA

    Add the Authority Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extSIA

    Add the Subject Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extCP

    Add the Certificate Policies extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extPM

    Add the Policy Mappings extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extPC

    Add the Policy Constraints extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extIA

    Add the Inhibit Any Policy Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extSKID

    Add the Subject Key ID extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extNC

    Add a Name Constraint extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --empty-password

    Use empty password when creating new certificate database with -N.

    --keyAttrFlags attrflags

    +

    X.509 certificate extensions are described in RFC 5280.

    -7 emailAddrs

    Add a comma-separated list of email addresses to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.

    -8 dns-names

    Add a comma-separated list of DNS names to the subject alternative name extension of a certificate or certificate request that is being created or added to the database. Subject alternative name extensions are described in Section 4.2.1.7 of RFC 3280.

    --extAIA

    Add the Authority Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extSIA

    Add the Subject Information Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extCP

    Add the Certificate Policies extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extPM

    Add the Policy Mappings extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extPC

    Add the Policy Constraints extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extIA

    Add the Inhibit Any Policy Access extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extSKID

    Add the Subject Key ID extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extNC

    Add a Name Constraint extension to the certificate. X.509 certificate extensions are described in RFC 5280.

    --extSAN type:name[,type:name]...

    +Create a Subject Alt Name extension with one or multiple names. +

    +-type: directory, dn, dns, edi, ediparty, email, ip, ipaddr, other, registerid, rfc822, uri, x400, x400addr +

    --empty-password

    Use empty password when creating new certificate database with -N.

    --keyAttrFlags attrflags

    PKCS #11 key Attributes. Comma separated list of key attribute flags, selected from the following list of choices: {token | session} {public | private} {sensitive | insensitive} {modifiable | unmodifiable} {extractable | unextractable}

    --keyOpFlagsOn opflags, --keyOpFlagsOff opflags

    PKCS #11 key Operation Flags. Comma separated list of one or more of the following: diff --git a/security/nss/doc/html/pp.html b/security/nss/doc/html/pp.html index 4407ef72..b9b8ed6e 100644 --- a/security/nss/doc/html/pp.html +++ b/security/nss/doc/html/pp.html @@ -1,7 +1,7 @@ -PP

    Name

    pp — Prints certificates, keys, crls, and pkcs7 files

    Synopsis

    pp -t type [-a] [-i input] [-o output]

    STATUS

    This documentation is still work in progress. Please contribute to the initial review in Mozilla NSS bug 836477 -

    Description

    pp pretty-prints private and public key, certificate, certificate-request, +PP

    Name

    pp — Prints certificates, keys, crls, and pkcs7 files

    Synopsis

    pp -t type [-a] [-i input] [-o output] [-u] [-w]

    STATUS

    This documentation is still work in progress. Please contribute to the initial review in Mozilla NSS bug 836477 +

    Description

    pp pretty-prints private and public key, certificate, certificate-request, pkcs7 or crl files -

    Options

    -t type

    specify the input, one of {private-key | public-key | certificate | certificate-request | pkcs7 | crl}

    -a
    Input is in ascii encoded form (RFC1113)
    -i inputfile
    Define an input file to use (default is stdin)
    -u outputfile
    Define an output file to use (default is stdout)

    Additional Resources

    NSS is maintained in conjunction with PKI and security-related projects through Mozilla and Fedora. The most closely-related project is Dogtag PKI, with a project wiki at PKI Wiki.

    For information specifically about NSS, the NSS project wiki is located at Mozilla NSS site. The NSS site relates directly to NSS code changes and releases.

    Mailing lists: pki-devel@redhat.com and pki-users@redhat.com

    IRC: Freenode at #dogtag-pki

    Authors

    The NSS tools were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google.

    +

    Options

    -t type

    specify the input, one of {private-key | public-key | certificate | certificate-request | pkcs7 | crl}

    -a
    Input is in ascii encoded form (RFC1113)
    -i inputfile
    Define an input file to use (default is stdin)
    -o outputfile
    Define an output file to use (default is stdout)
    -u
    Use UTF-8 (default is to show non-ascii as .)
    -w
    Don't wrap long output lines

    Additional Resources

    NSS is maintained in conjunction with PKI and security-related projects through Mozilla and Fedora. The most closely-related project is Dogtag PKI, with a project wiki at PKI Wiki.

    For information specifically about NSS, the NSS project wiki is located at Mozilla NSS site. The NSS site relates directly to NSS code changes and releases.

    Mailing lists: pki-devel@redhat.com and pki-users@redhat.com

    IRC: Freenode at #dogtag-pki

    Authors

    The NSS tools were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google.

    Authors: Elio Maldonado <emaldona@redhat.com>, Deon Lackey <dlackey@redhat.com>.

    LICENSE

    Licensed under the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

    diff --git a/security/nss/doc/nroff/certutil.1 b/security/nss/doc/nroff/certutil.1 index 1d7f247a..7ae5db01 100644 --- a/security/nss/doc/nroff/certutil.1 +++ b/security/nss/doc/nroff/certutil.1 @@ -2,12 +2,12 @@ .\" Title: CERTUTIL .\" Author: [see the "Authors" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 5 June 2014 +.\" Date: 29 July 2014 .\" Manual: NSS Security Tools .\" Source: nss-tools .\" Language: English .\" -.TH "CERTUTIL" "1" "5 June 2014" "nss-tools" "NSS Security Tools" +.TH "CERTUTIL" "1" "29 July 2014" "nss-tools" "NSS Security Tools" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -250,6 +250,11 @@ If no prefix is specified the default type is retrieved from NSS_DEFAULT_DB_TYPE is the default\&. .RE .PP +\-\-dump\-ext\-val OID +.RS 4 +For single cert, print binary DER encoding of extension OID\&. +.RE +.PP \-e .RS 4 Check a certificate\*(Aqs signature during the process of validating a certificate\&. @@ -260,6 +265,44 @@ Check a certificate\*(Aqs signature during the process of validating a certifica Specify the email address of a certificate to list\&. Used with the \-L command option\&. .RE .PP +\-\-extGeneric OID:critical\-flag:filename[,OID:critical\-flag:filename]\&.\&.\&. +.RS 4 +Add one or multiple extensions that certutil cannot encode yet, by loading their encodings from external files\&. +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +OID (example): 1\&.2\&.3\&.4 +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +critical\-flag: critical or not\-critical +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +filename: full path to a file containing an encoded extension +.RE +.RE +.PP \-f password\-file .RS 4 Specify a file that will automatically supply the password to include in a certificate or to access a certificate database\&. This is a plain\-text file containing one password\&. Be sure to prevent unauthorized access to this file\&. @@ -461,6 +504,42 @@ The contexts are the following: .sp -1 .IP \(bu 2.3 .\} +\fBL\fR +(as an SSL CA) +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBA\fR +(as Any CA) +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +\fBY\fR +(Verify CA) +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} \fBS\fR (as an email signer) .RE @@ -914,6 +993,13 @@ Add the Subject Key ID extension to the certificate\&. X\&.509 certificate exten Add a Name Constraint extension to the certificate\&. X\&.509 certificate extensions are described in RFC 5280\&. .RE .PP +\-\-extSAN type:name[,type:name]\&.\&.\&. +.RS 4 +Create a Subject Alt Name extension with one or multiple names\&. +.sp +\-type: directory, dn, dns, edi, ediparty, email, ip, ipaddr, other, registerid, rfc822, uri, x400, x400addr +.RE +.PP \-\-empty\-password .RS 4 Use empty password when creating new certificate database with \-N\&. diff --git a/security/nss/doc/nroff/pp.1 b/security/nss/doc/nroff/pp.1 index 2c9aa5a6..ce376398 100644 --- a/security/nss/doc/nroff/pp.1 +++ b/security/nss/doc/nroff/pp.1 @@ -2,12 +2,12 @@ .\" Title: PP .\" Author: [see the "Authors" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 -.\" Date: 5 June 2014 +.\" Date: 29 July 2014 .\" Manual: NSS Security Tools .\" Source: nss-tools .\" Language: English .\" -.TH "PP" "1" "5 June 2014" "nss-tools" "NSS Security Tools" +.TH "PP" "1" "29 July 2014" "nss-tools" "NSS Security Tools" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -30,8 +30,8 @@ .SH "NAME" pp \- Prints certificates, keys, crls, and pkcs7 files .SH "SYNOPSIS" -.HP \w'\fBpp\ \-t\ type\ [\-a]\ [\-i\ input]\ [\-o\ output]\fR\ 'u -\fBpp \-t type [\-a] [\-i input] [\-o output]\fR +.HP \w'\fBpp\ \-t\ type\ [\-a]\ [\-i\ input]\ [\-o\ output]\ [\-u]\ [\-w]\fR\ 'u +\fBpp \-t type [\-a] [\-i input] [\-o output] [\-u] [\-w]\fR .SH "STATUS" .PP This documentation is still work in progress\&. Please contribute to the initial review in @@ -57,10 +57,20 @@ Input is in ascii encoded form (RFC1113) Define an input file to use (default is stdin) .RE .PP -\fB\-u \fR \fIoutputfile\fR +\fB\-o \fR \fIoutputfile\fR .RS 4 Define an output file to use (default is stdout) .RE +.PP +\fB\-u \fR +.RS 4 +Use UTF\-8 (default is to show non\-ascii as \&.) +.RE +.PP +\fB\-w \fR +.RS 4 +Don\*(Aqt wrap long output lines +.RE .SH "ADDITIONAL RESOURCES" .PP NSS is maintained in conjunction with PKI and security\-related projects through Mozilla and Fedora\&. The most closely\-related project is Dogtag PKI, with a project wiki at diff --git a/security/nss/doc/pp.xml b/security/nss/doc/pp.xml index 426838a5..24efdf87 100644 --- a/security/nss/doc/pp.xml +++ b/security/nss/doc/pp.xml @@ -26,7 +26,7 @@ - pp -t type [-a] [-i input] [-o output] + pp -t type [-a] [-i input] [-o output] [-u] [-w] @@ -73,12 +73,26 @@ - outputfile + outputfile Define an output file to use (default is stdout) + + + + Use UTF-8 (default is to show non-ascii as .) + + + + + + + Don't wrap long output lines + + + diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index 4ebdf336..0e9e3919 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -1167,7 +1167,7 @@ CERT_DecodeNameConstraintsExtension(PLArenaPool *arena, /* returns addr of a NULL termainated array of pointers to CERTAuthInfoAccess */ extern CERTAuthInfoAccess ** CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena, - SECItem *encodedExtension); + const SECItem *encodedExtension); extern CERTPrivKeyUsagePeriod * CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue); @@ -1561,6 +1561,12 @@ CERT_FindNameConstraintsExten(PLArenaPool *arena, extern CERTGeneralName * CERT_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type); +/* + * Lookup a CERTGeneralNameType constant by its human readable string. + */ +extern CERTGeneralNameType +CERT_GetGeneralNameTypeFromString(const char *string); + /* * PKIX extension encoding routines */ diff --git a/security/nss/lib/certdb/genname.h b/security/nss/lib/certdb/genname.h index 1d94376d..091c82c1 100644 --- a/security/nss/lib/certdb/genname.h +++ b/security/nss/lib/certdb/genname.h @@ -26,9 +26,6 @@ cert_DecodeGeneralNames(PLArenaPool *arena, SECItem **encodedGenName); extern SECStatus cert_DestroyGeneralNames(CERTGeneralName *name); -extern CERTGeneralNameType -CERT_GetGeneralNameTypeFromString(const char *string); - extern SECStatus cert_EncodeNameConstraints(CERTNameConstraints *constraints, PLArenaPool *arena, SECItem *dest); diff --git a/security/nss/lib/certdb/xconst.c b/security/nss/lib/certdb/xconst.c index d4a32f3f..495987c4 100644 --- a/security/nss/lib/certdb/xconst.c +++ b/security/nss/lib/certdb/xconst.c @@ -226,7 +226,7 @@ CERT_DecodeNameConstraintsExtension(PLArenaPool *arena, CERTAuthInfoAccess ** CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena, - SECItem *encodedExtension) + const SECItem *encodedExtension) { CERTAuthInfoAccess **info = NULL; SECStatus rv; diff --git a/security/nss/lib/certhigh/certvfypkix.c b/security/nss/lib/certhigh/certvfypkix.c index 4a6859c9..dcb2dbf2 100644 --- a/security/nss/lib/certhigh/certvfypkix.c +++ b/security/nss/lib/certhigh/certvfypkix.c @@ -27,20 +27,6 @@ extern PRLogModuleInfo *pkixLog; -#ifdef DEBUG_volkov -/* Temporary declarations of functioins. Will be removed with fix for - * 391183 */ -extern char * -pkix_Error2ASCII(PKIX_Error *error, void *plContext); - -extern void -cert_PrintCert(PKIX_PL_Cert *pkixCert, void *plContext); - -extern PKIX_Error * -cert_PrintCertChain(PKIX_List *pkixCertChain, void *plContext); - -#endif /* DEBUG */ - #ifdef PKIX_OBJECT_LEAK_TEST extern PKIX_UInt32 @@ -898,11 +884,6 @@ cert_GetLogFromVerifyNode( if (children == NULL) { PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT; if (node->error && node->error->errCode != errCode) { -#ifdef DEBUG_volkov - char *string = pkix_Error2ASCII(node->error, plContext); - fprintf(stderr, "Branch search finished with error: \t%s\n", string); - PKIX_PL_Free(string, NULL); -#endif if (log != NULL) { SECErrorCodes nssErrorCode = 0; CERTCertificate *cert = NULL; @@ -1003,9 +984,6 @@ cert_GetBuildResults( PKIX_TrustAnchor *trustAnchor = NULL; PKIX_PL_Cert *trustedCert = NULL; PKIX_List *pkixCertChain = NULL; -#ifdef DEBUG_volkov - PKIX_Error *tmpPkixError = NULL; -#endif /* DEBUG */ PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults"); if (buildResult == NULL && error == NULL) { @@ -1014,11 +992,6 @@ cert_GetBuildResults( if (error) { SECErrorCodes nssErrorCode = 0; -#ifdef DEBUG_volkov - char *temp = pkix_Error2ASCII(error, plContext); - fprintf(stderr, "BUILD ERROR:\n%s\n", temp); - PKIX_PL_Free(temp, NULL); -#endif /* DEBUG */ if (verifyNode) { PKIX_Error *tmpError = cert_GetLogFromVerifyNode(log, verifyNode, plContext); @@ -1037,13 +1010,6 @@ cert_GetBuildResults( plContext), PKIX_BUILDRESULTGETCERTCHAINFAILED); -#ifdef DEBUG_volkov - tmpPkixError = cert_PrintCertChain(pkixCertChain, plContext); - if (tmpPkixError) { - PKIX_PL_Object_DecRef((PKIX_PL_Object*)tmpPkixError, plContext); - } -#endif - PKIX_CHECK( cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext), PKIX_CERTCHAINTONSSCHAINFAILED); @@ -1065,13 +1031,7 @@ cert_GetBuildResults( plContext), PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); -#ifdef DEBUG_volkov - if (pvalidChain == NULL) { - cert_PrintCert(trustedCert, plContext); - } -#endif - - PKIX_CHECK( + PKIX_CHECK( PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot, plContext), PKIX_CERTGETCERTCERTIFICATEFAILED); @@ -1158,10 +1118,6 @@ cert_VerifyCertChainPkix( SECStatus rv = SECFailure; void *plContext = NULL; -#ifdef DEBUG_volkov - CERTCertificate *trustedRoot = NULL; - CERTCertList *validChain = NULL; -#endif /* DEBUG */ #ifdef PKIX_OBJECT_LEAK_TEST int leakedObjNum = 0; @@ -1196,10 +1152,6 @@ do { result = NULL; verifyNode = NULL; error = NULL; -#ifdef DEBUG_volkov - trustedRoot = NULL; - validChain = NULL; -#endif /* DEBUG */ errorGenerated = PKIX_FALSE; stackPosition = 0; @@ -1242,29 +1194,11 @@ do { rv = SECSuccess; cleanup: - error = cert_GetBuildResults(result, verifyNode, error, log, -#ifdef DEBUG_volkov - &trustedRoot, &validChain, -#else - NULL, NULL, -#endif /* DEBUG */ + error = cert_GetBuildResults(result, verifyNode, error, log, NULL, NULL, plContext); if (error) { -#ifdef DEBUG_volkov - char *temp = pkix_Error2ASCII(error, plContext); - fprintf(stderr, "GET BUILD RES ERRORS:\n%s\n", temp); - PKIX_PL_Free(temp, NULL); -#endif /* DEBUG */ PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); } -#ifdef DEBUG_volkov - if (trustedRoot) { - CERT_DestroyCertificate(trustedRoot); - } - if (validChain) { - CERT_DestroyCertList(validChain); - } -#endif /* DEBUG */ if (procParams) { PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext); } diff --git a/security/nss/lib/certhigh/certvfypkixprint.c b/security/nss/lib/certhigh/certvfypkixprint.c deleted file mode 100644 index d08d1be6..00000000 --- a/security/nss/lib/certhigh/certvfypkixprint.c +++ /dev/null @@ -1,206 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* - * nss_pkix_proxy.h - * - * PKIX - NSS proxy functions - * - */ -#include "cert.h" -#include "pkix_pl_common.h" - -#ifdef DEBUG - -char * -pkix_Error2ASCII(PKIX_Error *error, void *plContext) -{ - PKIX_UInt32 length; - char *asciiString = NULL; - PKIX_PL_String *pkixString = NULL; - PKIX_Error *errorResult = NULL; - - errorResult = PKIX_PL_Object_ToString - ((PKIX_PL_Object*)error, &pkixString, plContext); - if (errorResult) goto cleanup; - - errorResult = PKIX_PL_String_GetEncoded - (pkixString, - PKIX_ESCASCII, - (void **)&asciiString, - &length, - plContext); - -cleanup: - - if (pkixString){ - if (PKIX_PL_Object_DecRef - ((PKIX_PL_Object*)pkixString, plContext)){ - return (NULL); - } - } - - if (errorResult){ - PKIX_PL_Object_DecRef((PKIX_PL_Object*)errorResult, plContext); - return (NULL); - } - - return (asciiString); -} - -char * -pkix_Object2ASCII(PKIX_PL_Object *object) -{ - PKIX_UInt32 length; - char *asciiString = NULL; - PKIX_PL_String *pkixString = NULL; - PKIX_Error *errorResult = NULL; - - errorResult = PKIX_PL_Object_ToString - (object, &pkixString, NULL); - if (errorResult) goto cleanup; - - errorResult = PKIX_PL_String_GetEncoded - (pkixString, PKIX_ESCASCII, (void **)&asciiString, &length, NULL); - -cleanup: - - if (pkixString){ - if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)pkixString, NULL)){ - return (NULL); - } - } - - if (errorResult){ - return (NULL); - } - - return (asciiString); -} - -char * -pkix_Cert2ASCII(PKIX_PL_Cert *cert) -{ - PKIX_PL_X500Name *issuer = NULL; - void *issuerAscii = NULL; - PKIX_PL_X500Name *subject = NULL; - void *subjectAscii = NULL; - void *asciiString = NULL; - PKIX_Error *errorResult = NULL; - PKIX_UInt32 numChars; - PKIX_UInt32 refCount = 0; - - /* Issuer */ - errorResult = PKIX_PL_Cert_GetIssuer(cert, &issuer, NULL); - if (errorResult) goto cleanup; - - issuerAscii = pkix_Object2ASCII((PKIX_PL_Object*)issuer); - - /* Subject */ - errorResult = PKIX_PL_Cert_GetSubject(cert, &subject, NULL); - if (errorResult) goto cleanup; - - if (subject){ - subjectAscii = pkix_Object2ASCII((PKIX_PL_Object*)subject); - } - -/* errorResult = PKIX_PL_Object_GetRefCount((PKIX_PL_Object*)cert, &refCount, NULL); */ - if (errorResult) goto cleanup; - - errorResult = PKIX_PL_Malloc(200, &asciiString, NULL); - if (errorResult) goto cleanup; - - numChars = - PR_snprintf - (asciiString, - 200, - "Ref: %d Subject=%s\nIssuer=%s\n", - refCount, - subjectAscii, - issuerAscii); - - if (!numChars) goto cleanup; - -cleanup: - - if (issuer){ - if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)issuer, NULL)){ - return (NULL); - } - } - - if (subject){ - if (PKIX_PL_Object_DecRef((PKIX_PL_Object*)subject, NULL)){ - return (NULL); - } - } - - if (PKIX_PL_Free((PKIX_PL_Object*)issuerAscii, NULL)){ - return (NULL); - } - - if (PKIX_PL_Free((PKIX_PL_Object*)subjectAscii, NULL)){ - return (NULL); - } - - if (errorResult){ - return (NULL); - } - - return (asciiString); -} - -PKIX_Error * -cert_PrintCertChain( - PKIX_List *pkixCertChain, - void *plContext) -{ - PKIX_PL_Cert *cert = NULL; - PKIX_UInt32 numCerts = 0, i = 0; - char *asciiResult = NULL; - - PKIX_ENTER(CERTVFYPKIX, "cert_PrintCertChain"); - - PKIX_CHECK( - PKIX_List_GetLength(pkixCertChain, &numCerts, plContext), - PKIX_LISTGETLENGTHFAILED); - - fprintf(stderr, "\n"); - - for (i = 0; i < numCerts; i++){ - PKIX_CHECK - (PKIX_List_GetItem - (pkixCertChain, i, (PKIX_PL_Object**)&cert, plContext), - PKIX_LISTGETITEMFAILED); - - asciiResult = pkix_Cert2ASCII(cert); - - fprintf(stderr, "CERT[%d]:\n%s\n", i, asciiResult); - - PKIX_PL_Free(asciiResult, plContext); - asciiResult = NULL; - - PKIX_DECREF(cert); - } - -cleanup: - PKIX_DECREF(cert); - - PKIX_RETURN(CERTVFYPKIX); -} - -void -cert_PrintCert( - PKIX_PL_Cert *pkixCert, - void *plContext) -{ - char *asciiResult = NULL; - - asciiResult = pkix_Cert2ASCII(pkixCert); - - fprintf(stderr, "CERT[0]:\n%s\n", asciiResult); - - PKIX_PL_Free(asciiResult, plContext); -} - -#endif /* DEBUG */ diff --git a/security/nss/lib/certhigh/manifest.mn b/security/nss/lib/certhigh/manifest.mn index c025d7be..ed9b9108 100644 --- a/security/nss/lib/certhigh/manifest.mn +++ b/security/nss/lib/certhigh/manifest.mn @@ -25,7 +25,6 @@ CSRCS = \ certhigh.c \ certvfy.c \ certvfypkix.c \ - certvfypkixprint.c \ xcrldist.c \ $(NULL) diff --git a/security/nss/lib/ckfw/builtins/bfind.c b/security/nss/lib/ckfw/builtins/bfind.c index e31c4ef0..df35ed8b 100644 --- a/security/nss/lib/ckfw/builtins/bfind.c +++ b/security/nss/lib/ckfw/builtins/bfind.c @@ -183,7 +183,16 @@ nss_builtins_FindObjectsInit NSSArena *arena; NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL; - builtinsInternalObject **temp = (builtinsInternalObject **)NULL; + + /* + * 99% of the time we get 0 or 1 matches. So we start with a small + * stack-allocated array to hold the matches and switch to a heap-allocated + * array later if the number of matches exceeds STACK_BUF_LENGTH. + */ + #define STACK_BUF_LENGTH 1 + builtinsInternalObject *stackTemp[STACK_BUF_LENGTH]; + builtinsInternalObject **temp = stackTemp; + PRBool tempIsHeapAllocated = PR_FALSE; PRUint32 i; arena = NSSArena_Create(); @@ -211,17 +220,24 @@ nss_builtins_FindObjectsInit rv->Next = builtins_mdFindObjects_Next; rv->null = (void *)NULL; - temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *, - nss_builtins_nObjects); - if( (builtinsInternalObject **)NULL == temp ) { - *pError = CKR_HOST_MEMORY; - goto loser; - } - for( i = 0; i < nss_builtins_nObjects; i++ ) { builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i]; if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) { + if( fo->n == STACK_BUF_LENGTH ) { + /* Switch from the small stack array to a heap-allocated array large + * enough to handle matches in all remaining cases. */ + temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *, + fo->n + nss_builtins_nObjects - i); + if( (builtinsInternalObject **)NULL == temp ) { + *pError = CKR_HOST_MEMORY; + goto loser; + } + tempIsHeapAllocated = PR_TRUE; + (void)nsslibc_memcpy(temp, stackTemp, + sizeof(builtinsInternalObject *) * fo->n); + } + temp[ fo->n ] = o; fo->n++; } @@ -234,13 +250,17 @@ nss_builtins_FindObjectsInit } (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n); - nss_ZFreeIf(temp); - temp = (builtinsInternalObject **)NULL; + if (tempIsHeapAllocated) { + nss_ZFreeIf(temp); + temp = (builtinsInternalObject **)NULL; + } return rv; loser: - nss_ZFreeIf(temp); + if (tempIsHeapAllocated) { + nss_ZFreeIf(temp); + } nss_ZFreeIf(fo); nss_ZFreeIf(rv); if ((NSSArena *)NULL != arena) { diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h index ba43e70f..a0ce7b20 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.h +++ b/security/nss/lib/ckfw/builtins/nssckbi.h @@ -44,9 +44,9 @@ * whether we may use its full range (0-255) or only 0-99 because * of the comment in the CK_VERSION type definition. */ -#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1 -#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 98 -#define NSS_BUILTINS_LIBRARY_VERSION "1.98" +#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2 +#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 1 +#define NSS_BUILTINS_LIBRARY_VERSION "2.1" /* These version numbers detail the semantic changes to the ckfw engine. */ #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 diff --git a/security/nss/lib/crmf/respcli.c b/security/nss/lib/crmf/respcli.c index 653bd8a6..5525aaf2 100644 --- a/security/nss/lib/crmf/respcli.c +++ b/security/nss/lib/crmf/respcli.c @@ -92,11 +92,13 @@ CMMF_CertRepContentGetResponseAtIndex(CMMFCertRepContent *inCertRepContent, return NULL; } certResponse = PORT_ZNew(CMMFCertResponse); - rv = cmmf_CopyCertResponse(NULL, certResponse, - inCertRepContent->response[inIndex]); - if (rv != SECSuccess) { - CMMF_DestroyCertResponse(certResponse); - certResponse = NULL; + if (certResponse){ + rv = cmmf_CopyCertResponse(NULL, certResponse, + inCertRepContent->response[inIndex]); + if (rv != SECSuccess) { + CMMF_DestroyCertResponse(certResponse); + certResponse = NULL; + } } return certResponse; } diff --git a/security/nss/lib/crmf/servget.c b/security/nss/lib/crmf/servget.c index 757a7fe3..d19c8290 100644 --- a/security/nss/lib/crmf/servget.c +++ b/security/nss/lib/crmf/servget.c @@ -597,7 +597,7 @@ CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg, return SECFailure; } *destKey = PORT_ZNew(CRMFPOPOPrivKey); - if (destKey == NULL) { + if (*destKey == NULL) { return SECFailure; } return crmf_copy_popoprivkey(NULL, diff --git a/security/nss/lib/cryptohi/secsign.c b/security/nss/lib/cryptohi/secsign.c index 2ea337b3..f2bd229f 100644 --- a/security/nss/lib/cryptohi/secsign.c +++ b/security/nss/lib/cryptohi/secsign.c @@ -445,11 +445,11 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) sigTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; break; case SEC_OID_MD5: sigTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; break; - case SEC_OID_UNKNOWN: /* default for RSA if not specified */ case SEC_OID_SHA1: sigTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break; case SEC_OID_SHA224: sigTag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION; break; + case SEC_OID_UNKNOWN: /* default for RSA if not specified */ case SEC_OID_SHA256: sigTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break; case SEC_OID_SHA384: diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c index c1ac39bc..c869167c 100644 --- a/security/nss/lib/cryptohi/secvfy.c +++ b/security/nss/lib/cryptohi/secvfy.c @@ -12,78 +12,111 @@ #include "secasn1.h" #include "secoid.h" #include "pk11func.h" +#include "pkcs1sig.h" #include "secdig.h" #include "secerr.h" #include "keyi.h" /* -** Decrypt signature block using public key -** Store the hash algorithm oid tag in *tagp -** Store the digest in the digest buffer -** Store the digest length in *digestlen +** Recover the DigestInfo from an RSA PKCS#1 signature. +** +** If givenDigestAlg != SEC_OID_UNKNOWN, copy givenDigestAlg to digestAlgOut. +** Otherwise, parse the DigestInfo structure and store the decoded digest +** algorithm into digestAlgOut. +** +** Store the encoded DigestInfo into digestInfo. +** Store the DigestInfo length into digestInfoLen. +** +** This function does *not* verify that the AlgorithmIdentifier in the +** DigestInfo identifies givenDigestAlg or that the DigestInfo is encoded +** correctly; verifyPKCS1DigestInfo does that. +** ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION */ static SECStatus -DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, - unsigned int *digestlen, unsigned int maxdigestlen, - SECKEYPublicKey *key, const SECItem *sig, char *wincx) +recoverPKCS1DigestInfo(SECOidTag givenDigestAlg, + /*out*/ SECOidTag* digestAlgOut, + /*out*/ unsigned char** digestInfo, + /*out*/ unsigned int* digestInfoLen, + SECKEYPublicKey* key, + const SECItem* sig, void* wincx) { - SGNDigestInfo *di = NULL; - unsigned char *buf = NULL; - SECStatus rv; - SECOidTag tag; - SECItem it; + SGNDigestInfo* di = NULL; + SECItem it; + PRBool rv = SECSuccess; - if (key == NULL) goto loser; + PORT_Assert(digestAlgOut); + PORT_Assert(digestInfo); + PORT_Assert(digestInfoLen); + PORT_Assert(key); + PORT_Assert(key->keyType == rsaKey); + PORT_Assert(sig); + it.data = NULL; it.len = SECKEY_PublicKeyStrength(key); - if (!it.len) goto loser; - it.data = buf = (unsigned char *)PORT_Alloc(it.len); - if (!buf) goto loser; - - /* decrypt the block */ - rv = PK11_VerifyRecover(key, (SECItem *)sig, &it, wincx); - if (rv != SECSuccess) goto loser; - - di = SGN_DecodeDigestInfo(&it); - if (di == NULL) goto sigloser; - - /* - ** Finally we have the digest info; now we can extract the algorithm - ** ID and the signature block - */ - tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm); - /* Check that tag is an appropriate algorithm */ - if (tag == SEC_OID_UNKNOWN) { - goto sigloser; + if (it.len != 0) { + it.data = (unsigned char *)PORT_Alloc(it.len); } - /* make sure the "parameters" are not too bogus. */ - if (di->digestAlgorithm.parameters.len > 2) { - goto sigloser; + if (it.len == 0 || it.data == NULL ) { + rv = SECFailure; } - if (di->digest.len > maxdigestlen) { - PORT_SetError(SEC_ERROR_OUTPUT_LEN); - goto loser; + + if (rv == SECSuccess) { + /* decrypt the block */ + rv = PK11_VerifyRecover(key, sig, &it, wincx); } - PORT_Memcpy(digest, di->digest.data, di->digest.len); - *tagp = tag; - *digestlen = di->digest.len; - goto done; - - sigloser: - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - - loser: - rv = SECFailure; - - done: - if (di != NULL) SGN_DestroyDigestInfo(di); - if (buf != NULL) PORT_Free(buf); + if (rv == SECSuccess) { + if (givenDigestAlg != SEC_OID_UNKNOWN) { + /* We don't need to parse the DigestInfo if the caller gave us the + * digest algorithm to use. Later verifyPKCS1DigestInfo will verify + * that the DigestInfo identifies the given digest algorithm and + * that the DigestInfo is encoded absolutely correctly. + */ + *digestInfoLen = it.len; + *digestInfo = (unsigned char*)it.data; + *digestAlgOut = givenDigestAlg; + return SECSuccess; + } + } + + if (rv == SECSuccess) { + /* The caller didn't specify a digest algorithm to use, so choose the + * digest algorithm by parsing the AlgorithmIdentifier within the + * DigestInfo. + */ + di = SGN_DecodeDigestInfo(&it); + if (!di) { + rv = SECFailure; + } + } + + if (rv == SECSuccess) { + *digestAlgOut = SECOID_GetAlgorithmTag(&di->digestAlgorithm); + if (*digestAlgOut == SEC_OID_UNKNOWN) { + rv = SECFailure; + } + } + + if (di) { + SGN_DestroyDigestInfo(di); + } + + if (rv == SECSuccess) { + *digestInfoLen = it.len; + *digestInfo = (unsigned char*)it.data; + } else { + if (it.data) { + PORT_Free(it.data); + } + *digestInfo = NULL; + *digestInfoLen = 0; + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + } + return rv; } - struct VFYContextStr { SECOidTag hashAlg; /* the hash algorithm */ SECKEYPublicKey *key; @@ -99,14 +132,14 @@ struct VFYContextStr { union { unsigned char buffer[1]; - /* the digest in the decrypted RSA signature */ - unsigned char rsadigest[HASH_LENGTH_MAX]; /* the full DSA signature... 40 bytes */ unsigned char dsasig[DSA_MAX_SIGNATURE_LEN]; /* the full ECDSA signature */ unsigned char ecdsasig[2 * MAX_ECKEY_LEN]; } u; - unsigned int rsadigestlen; + unsigned int pkcs1RSADigestInfoLen; + /* the encoded DigestInfo from a RSA PKCS#1 signature */ + unsigned char *pkcs1RSADigestInfo; void * wincx; void *hashcx; const SECHashObject *hashobj; @@ -117,6 +150,17 @@ struct VFYContextStr { * VFY_EndWithSignature call. */ }; +static SECStatus +verifyPKCS1DigestInfo(const VFYContext* cx, const SECItem* digest) +{ + SECItem pkcs1DigestInfo; + pkcs1DigestInfo.data = cx->pkcs1RSADigestInfo; + pkcs1DigestInfo.len = cx->pkcs1RSADigestInfoLen; + return _SGN_VerifyPKCS1DigestInfo( + cx->hashAlg, digest, &pkcs1DigestInfo, + PR_TRUE /*XXX: unsafeAllowMissingParameters*/); +} + /* * decode the ECDSA or DSA signature from it's DER wrapping. * The unwrapped/raw signature is placed in the buffer pointed @@ -376,16 +420,16 @@ vfy_CreateContext(const SECKEYPublicKey *key, const SECItem *sig, cx->encAlg = encAlg; cx->hashAlg = hashAlg; cx->key = SECKEY_CopyPublicKey(key); + cx->pkcs1RSADigestInfo = NULL; rv = SECSuccess; if (sig) { switch (type) { case rsaKey: - rv = DecryptSigBlock(&cx->hashAlg, cx->u.buffer, &cx->rsadigestlen, - HASH_LENGTH_MAX, cx->key, sig, (char*)wincx); - if (cx->hashAlg != hashAlg && hashAlg != SEC_OID_UNKNOWN) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - rv = SECFailure; - } + rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, + &cx->pkcs1RSADigestInfo, + &cx->pkcs1RSADigestInfoLen, + cx->key, + sig, wincx); break; case dsaKey: case ecKey: @@ -469,6 +513,9 @@ VFY_DestroyContext(VFYContext *cx, PRBool freeit) if (cx->key) { SECKEY_DestroyPublicKey(cx->key); } + if (cx->pkcs1RSADigestInfo) { + PORT_Free(cx->pkcs1RSADigestInfo); + } if (freeit) { PORT_ZFree(cx, sizeof(VFYContext)); } @@ -548,21 +595,25 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) } break; case rsaKey: + { + SECItem digest; + digest.data = final; + digest.len = part; if (sig) { - SECOidTag hashid = SEC_OID_UNKNOWN; - rv = DecryptSigBlock(&hashid, cx->u.buffer, &cx->rsadigestlen, - HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx); - if ((rv != SECSuccess) || (hashid != cx->hashAlg)) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + SECOidTag hashid; + PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN); + rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid, + &cx->pkcs1RSADigestInfo, + &cx->pkcs1RSADigestInfoLen, + cx->key, + sig, cx->wincx); + PORT_Assert(cx->hashAlg == hashid); + if (rv != SECSuccess) { return SECFailure; } } - if ((part != cx->rsadigestlen) || - PORT_Memcmp(final, cx->u.buffer, part)) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - return SECFailure; - } - break; + return verifyPKCS1DigestInfo(cx, &digest); + } default: PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; /* shouldn't happen */ @@ -595,12 +646,7 @@ vfy_VerifyDigest(const SECItem *digest, const SECKEYPublicKey *key, if (cx != NULL) { switch (key->keyType) { case rsaKey: - if ((digest->len != cx->rsadigestlen) || - PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - } else { - rv = SECSuccess; - } + rv = verifyPKCS1DigestInfo(cx, digest); break; case dsaKey: case ecKey: diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index ec6a7698..68fcddfe 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -141,6 +141,9 @@ else DEFINES += -DUSE_HW_AES -DINTEL_GCM ASFILES += intel-aes-x86-masm.asm intel-gcm-x86-masm.asm EXTRA_SRCS += intel-gcm-wrap.c + ifeq ($(CLANG_CL),1) + INTEL_GCM_CLANG_CL = 1 + endif endif endif else @@ -668,3 +671,10 @@ ifneq (,$(findstring clang,$(shell $(AS) --version))) $(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): ASFLAGS += -no-integrated-as endif endif + +ifdef INTEL_GCM_CLANG_CL +# +# clang-cl needs -mssse3 +# +$(OBJDIR)/$(PROG_PREFIX)intel-gcm-wrap$(OBJ_SUFFIX): CFLAGS += -mssse3 +endif diff --git a/security/nss/lib/freebl/cts.c b/security/nss/lib/freebl/cts.c index 74cdc0be..5d4ed18b 100644 --- a/security/nss/lib/freebl/cts.c +++ b/security/nss/lib/freebl/cts.c @@ -239,7 +239,6 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf, return SECSuccess; } outbuf += fullblocks; - maxout -= fullblocks; /* recover the stolen text */ PORT_Memset(lastBlock, 0, blocksize); diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c index ca53c1ae..6af242dc 100644 --- a/security/nss/lib/freebl/ec.c +++ b/security/nss/lib/freebl/ec.c @@ -870,6 +870,11 @@ cleanup: /* ** Checks the signature on the given digest using the key provided. +** +** The key argument must represent a valid EC public key (a point on +** the relevant curve). If it is not a valid point, then the behavior +** of this function is undefined. In cases where a public key might +** not be valid, use EC_ValidatePublicKey to check. */ SECStatus ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, diff --git a/security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm b/security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm index ead73bbe..cb432583 100644 --- a/security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm +++ b/security/nss/lib/freebl/mpi/mp_comba_amd64_masm.asm @@ -7863,13 +7863,13 @@ s_mp_sqr_comba_4 PROC mov rsi, rdx push rbp + push rbx sub rsp, 80 mov r11, rsi xor esi, esi mov r10, rsi mov rbp, rsi mov r8, rsi - push rbx mov rbx, rsi mov rcx, qword ptr [16+rdi] mov rdi, rsi diff --git a/security/nss/lib/freebl/rsa.c b/security/nss/lib/freebl/rsa.c index cc7d4fee..498cc96b 100644 --- a/security/nss/lib/freebl/rsa.c +++ b/security/nss/lib/freebl/rsa.c @@ -97,8 +97,8 @@ static struct RSABlindingParamsListStr blindingParamsList = { 0 }; static PRBool nssRSAUseBlinding = PR_TRUE; static SECStatus -rsa_build_from_primes(mp_int *p, mp_int *q, - mp_int *e, PRBool needPublicExponent, +rsa_build_from_primes(const mp_int *p, const mp_int *q, + mp_int *e, PRBool needPublicExponent, mp_int *d, PRBool needPrivateExponent, RSAPrivateKey *key, unsigned int keySizeInBits) { @@ -116,6 +116,12 @@ rsa_build_from_primes(mp_int *p, mp_int *q, CHECK_MPI_OK( mp_init(&psub1) ); CHECK_MPI_OK( mp_init(&qsub1) ); CHECK_MPI_OK( mp_init(&tmp) ); + /* p and q must be distinct. */ + if (mp_cmp(p, q) == 0) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + rv = SECFailure; + goto cleanup; + } /* 1. Compute n = p*q */ CHECK_MPI_OK( mp_mul(p, q, &n) ); /* verify that the modulus has the desired number of bits */ @@ -280,7 +286,11 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent) PORT_SetError(0); CHECK_SEC_OK( generate_prime(&p, primeLen) ); CHECK_SEC_OK( generate_prime(&q, primeLen) ); - /* Assure q < p */ + /* Assure p > q */ + /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any + * implementation optimization that requires p > q. We can remove + * this code in the future. + */ if (mp_cmp(&p, &q) < 0) mp_exch(&p, &q); /* Attempt to use these primes to generate a key */ @@ -762,7 +772,11 @@ RSA_PopulatePrivateKey(RSAPrivateKey *key) } } - /* force p to the the larger prime */ + /* Assure p > q */ + /* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any + * implementation optimization that requires p > q. We can remove + * this code in the future. + */ if (mp_cmp(&p, &q) < 0) mp_exch(&p, &q); @@ -1093,7 +1107,7 @@ get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen, { RSABlindingParams *rsabp = NULL; blindingParams *bpUnlinked = NULL; - blindingParams *bp, *prevbp = NULL; + blindingParams *bp; PRCList *el; SECStatus rv = SECSuccess; mp_err err = MP_OKAY; @@ -1183,7 +1197,6 @@ get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen, } /* We did not find a usable set of blinding params. Can we make one? */ /* Find a free bp struct. */ - prevbp = NULL; if ((bp = rsabp->free) != NULL) { /* unlink this bp */ rsabp->free = bp->next; @@ -1400,8 +1413,8 @@ RSA_PrivateKeyCheck(const RSAPrivateKey *key) SECITEM_TO_MPINT(key->exponent1, &d_p); SECITEM_TO_MPINT(key->exponent2, &d_q); SECITEM_TO_MPINT(key->coefficient, &qInv); - /* p > q */ - if (mp_cmp(&p, &q) <= 0) { + /* p and q must be distinct. */ + if (mp_cmp(&p, &q) == 0) { rv = SECFailure; goto cleanup; } diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c index 4bbf618e..4f29de28 100644 --- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c +++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c @@ -122,7 +122,7 @@ pkix_pl_CrlDp_Create( if (!rdnArena) { PKIX_ERROR(PKIX_PORTARENAALLOCFAILED); } - issuerNameCopy = (CERTName *)PORT_ArenaZNew(rdnArena, CERTName*); + issuerNameCopy = (CERTName *)PORT_ArenaZNew(rdnArena, CERTName); if (!issuerNameCopy) { PKIX_ERROR(PKIX_ALLOCERROR); } diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index 6f6b6708..48bb2f22 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -1062,3 +1062,9 @@ PK11_PrivDecrypt; ;+ local: ;+ *; ;+}; +;+NSS_3.18 { # NSS 3.18 release +;+ global: +PK11_SetCertificateNickname; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 4d3d1f5e..6121563f 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -33,9 +33,9 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define NSS_VERSION "3.16.2.1" _NSS_ECC_STRING _NSS_CUSTOMIZED +#define NSS_VERSION "3.17.2.1" _NSS_ECC_STRING _NSS_CUSTOMIZED #define NSS_VMAJOR 3 -#define NSS_VMINOR 16 +#define NSS_VMINOR 17 #define NSS_VPATCH 2 #define NSS_VBUILD 1 #define NSS_BETA PR_FALSE diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c index a748e524..c1fe55c5 100644 --- a/security/nss/lib/pk11wrap/dev3hack.c +++ b/security/nss/lib/pk11wrap/dev3hack.c @@ -92,14 +92,14 @@ nssSession_Destroy nssSession *s ) { - CK_RV ckrv = CKR_OK; + PRStatus rv = PR_SUCCESS; if (s) { if (s->isRW) { PK11_RestoreROSession(s->slot->pk11slot, s->handle); } - nss_ZFreeIf(s); + rv = nss_ZFreeIf(s); } - return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; + return rv; } static NSSSlot * diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 3f3edb11..c4250c64 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -982,12 +982,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, */ nssPKIObject_AddInstance(&c->object, certobj); /* nssTrustDomain_AddCertsToCache may release a reference to 'c' and - * replace 'c' by a different value. So we add a reference to 'c' to + * replace 'c' with a different value. So we add a reference to 'c' to * prevent 'c' from being destroyed. */ nssCertificate_AddRef(c); nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1); - /* XXX should we pass the original value of 'c' to - * STAN_ForceCERTCertificateUpdate? */ (void)STAN_ForceCERTCertificateUpdate(c); nssCertificate_Destroy(c); SECITEM_FreeItem(keyID,PR_TRUE); @@ -2155,7 +2153,6 @@ PK11_FindCertFromDERCertItem(PK11SlotInfo *slot, const SECItem *inDerCert, { NSSDER derCert; NSSToken *tok; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); nssCryptokiObject *co = NULL; SECStatus rv; @@ -2689,3 +2686,14 @@ PK11_GetAllSlotsForCert(CERTCertificate *cert, void *arg) nssCryptokiObjectArray_Destroy(instances); return slotList; } + +SECStatus +PK11_SetCertificateNickname(CERTCertificate *cert, const char *nickname) +{ + /* Can't set nickname of temp cert. */ + if (!cert->slot || cert->pkcs11ID == CK_INVALID_HANDLE) { + return SEC_ERROR_INVALID_ARGS; + } + return PK11_SetObjectNickname(cert->slot, cert->pkcs11ID, nickname); +} + diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h index f0bf2c88..709ce21e 100644 --- a/security/nss/lib/pk11wrap/pk11pub.h +++ b/security/nss/lib/pk11wrap/pk11pub.h @@ -458,6 +458,8 @@ SECStatus PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, const char *nickname); SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname); +SECStatus PK11_SetCertificateNickname(CERTCertificate *cert, + const char *nickname); /* size to hold key in bytes */ unsigned int PK11_GetKeyLength(PK11SymKey *key); diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c index 58ff5da9..4a384ad5 100644 --- a/security/nss/lib/pk11wrap/pk11util.c +++ b/security/nss/lib/pk11wrap/pk11util.c @@ -1185,7 +1185,7 @@ end_wait: SECStatus SECMOD_CancelWait(SECMODModule *mod) { - unsigned long controlMask = mod->evControlMask; + unsigned long controlMask; SECStatus rv = SECSuccess; CK_RV crv; diff --git a/security/nss/lib/softoken/legacydb/lowcert.c b/security/nss/lib/softoken/legacydb/lowcert.c index 0b0540bc..a8191d87 100644 --- a/security/nss/lib/softoken/legacydb/lowcert.c +++ b/security/nss/lib/softoken/legacydb/lowcert.c @@ -447,7 +447,7 @@ nsslowcert_EmailName(SECItem *derDN, char *space, unsigned int len) name=nsslowcert_dataStart(ava, ava_length, &name_length, PR_FALSE, NULL); - if (oid == NULL) { return NULL; } + if (name == NULL) { return NULL; } ava_length -= (name-ava)+name_length; ava = name+name_length; diff --git a/security/nss/lib/softoken/legacydb/pcertdb.c b/security/nss/lib/softoken/legacydb/pcertdb.c index 58fe27af..5f767006 100644 --- a/security/nss/lib/softoken/legacydb/pcertdb.c +++ b/security/nss/lib/softoken/legacydb/pcertdb.c @@ -4733,7 +4733,6 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue SECItem *sn = &issuerAndSN->serialNumber; SECItem *issuer = &issuerAndSN->derIssuer; NSSLOWCERTCertificate *cert; - int data_left = sn->len-1; int data_len = sn->len; int index = 0; @@ -4743,7 +4742,7 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue if ((sn->len >= 3) && (sn->data[0] == 0x2)) { /* remove the der encoding of the serial number before generating the * key.. */ - data_left = sn->len-2; + int data_left = sn->len-2; data_len = sn->data[1]; index = 2; @@ -4818,7 +4817,6 @@ nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, SECItem *issuer = &issuerAndSN->derIssuer; NSSLOWCERTTrust *trust; unsigned char keyBuf[512]; - int data_left = sn->len-1; int data_len = sn->len; int index = 0; int len; @@ -4829,7 +4827,7 @@ nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, if ((sn->len >= 3) && (sn->data[0] == 0x2)) { /* remove the der encoding of the serial number before generating the * key.. */ - data_left = sn->len-2; + int data_left = sn->len-2; data_len = sn->data[1]; index = 2; diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 6fa4e4ec..bd7c4bd5 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -969,6 +969,17 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object, } object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey; + /* Check that an imported EC key is valid */ + if (key_type == CKK_EC) { + NSSLOWKEYPublicKey *pubKey = (NSSLOWKEYPublicKey*) object->objectInfo; + SECStatus rv = EC_ValidatePublicKey(&pubKey->u.ec.ecParams, + &pubKey->u.ec.publicValue); + + if (rv != SECSuccess) { + return CKR_TEMPLATE_INCONSISTENT; + } + } + if (sftk_isTrue(object,CKA_TOKEN)) { SFTKSlot *slot = session->slot; SFTKDBHandle *certHandle = sftk_getCertDB(slot); diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 8f50882a..fc050f35 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -23,6 +23,7 @@ #include "blapi.h" #include "pkcs11.h" #include "pkcs11i.h" +#include "pkcs1sig.h" #include "lowkeyi.h" #include "secder.h" #include "secdig.h" @@ -2856,65 +2857,42 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, const unsigned char *sig, } SECStatus -RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key, +RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key, const unsigned char *sig, unsigned int sigLen, - const unsigned char *hash, unsigned int hashLen) + const unsigned char *digestData, unsigned int digestLen) { - SECItem it; - SGNDigestInfo *di = NULL; - SECStatus rv = SECSuccess; + unsigned char *pkcs1DigestInfoData; + SECItem pkcs1DigestInfo; + SECItem digest; + unsigned int bufferSize; + SECStatus rv; - it.data = NULL; - it.len = nsslowkey_PublicModulusLen(key); - if (!it.len) { - goto loser; - } - - it.data = (unsigned char *)PORT_Alloc(it.len); - if (it.data == NULL) { - goto loser; + /* pkcs1DigestInfo.data must be less than key->u.rsa.modulus.len */ + bufferSize = key->u.rsa.modulus.len; + pkcs1DigestInfoData = PORT_ZAlloc(bufferSize); + if (!pkcs1DigestInfoData) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return SECFailure; } + pkcs1DigestInfo.data = pkcs1DigestInfoData; + pkcs1DigestInfo.len = bufferSize; + /* decrypt the block */ - rv = RSA_CheckSignRecover(&key->u.rsa, it.data, &it.len, it.len, sig, - sigLen); + rv = RSA_CheckSignRecover(&key->u.rsa, pkcs1DigestInfo.data, + &pkcs1DigestInfo.len, pkcs1DigestInfo.len, + sig, sigLen); if (rv != SECSuccess) { - goto loser; - } - - di = SGN_DecodeDigestInfo(&it); - if (di == NULL) { - goto loser; - } - if (di->digest.len != hashLen) { - goto loser; - } - - /* make sure the tag is OK */ - if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) { - goto loser; - } - /* make sure the "parameters" are not too bogus. */ - if (di->digestAlgorithm.parameters.len > 2) { - goto loser; - } - /* Now check the signature */ - if (PORT_Memcmp(hash, di->digest.data, di->digest.len) == 0) { - goto done; - } - - loser: - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - rv = SECFailure; - - done: - if (it.data != NULL) { - PORT_Free(it.data); - } - if (di != NULL) { - SGN_DestroyDigestInfo(di); + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + } else { + digest.data = (PRUint8*) digestData; + digest.len = digestLen; + rv = _SGN_VerifyPKCS1DigestInfo( + digestOid, &digest, &pkcs1DigestInfo, + PR_TRUE /*XXX: unsafeAllowMissingParameters*/); } + PORT_Free(pkcs1DigestInfoData); return rv; } diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index 8fed46d2..fd8ad58d 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -25,9 +25,9 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define SOFTOKEN_VERSION "3.16.2.1" SOFTOKEN_ECC_STRING +#define SOFTOKEN_VERSION "3.17.2.1" SOFTOKEN_ECC_STRING #define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 16 +#define SOFTOKEN_VMINOR 17 #define SOFTOKEN_VPATCH 2 #define SOFTOKEN_VBUILD 1 #define SOFTOKEN_BETA PR_FALSE diff --git a/security/nss/lib/ssl/SSLerrs.h b/security/nss/lib/ssl/SSLerrs.h index bbe2bd9b..174037b1 100644 --- a/security/nss/lib/ssl/SSLerrs.h +++ b/security/nss/lib/ssl/SSLerrs.h @@ -418,3 +418,7 @@ ER3(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK, (SSL_ERROR_BASE + 129), ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130), "The server supports no protocols that the client advertises in the ALPN extension.") + +ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131), +"The server rejected the handshake because the client downgraded to a lower " +"TLS version than the server supports.") diff --git a/security/nss/lib/ssl/config.mk b/security/nss/lib/ssl/config.mk index da8b9ef7..40b1c301 100644 --- a/security/nss/lib/ssl/config.mk +++ b/security/nss/lib/ssl/config.mk @@ -7,6 +7,11 @@ ifdef NISCC_TEST DEFINES += -DNISCC_TEST endif +# Allow build-time configuration of TLS 1.3 (Experimental) +ifdef NSS_ENABLE_TLS_1_3 +DEFINES += -DNSS_ENABLE_TLS_1_3 +endif + ifdef NSS_NO_PKCS11_BYPASS DEFINES += -DNO_PKCS11_BYPASS else diff --git a/security/nss/lib/ssl/dtlscon.c b/security/nss/lib/ssl/dtlscon.c index 4e384619..89315eee 100644 --- a/security/nss/lib/ssl/dtlscon.c +++ b/security/nss/lib/ssl/dtlscon.c @@ -52,6 +52,7 @@ static const ssl3CipherSuite nonDTLSSuites[] = { * TLS DTLS * 1.1 (0302) 1.0 (feff) * 1.2 (0303) 1.2 (fefd) + * 1.3 (0304) 1.3 (fefc) */ SSL3ProtocolVersion dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv) @@ -62,6 +63,9 @@ dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv) if (tlsv == SSL_LIBRARY_VERSION_TLS_1_2) { return SSL_LIBRARY_VERSION_DTLS_1_2_WIRE; } + if (tlsv == SSL_LIBRARY_VERSION_TLS_1_3) { + return SSL_LIBRARY_VERSION_DTLS_1_3_WIRE; + } /* Anything other than TLS 1.1 or 1.2 is an error, so return * the invalid version 0xffff. */ @@ -85,6 +89,9 @@ dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv) if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_2_WIRE) { return SSL_LIBRARY_VERSION_TLS_1_2; } + if (dtlsv == SSL_LIBRARY_VERSION_DTLS_1_3_WIRE) { + return SSL_LIBRARY_VERSION_TLS_1_3; + } /* Return a fictional higher version than we know of */ return SSL_LIBRARY_VERSION_TLS_1_2 + 1; diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h index 35418e38..91a47a69 100644 --- a/security/nss/lib/ssl/ssl.h +++ b/security/nss/lib/ssl/ssl.h @@ -182,6 +182,15 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd); */ #define SSL_ENABLE_ALPN 26 +/* SSL_REUSE_SERVER_ECDHE_KEY controls whether the ECDHE server key is + * reused for multiple handshakes or generated each time. + * SSL_REUSE_SERVER_ECDHE_KEY is currently enabled by default. + */ +#define SSL_REUSE_SERVER_ECDHE_KEY 27 + +#define SSL_ENABLE_FALLBACK_SCSV 28 /* Send fallback SCSV in + * handshakes. */ + #ifdef SSL_DEPRECATED_FUNCTION /* Old deprecated function names */ SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRBool on); diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 01164e5e..c6d1e0e5 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -215,7 +215,10 @@ compressionEnabled(sslSocket *ss, SSLCompressionMethod compression) return PR_TRUE; /* Always enabled */ #ifdef NSS_ENABLE_ZLIB case ssl_compression_deflate: - return ss->opt.enableDeflate; + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + return ss->opt.enableDeflate; + } + return PR_FALSE; #endif default: return PR_FALSE; @@ -637,14 +640,16 @@ ssl3_CipherSuiteAllowedForVersionRange( case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: case TLS_RSA_WITH_AES_256_CBC_SHA256: case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: case TLS_RSA_WITH_AES_128_CBC_SHA256: case TLS_RSA_WITH_AES_128_GCM_SHA256: case TLS_RSA_WITH_NULL_SHA256: + return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2; + + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_2; /* RFC 4492: ECC cipher suites need TLS extensions to negotiate curves and @@ -669,10 +674,11 @@ ssl3_CipherSuiteAllowedForVersionRange( case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0; + return vrange->max >= SSL_LIBRARY_VERSION_TLS_1_0 && + vrange->min < SSL_LIBRARY_VERSION_TLS_1_3; default: - return PR_TRUE; + return vrange->min < SSL_LIBRARY_VERSION_TLS_1_3; } } @@ -3352,6 +3358,9 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) case certificate_unknown: error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT; break; case illegal_parameter: error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break; + case inappropriate_fallback: + error = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT; + break; /* All alerts below are TLS only. */ case unknown_ca: error = SSL_ERROR_UNKNOWN_CA_ALERT; break; @@ -4873,6 +4882,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) int num_suites; int actual_count = 0; PRBool isTLS = PR_FALSE; + PRBool requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE; PRInt32 total_exten_len = 0; unsigned paddingExtensionLen; unsigned numCompressionMethods; @@ -5015,6 +5025,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) } if (sid) { + requestingResume = PR_TRUE; SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID, @@ -5105,7 +5116,6 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } return SECFailure; } - maxBytes -= extLen; total_exten_len += extLen; if (total_exten_len > 0) @@ -5129,8 +5139,15 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } return SECFailure; /* count_cipher_suites has set error code. */ } + + fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume || + ss->version < sid->version); + /* make room for SCSV */ if (ss->ssl3.hs.sendingSCSV) { - ++num_suites; /* make room for SCSV */ + ++num_suites; + } + if (fallbackSCSV) { + ++num_suites; } /* count compression methods */ @@ -5236,6 +5253,15 @@ ssl3_SendClientHello(sslSocket *ss, PRBool resending) } actual_count++; } + if (fallbackSCSV) { + rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV, + sizeof(ssl3CipherSuite)); + if (rv != SECSuccess) { + if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); } + return rv; /* err set by ssl3_AppendHandshake* */ + } + actual_count++; + } for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i]; if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) { @@ -7711,12 +7737,31 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) goto loser; /* malformed */ } + /* If the ClientHello version is less than our maximum version, check for a + * TLS_FALLBACK_SCSV and reject the connection if found. */ + if (ss->vrange.max > ss->clientHelloVersion) { + for (i = 0; i + 1 < suites.len; i += 2) { + PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1]; + if (suite_i != TLS_FALLBACK_SCSV) + continue; + desc = inappropriate_fallback; + errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT; + goto alert_loser; + } + } + /* grab the list of compression methods. */ rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length); if (rv != SECSuccess) { goto loser; /* malformed */ } + /* TLS 1.3 requires that compression be empty */ + if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { + if (comps.len != 1 || comps.data[0] != ssl_compression_null) { + goto loser; + } + } desc = handshake_failure; /* Handle TLS hello extensions for SSL3 & TLS. We do not know if @@ -9379,6 +9424,10 @@ skip: } rv = ssl3_HandleECDHClientKeyExchange(ss, b, length, serverPubKey, serverKey); + if (ss->ephemeralECDHKeyPair) { + ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); + ss->ephemeralECDHKeyPair = NULL; + } if (rv != SECSuccess) { return SECFailure; /* error code set */ } diff --git a/security/nss/lib/ssl/ssl3ecc.c b/security/nss/lib/ssl/ssl3ecc.c index e8ee5901..555c89dc 100644 --- a/security/nss/lib/ssl/ssl3ecc.c +++ b/security/nss/lib/ssl/ssl3ecc.c @@ -505,28 +505,21 @@ ssl3_ECRegister(void) return (PRStatus)rv; } -/* CallOnce function, called once for each named curve. */ -static PRStatus -ssl3_CreateECDHEphemeralKeyPair(void * arg) +/* Create an ECDHE key pair for a given curve */ +static SECStatus +ssl3_CreateECDHEphemeralKeyPair(ECName ec_curve, ssl3KeyPair** keyPair) { SECKEYPrivateKey * privKey = NULL; SECKEYPublicKey * pubKey = NULL; - ssl3KeyPair * keyPair = NULL; - ECName ec_curve = (ECName)arg; SECKEYECParams ecParams = { siBuffer, NULL, 0 }; - PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); - - /* ok, no one has generated a global key for this curve yet, do so */ if (ssl3_ECName2Params(NULL, ec_curve, &ecParams) != SECSuccess) { - gECDHEKeyPairs[ec_curve].error = PORT_GetError(); - return PR_FAILURE; + return SECFailure; } - privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); SECITEM_FreeItem(&ecParams, PR_FALSE); - if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) { + if (!privKey || !pubKey || !(*keyPair = ssl3_NewKeyPair(privKey, pubKey))) { if (privKey) { SECKEY_DestroyPrivateKey(privKey); } @@ -534,6 +527,23 @@ ssl3_CreateECDHEphemeralKeyPair(void * arg) SECKEY_DestroyPublicKey(pubKey); } ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); + return SECFailure; + } + + return SECSuccess; +} + +/* CallOnce function, called once for each named curve. */ +static PRStatus +ssl3_CreateECDHEphemeralKeyPairOnce(void * arg) +{ + ECName ec_curve = (ECName)arg; + ssl3KeyPair * keyPair = NULL; + + PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); + + /* ok, no one has generated a global key for this curve yet, do so */ + if (ssl3_CreateECDHEphemeralKeyPair(ec_curve, &keyPair) != SECSuccess) { gECDHEKeyPairs[ec_curve].error = PORT_GetError(); return PR_FAILURE; } @@ -566,7 +576,7 @@ ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve) return SECFailure; } status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once, - ssl3_CreateECDHEphemeralKeyPair, + ssl3_CreateECDHEphemeralKeyPairOnce, (void *)ec_curve); if (status != PR_SUCCESS) { PORT_SetError(gECDHEKeyPairs[ec_curve].error); @@ -759,10 +769,16 @@ ssl3_SendECDHServerKeyExchange( if (curve == ec_noName) { goto loser; } - rv = ssl3_CreateECDHEphemeralKeys(ss, curve); - if (rv != SECSuccess) { - goto loser; /* err set by AppendHandshake. */ + + if (ss->opt.reuseServerECDHEKey) { + rv = ssl3_CreateECDHEphemeralKeys(ss, curve); + } else { + rv = ssl3_CreateECDHEphemeralKeyPair(curve, &ss->ephemeralECDHKeyPair); } + if (rv != SECSuccess) { + goto loser; + } + ecdhePub = ss->ephemeralECDHKeyPair->pubKey; PORT_Assert(ecdhePub != NULL); if (!ecdhePub) { diff --git a/security/nss/lib/ssl/ssl3ext.c b/security/nss/lib/ssl/ssl3ext.c index 1d1f39cc..247f1f8f 100644 --- a/security/nss/lib/ssl/ssl3ext.c +++ b/security/nss/lib/ssl/ssl3ext.c @@ -82,6 +82,11 @@ static PRInt32 ssl3_ClientSendSigAlgsXtn(sslSocket *ss, PRBool append, static SECStatus ssl3_ServerHandleSigAlgsXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); +static PRInt32 ssl3_ClientSendDraftVersionXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); +static SECStatus ssl3_ServerHandleDraftVersionXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data); + /* * Write bytes. Using this function means the SECItem structure * cannot be freed. The caller is expected to call this function @@ -245,6 +250,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, + { ssl_tls13_draft_version_xtn, &ssl3_ServerHandleDraftVersionXtn }, { -1, NULL } }; @@ -286,7 +292,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { { ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn }, { ssl_use_srtp_xtn, &ssl3_SendUseSRTPXtn }, { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, - { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn } + { ssl_signature_algorithms_xtn, &ssl3_ClientSendSigAlgsXtn }, + { ssl_tls13_draft_version_xtn, &ssl3_ClientSendDraftVersionXtn }, /* any extra entries will appear as { 0, NULL } */ }; @@ -2421,3 +2428,93 @@ ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, return extensionLen; } + +/* ssl3_ClientSendDraftVersionXtn sends the TLS 1.3 temporary draft + * version extension. + * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */ +static PRInt32 +ssl3_ClientSendDraftVersionXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) +{ + PRInt32 extension_length; + + if (ss->version != SSL_LIBRARY_VERSION_TLS_1_3) { + return 0; + } + + extension_length = 6; /* Type + length + number */ + if (append && maxBytes >= extension_length) { + SECStatus rv; + rv = ssl3_AppendHandshakeNumber(ss, ssl_tls13_draft_version_xtn, 2); + if (rv != SECSuccess) + goto loser; + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + if (rv != SECSuccess) + goto loser; + rv = ssl3_AppendHandshakeNumber(ss, TLS_1_3_DRAFT_VERSION, 2); + if (rv != SECSuccess) + goto loser; + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + ssl_tls13_draft_version_xtn; + } else if (maxBytes < extension_length) { + PORT_Assert(0); + return 0; + } + + return extension_length; + +loser: + return -1; +} + +/* ssl3_ServerHandleDraftVersionXtn handles the TLS 1.3 temporary draft + * version extension. + * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */ +static SECStatus +ssl3_ServerHandleDraftVersionXtn(sslSocket * ss, PRUint16 ex_type, + SECItem *data) +{ + PRInt32 draft_version; + + /* Ignore this extension if we aren't doing TLS 1.3 */ + if (ss->version != SSL_LIBRARY_VERSION_TLS_1_3) { + return SECSuccess; + } + + if (data->len != 2) + goto loser; + + /* Get the draft version out of the handshake */ + draft_version = ssl3_ConsumeHandshakeNumber(ss, 2, + &data->data, &data->len); + if (draft_version < 0) { + goto loser; + } + + /* Keep track of negotiated extensions. */ + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + + /* Compare the version */ + if (draft_version != TLS_1_3_DRAFT_VERSION) { + SSL_TRC(30, ("%d: SSL3[%d]: Incompatible version of TLS 1.3 (%d), " + "expected %d", + SSL_GETPID(), ss->fd, draft_version, TLS_1_3_DRAFT_VERSION)); + goto loser; + } + + return SECSuccess; + +loser: + /* + * Incompatible/broken TLS 1.3 implementation. Fall back to TLS 1.2. + * TODO(ekr@rtfm.com): It's not entirely clear it's safe to roll back + * here. Need to double-check. + * TODO(ekr@rtfm.com): Currently we fall back even on broken extensions. + * because SECFailure does not cause handshake failures. See bug + * 753136. + */ + SSL_TRC(30, ("%d: SSL3[%d]: Rolling back to TLS 1.2", SSL_GETPID(), ss->fd)); + ss->version = SSL_LIBRARY_VERSION_TLS_1_2; + + return SECSuccess; +} + diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h index 4d4aa10b..485d7dd3 100644 --- a/security/nss/lib/ssl/ssl3prot.h +++ b/security/nss/lib/ssl/ssl3prot.h @@ -14,6 +14,11 @@ typedef PRUint8 SSL3Opaque; typedef PRUint16 SSL3ProtocolVersion; /* version numbers are defined in sslproto.h */ +/* The TLS 1.3 draft version. Used to avoid negotiating + * between incompatible pre-standard TLS 1.3 drafts. + * TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */ +#define TLS_1_3_DRAFT_VERSION 3 + typedef PRUint16 ssl3CipherSuite; /* The cipher suites are defined in sslproto.h */ @@ -98,6 +103,7 @@ typedef enum { protocol_version = 70, insufficient_security = 71, internal_error = 80, + inappropriate_fallback = 86, /* could also be sent for SSLv3 */ user_canceled = 90, no_renegotiation = 100, diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c index 891b4099..8c5a5ad3 100644 --- a/security/nss/lib/ssl/sslcon.c +++ b/security/nss/lib/ssl/sslcon.c @@ -428,7 +428,6 @@ ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, int cipherChoice) { switch (cipherChoice) { - case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: case SSL_CK_RC2_128_CBC_WITH_MD5: case SSL_CK_RC4_128_EXPORT40_WITH_MD5: @@ -436,8 +435,10 @@ ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, case SSL_CK_DES_64_CBC_WITH_MD5: case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: sec->hash = HASH_GetHashObject(HASH_AlgMD5); - SECITEM_CopyItem(0, &sec->sendSecret, writeKey); - SECITEM_CopyItem(0, &sec->rcvSecret, readKey); + if (SECITEM_CopyItem(0, &sec->sendSecret, writeKey) || + SECITEM_CopyItem(0, &sec->rcvSecret, readKey)) { + return SECFailure; + } break; default: diff --git a/security/nss/lib/ssl/sslerr.h b/security/nss/lib/ssl/sslerr.h index 38520859..12dbb1d8 100644 --- a/security/nss/lib/ssl/sslerr.h +++ b/security/nss/lib/ssl/sslerr.h @@ -196,6 +196,8 @@ SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128), SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK = (SSL_ERROR_BASE + 129), SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130), +SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131), + SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ } SSLErrorCodes; #endif /* NO_SECURITY_ERROR_ENUM */ diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index af3c1918..858ae0cc 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -326,6 +326,8 @@ typedef struct sslOptionsStr { unsigned int enableOCSPStapling : 1; /* 25 */ unsigned int enableNPN : 1; /* 26 */ unsigned int enableALPN : 1; /* 27 */ + unsigned int reuseServerECDHEKey : 1; /* 28 */ + unsigned int enableFallbackSCSV : 1; /* 29 */ } sslOptions; typedef enum { sslHandshakingUndetermined = 0, @@ -1534,7 +1536,11 @@ extern PRInt32 ssl3_SendRecord(sslSocket *ss, DTLSEpoch epoch, * runtime to determine which versions are supported by the version of libssl * in use. */ +#ifdef NSS_ENABLE_TLS_1_3 +#define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_3 +#else #define SSL_LIBRARY_VERSION_MAX_SUPPORTED SSL_LIBRARY_VERSION_TLS_1_2 +#endif /* Rename this macro SSL_ALL_VERSIONS_DISABLED when SSL 2.0 is removed. */ #define SSL3_ALL_VERSIONS_DISABLED(vrange) \ diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h index 7a283c73..e02442c0 100644 --- a/security/nss/lib/ssl/sslproto.h +++ b/security/nss/lib/ssl/sslproto.h @@ -16,9 +16,12 @@ #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301 #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302 #define SSL_LIBRARY_VERSION_TLS_1_2 0x0303 +#define SSL_LIBRARY_VERSION_TLS_1_3 0x0304 + /* Note: this is the internal format, not the wire format */ #define SSL_LIBRARY_VERSION_DTLS_1_0 0x0302 #define SSL_LIBRARY_VERSION_DTLS_1_2 0x0303 +#define SSL_LIBRARY_VERSION_DTLS_1_3 0x0304 /* deprecated old name */ #define SSL_LIBRARY_VERSION_3_1_TLS SSL_LIBRARY_VERSION_TLS_1_0 @@ -26,6 +29,7 @@ /* The DTLS versions used in the spec */ #define SSL_LIBRARY_VERSION_DTLS_1_0_WIRE ((~0x0100) & 0xffff) #define SSL_LIBRARY_VERSION_DTLS_1_2_WIRE ((~0x0102) & 0xffff) +#define SSL_LIBRARY_VERSION_DTLS_1_3_WIRE ((~0x0103) & 0xffff) /* Header lengths of some of the messages */ #define SSL_HL_ERROR_HBYTES 3 @@ -208,6 +212,11 @@ */ #define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF +/* TLS_FALLBACK_SCSV is a signaling cipher suite value that indicates that a + * handshake is the result of TLS version fallback. + */ +#define TLS_FALLBACK_SCSV 0x5600 + /* Cipher Suite Values starting with 0xC000 are defined in informational * RFCs. */ diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c index a32e3d54..ea2d4080 100644 --- a/security/nss/lib/ssl/sslsecur.c +++ b/security/nss/lib/ssl/sslsecur.c @@ -968,11 +968,9 @@ ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) ss->sec.hashcx = NULL; } - SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret); - if (os->sec.sendSecret.data && !ss->sec.sendSecret.data) + if (SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret)) goto loser; - SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret); - if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data) + if (SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret)) goto loser; /* XXX following code is wrong if either cx != 0 */ diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index ee357b63..dfa7a2c7 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -80,7 +80,9 @@ static sslOptions ssl_defaults = { PR_TRUE, /* cbcRandomIV */ PR_FALSE, /* enableOCSPStapling */ PR_TRUE, /* enableNPN */ - PR_FALSE /* enableALPN */ + PR_FALSE, /* enableALPN */ + PR_TRUE, /* reuseServerECDHEKey */ + PR_FALSE /* enableFallbackSCSV */ }; /* @@ -784,6 +786,14 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) ss->opt.enableALPN = on; break; + case SSL_REUSE_SERVER_ECDHE_KEY: + ss->opt.reuseServerECDHEKey = on; + break; + + case SSL_ENABLE_FALLBACK_SCSV: + ss->opt.enableFallbackSCSV = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; @@ -856,6 +866,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; case SSL_ENABLE_NPN: on = ss->opt.enableNPN; break; case SSL_ENABLE_ALPN: on = ss->opt.enableALPN; break; + case SSL_REUSE_SERVER_ECDHE_KEY: + on = ss->opt.reuseServerECDHEKey; break; + case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -919,6 +932,12 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) break; case SSL_ENABLE_NPN: on = ssl_defaults.enableNPN; break; case SSL_ENABLE_ALPN: on = ssl_defaults.enableALPN; break; + case SSL_REUSE_SERVER_ECDHE_KEY: + on = ssl_defaults.reuseServerECDHEKey; + break; + case SSL_ENABLE_FALLBACK_SCSV: + on = ssl_defaults.enableFallbackSCSV; + break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -1094,6 +1113,14 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) ssl_defaults.enableALPN = on; break; + case SSL_REUSE_SERVER_ECDHE_KEY: + ssl_defaults.reuseServerECDHEKey = on; + break; + + case SSL_ENABLE_FALLBACK_SCSV: + ssl_defaults.enableFallbackSCSV = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; diff --git a/security/nss/lib/ssl/sslt.h b/security/nss/lib/ssl/sslt.h index c22c820c..1d28feb1 100644 --- a/security/nss/lib/ssl/sslt.h +++ b/security/nss/lib/ssl/sslt.h @@ -191,9 +191,10 @@ typedef enum { ssl_padding_xtn = 21, ssl_session_ticket_xtn = 35, ssl_next_proto_nego_xtn = 13172, - ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ + ssl_renegotiation_info_xtn = 0xff01, + ssl_tls13_draft_version_xtn = 0xff02 /* experimental number */ } SSLExtensionType; -#define SSL_MAX_EXTENSIONS 10 /* doesn't include ssl_padding_xtn. */ +#define SSL_MAX_EXTENSIONS 11 /* doesn't include ssl_padding_xtn. */ #endif /* __sslt_h_ */ diff --git a/security/nss/lib/util/manifest.mn b/security/nss/lib/util/manifest.mn index ed54a162..9ff3758f 100644 --- a/security/nss/lib/util/manifest.mn +++ b/security/nss/lib/util/manifest.mn @@ -22,6 +22,7 @@ EXPORTS = \ pkcs11t.h \ pkcs11n.h \ pkcs11u.h \ + pkcs1sig.h \ portreg.h \ secasn1.h \ secasn1t.h \ @@ -58,6 +59,7 @@ CSRCS = \ nssrwlk.c \ nssilock.c \ oidstring.c \ + pkcs1sig.c \ portreg.c \ secalgid.c \ secasn1d.c \ diff --git a/security/nss/lib/util/nssutil.def b/security/nss/lib/util/nssutil.def index 86a0ad7e..9d98df22 100644 --- a/security/nss/lib/util/nssutil.def +++ b/security/nss/lib/util/nssutil.def @@ -271,3 +271,9 @@ SECITEM_ZfreeArray; ;+ local: ;+ *; ;+}; +;+NSSUTIL_3.17.1 { # NSS Utilities 3.17.1 release +;+ global: +_SGN_VerifyPKCS1DigestInfo; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index ac771b6c..34efdea0 100644 --- a/security/nss/lib/util/nssutil.h +++ b/security/nss/lib/util/nssutil.h @@ -19,9 +19,9 @@ * The format of the version string should be * ".[.[.]][ ]" */ -#define NSSUTIL_VERSION "3.16.2.1" +#define NSSUTIL_VERSION "3.17.2.1" #define NSSUTIL_VMAJOR 3 -#define NSSUTIL_VMINOR 16 +#define NSSUTIL_VMINOR 17 #define NSSUTIL_VPATCH 2 #define NSSUTIL_VBUILD 1 #define NSSUTIL_BETA PR_FALSE diff --git a/security/nss/lib/util/pkcs1sig.c b/security/nss/lib/util/pkcs1sig.c new file mode 100644 index 00000000..03b16f50 --- /dev/null +++ b/security/nss/lib/util/pkcs1sig.c @@ -0,0 +1,169 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "pkcs1sig.h" +#include "hasht.h" +#include "secerr.h" +#include "secasn1t.h" +#include "secoid.h" + +typedef struct pkcs1PrefixStr pkcs1Prefix; +struct pkcs1PrefixStr { + unsigned int len; + PRUint8 *data; +}; + +typedef struct pkcs1PrefixesStr pkcs1Prefixes; +struct pkcs1PrefixesStr { + unsigned int digestLen; + pkcs1Prefix prefixWithParams; + pkcs1Prefix prefixWithoutParams; +}; + +/* The value for SGN_PKCS1_DIGESTINFO_MAX_PREFIX_LEN_EXCLUDING_OID is based on + * the possible prefix encodings as explained below. + */ +#define MAX_PREFIX_LEN_EXCLUDING_OID 10 + +static SECStatus +encodePrefix(const SECOidData *hashOid, unsigned int digestLen, + pkcs1Prefix *prefix, PRBool withParams) +{ + /* with params coding is: + * Sequence (2 bytes) { + * Sequence (2 bytes) { + * Oid (2 bytes) { + * Oid value (derOid->oid.len) + * } + * NULL (2 bytes) + * } + * OCTECT (2 bytes); + * + * without params coding is: + * Sequence (2 bytes) { + * Sequence (2 bytes) { + * Oid (2 bytes) { + * Oid value (derOid->oid.len) + * } + * } + * OCTECT (2 bytes); + */ + + unsigned int innerSeqLen = 2 + hashOid->oid.len; + unsigned int outerSeqLen = 2 + innerSeqLen + 2 + digestLen; + unsigned int extra = 0; + + if (withParams) { + innerSeqLen += 2; + outerSeqLen += 2; + extra = 2; + } + + if (innerSeqLen >= 128 || + outerSeqLen >= 128 || + (outerSeqLen + 2 - digestLen) > + (MAX_PREFIX_LEN_EXCLUDING_OID + hashOid->oid.len)) { + /* this is actually a library failure, It shouldn't happen */ + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + prefix->len = 6 + hashOid->oid.len + extra + 2; + prefix->data = PORT_Alloc(prefix->len); + if (!prefix->data) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return SECFailure; + } + + prefix->data[0] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED; + prefix->data[1] = outerSeqLen; + prefix->data[2] = SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED; + prefix->data[3] = innerSeqLen; + prefix->data[4] = SEC_ASN1_OBJECT_ID; + prefix->data[5] = hashOid->oid.len; + PORT_Memcpy(&prefix->data[6], hashOid->oid.data, hashOid->oid.len); + if (withParams) { + prefix->data[6 + hashOid->oid.len] = SEC_ASN1_NULL; + prefix->data[6 + hashOid->oid.len + 1] = 0; + } + prefix->data[6 + hashOid->oid.len + extra] = SEC_ASN1_OCTET_STRING; + prefix->data[6 + hashOid->oid.len + extra + 1] = digestLen; + + return SECSuccess; +} + +SECStatus +_SGN_VerifyPKCS1DigestInfo(SECOidTag digestAlg, + const SECItem* digest, + const SECItem* dataRecoveredFromSignature, + PRBool unsafeAllowMissingParameters) +{ + SECOidData *hashOid; + pkcs1Prefixes pp; + const pkcs1Prefix* expectedPrefix; + SECStatus rv, rv2, rv3; + + if (!digest || !digest->data || + !dataRecoveredFromSignature || !dataRecoveredFromSignature->data) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + hashOid = SECOID_FindOIDByTag(digestAlg); + if (hashOid == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + pp.digestLen = digest->len; + pp.prefixWithParams.data = NULL; + pp.prefixWithoutParams.data = NULL; + + rv2 = encodePrefix(hashOid, pp.digestLen, &pp.prefixWithParams, PR_TRUE); + rv3 = encodePrefix(hashOid, pp.digestLen, &pp.prefixWithoutParams, PR_FALSE); + + rv = SECSuccess; + if (rv2 != SECSuccess || rv3 != SECSuccess) { + rv = SECFailure; + } + + if (rv == SECSuccess) { + /* We don't attempt to avoid timing attacks on these comparisons because + * signature verification is a public key operation, not a private key + * operation. + */ + + if (dataRecoveredFromSignature->len == + pp.prefixWithParams.len + pp.digestLen) { + expectedPrefix = &pp.prefixWithParams; + } else if (unsafeAllowMissingParameters && + dataRecoveredFromSignature->len == + pp.prefixWithoutParams.len + pp.digestLen) { + expectedPrefix = &pp.prefixWithoutParams; + } else { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + rv = SECFailure; + } + } + + if (rv == SECSuccess) { + if (memcmp(dataRecoveredFromSignature->data, expectedPrefix->data, + expectedPrefix->len) || + memcmp(dataRecoveredFromSignature->data + expectedPrefix->len, + digest->data, digest->len)) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + rv = SECFailure; + } + } + + if (pp.prefixWithParams.data) { + PORT_Free(pp.prefixWithParams.data); + } + if (pp.prefixWithoutParams.data) { + PORT_Free(pp.prefixWithoutParams.data); + } + + return rv; +} diff --git a/security/nss/lib/util/pkcs1sig.h b/security/nss/lib/util/pkcs1sig.h new file mode 100644 index 00000000..7c52b157 --- /dev/null +++ b/security/nss/lib/util/pkcs1sig.h @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef _PKCS1SIG_H_ +#define _PKCS1SIG_H_ + +#include "hasht.h" +#include "seccomon.h" +#include "secoidt.h" + +/* SGN_VerifyPKCS1DigestInfo verifies that the length of the digest is correct + * for the given algorithm, then verifies that the recovered data from the + * PKCS#1 signature is a properly-formatted DigestInfo that identifies the + * given digest algorithm, then verifies that the digest in the DigestInfo + * matches the given digest. + * + * dataRecoveredFromSignature must be the result of calling PK11_VerifyRecover + * or equivalent. + * + * If unsafeAllowMissingParameters is true (not recommended), then a DigestInfo + * without the mandatory ASN.1 NULL parameter will also be accepted. + */ +SECStatus _SGN_VerifyPKCS1DigestInfo(SECOidTag digestAlg, + const SECItem* digest, + const SECItem* dataRecoveredFromSignature, + PRBool unsafeAllowMissingParameters); + +#endif /* _PKCS1SIG_H_ */ diff --git a/security/nss/lib/util/quickder.c b/security/nss/lib/util/quickder.c index 6f518ddf..f9776bb9 100644 --- a/security/nss/lib/util/quickder.c +++ b/security/nss/lib/util/quickder.c @@ -16,55 +16,110 @@ */ static unsigned char* definite_length_decoder(const unsigned char *buf, - const unsigned int length, - unsigned int *data_length, + const unsigned int buf_length, + unsigned int *out_data_length, PRBool includeTag) { unsigned char tag; - unsigned int used_length= 0; - unsigned int data_len; + unsigned int used_length = 0; + unsigned int data_length = 0; + unsigned char length_field_len = 0; + unsigned char byte; + unsigned int i; - if (used_length >= length) + if (used_length >= buf_length) { + /* Tag field was not found! */ return NULL; } tag = buf[used_length++]; - /* blow out when we come to the end */ if (tag == 0) { + /* End-of-contents octects should not be present in DER because + DER doesn't use the indefinite length form. */ return NULL; } - if (used_length >= length) + if ((tag & 0x1F) == 0x1F) { + /* High tag number (a tag number > 30) is not supported */ return NULL; } - data_len = buf[used_length++]; - if (data_len&0x80) + if (used_length >= buf_length) { - int len_count = data_len & 0x7f; + /* Length field was not found! */ + return NULL; + } + byte = buf[used_length++]; - data_len = 0; - - while (len_count-- > 0) + if (!(byte & 0x80)) + { + /* Short form: The high bit is not set. */ + data_length = byte; /* clarity; we're returning a 32-bit int. */ + } + else + { + /* Long form. Extract the field length */ + length_field_len = byte & 0x7F; + if (length_field_len == 0) { - if (used_length >= length) + /* DER doesn't use the indefinite length form. */ + return NULL; + } + + if (length_field_len > sizeof(data_length)) + { + /* We don't support an extended length field longer than + 4 bytes (2^32) */ + return NULL; + } + + if (length_field_len > (buf_length - used_length)) + { + /* Extended length field was not found */ + return NULL; + } + + /* Iterate across the extended length field */ + for (i = 0; i < length_field_len; i++) + { + byte = buf[used_length++]; + data_length = (data_length << 8) | byte; + + if (i == 0) { - return NULL; + PRBool too_long = PR_FALSE; + if (length_field_len == 1) + { + too_long = ((byte & 0x80) == 0); /* Short form suffices */ + } + else + { + too_long = (byte == 0); /* This zero byte can be omitted */ + } + if (too_long) + { + /* The length is longer than needed. */ + return NULL; + } } - data_len = (data_len << 8) | buf[used_length++]; } } - if (data_len > (length-used_length) ) + if (data_length > (buf_length - used_length)) { + /* The decoded length exceeds the available buffer */ return NULL; } - if (includeTag) data_len += used_length; - *data_length = data_len; + if (includeTag) + { + data_length += used_length; + } + + *out_data_length = data_length; return ((unsigned char*)buf + (includeTag ? 0 : used_length)); } diff --git a/security/nss/tests/chains/scenarios/nameconstraints.cfg b/security/nss/tests/chains/scenarios/nameconstraints.cfg index d49e20e3..6eda441c 100644 --- a/security/nss/tests/chains/scenarios/nameconstraints.cfg +++ b/security/nss/tests/chains/scenarios/nameconstraints.cfg @@ -7,8 +7,8 @@ scenario TrustAnchors db trustanchors import NameConstraints.ca:x:CT,C,C -import NameConstraints.ncca:x:CT,C,C # Name Constrained CA: Name constrained to permited DNSName ".example" +import NameConstraints.ncca:x:CT,C,C import NameConstraints.dcisscopy:x:CT,C,C # Intermediate 1: Name constrained to permited DNSName ".example" diff --git a/security/nss/tests/libpkix/certs/make-nc b/security/nss/tests/libpkix/certs/make-nc index b32dd65e..aaab1edf 100644 --- a/security/nss/tests/libpkix/certs/make-nc +++ b/security/nss/tests/libpkix/certs/make-nc @@ -456,7 +456,7 @@ y n CERTSCRIPT -#the following cert MUST not pass +#the following cert MUST pass certutil -S -z noise -g 2048 -d . -n dcissallowed -s "CN=foo.example.fr,O=Foo,ST=CA,C=US" -t ,, -c dcisscopy -m 998901 -v 120 -1 -2 -5 < @@ -174,7 +174,7 @@ PRIntn main(PRIntn ac, char **av, char **ev) { "\nSSL Test Suite Version %d.%d.%d\n\ All Rights Reserved\n\ Usage: sslt [-c client_nickname] [-n server_nickname] [-p passwd] [-d] testid\n", -VERION_MAJOR, VERION_MINOR, VERSION_POINT); +VERSION_MAJOR, VERSION_MINOR, VERSION_POINT); exit(0); }