diff options
Diffstat (limited to 'nss/lib')
153 files changed, 6665 insertions, 5296 deletions
diff --git a/nss/lib/base/error.c b/nss/lib/base/error.c index ea1d5e3..95a76cf 100644 --- a/nss/lib/base/error.c +++ b/nss/lib/base/error.c @@ -55,6 +55,7 @@ static PRUintn error_stack_index = INVALID_TPD_INDEX; */ static PRCallOnceType error_call_once; +static const PRCallOnceType error_call_again; /* * error_once_function @@ -264,6 +265,8 @@ nss_DestroyErrorStack(void) { if (INVALID_TPD_INDEX != error_stack_index) { PR_SetThreadPrivate(error_stack_index, NULL); + error_stack_index = INVALID_TPD_INDEX; + error_call_once = error_call_again; /* allow to init again */ } return; } diff --git a/nss/lib/certdb/alg1485.c b/nss/lib/certdb/alg1485.c index b6736c4..38b2fe4 100644 --- a/nss/lib/certdb/alg1485.c +++ b/nss/lib/certdb/alg1485.c @@ -341,13 +341,16 @@ hexToBin(PLArenaPool* pool, SECItem* destItem, const char* src, int len) goto loser; } len >>= 1; - if (!SECITEM_AllocItem(pool, destItem, len)) + if (!SECITEM_AllocItem(pool, destItem, len)) { goto loser; + } dest = destItem->data; for (; len > 0; len--, src += 2) { - PRInt16 bin = (x2b[(PRUint8)src[0]] << 4) | x2b[(PRUint8)src[1]]; - if (bin < 0) + PRUint16 bin = ((PRUint16)x2b[(PRUint8)src[0]] << 4); + bin |= (PRUint16)x2b[(PRUint8)src[1]]; + if (bin >> 15) { /* is negative */ goto loser; + } *dest++ = (PRUint8)bin; } return SECSuccess; @@ -372,6 +375,7 @@ ParseRFC1485AVA(PLArenaPool* arena, const char** pbp, const char* endptr) const char* bp; int vt = -1; int valLen; + PRBool isDottedOid = PR_FALSE; SECOidTag kind = SEC_OID_UNKNOWN; SECStatus rv = SECFailure; SECItem derOid = { 0, NULL, 0 }; @@ -398,8 +402,9 @@ ParseRFC1485AVA(PLArenaPool* arena, const char** pbp, const char* endptr) } /* is this a dotted decimal OID attribute type ? */ - if (!PL_strncasecmp("oid.", tagBuf, 4)) { + if (!PL_strncasecmp("oid.", tagBuf, 4) || isdigit(tagBuf[0])) { rv = SEC_StringToOID(arena, &derOid, tagBuf, strlen(tagBuf)); + isDottedOid = (PRBool)(rv == SECSuccess); } else { for (n2k = name2kinds; n2k->name; n2k++) { SECOidData* oidrec; @@ -425,8 +430,6 @@ ParseRFC1485AVA(PLArenaPool* arena, const char** pbp, const char* endptr) goto loser; a = CERT_CreateAVAFromRaw(arena, &derOid, &derVal); } else { - if (kind == SEC_OID_UNKNOWN) - goto loser; if (kind == SEC_OID_AVA_COUNTRY_NAME && valLen != 2) goto loser; if (vt == SEC_ASN1_PRINTABLE_STRING && @@ -442,7 +445,11 @@ ParseRFC1485AVA(PLArenaPool* arena, const char** pbp, const char* endptr) derVal.data = (unsigned char*)valBuf; derVal.len = valLen; - a = CERT_CreateAVAFromSECItem(arena, kind, vt, &derVal); + if (kind == SEC_OID_UNKNOWN && isDottedOid) { + a = CERT_CreateAVAFromRaw(arena, &derOid, &derVal); + } else { + a = CERT_CreateAVAFromSECItem(arena, kind, vt, &derVal); + } } return a; diff --git a/nss/lib/certdb/cert.h b/nss/lib/certdb/cert.h index e0af65a..4224da1 100644 --- a/nss/lib/certdb/cert.h +++ b/nss/lib/certdb/cert.h @@ -1405,24 +1405,11 @@ void CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config); void CERT_LockCertRefCount(CERTCertificate *cert); /* - * Free the cert reference count lock + * Release the cert reference count lock */ void CERT_UnlockCertRefCount(CERTCertificate *cert); /* - * Acquire the cert trust lock - * There is currently one global lock for all certs, but I'm putting a cert - * arg here so that it will be easy to make it per-cert in the future if - * that turns out to be necessary. - */ -void CERT_LockCertTrust(const CERTCertificate *cert); - -/* - * Free the cert trust lock - */ -void CERT_UnlockCertTrust(const CERTCertificate *cert); - -/* * Digest the cert's subject public key using the specified algorithm. * NOTE: this digests the value of the BIT STRING subjectPublicKey (excluding * the tag, length, and number of unused bits) rather than the whole @@ -1579,6 +1566,12 @@ extern CERTRevocationFlags *CERT_AllocCERTRevocationFlags( */ extern void CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags); +/* + * Get istemp and isperm fields from a cert in a thread safe way. + */ +extern SECStatus CERT_GetCertIsTemp(const CERTCertificate *cert, PRBool *istemp); +extern SECStatus CERT_GetCertIsPerm(const CERTCertificate *cert, PRBool *isperm); + SEC_END_PROTOS #endif /* _CERT_H_ */ diff --git a/nss/lib/certdb/certdb.c b/nss/lib/certdb/certdb.c index d37334d..7864edc 100644 --- a/nss/lib/certdb/certdb.c +++ b/nss/lib/certdb/certdb.c @@ -2559,9 +2559,9 @@ CERT_AddCertToListHeadWithData(CERTCertList *certs, CERTCertificate *cert, CERTCertListNode *head; head = CERT_LIST_HEAD(certs); - - if (head == NULL) - return CERT_AddCertToListTail(certs, cert); + if (head == NULL) { + goto loser; + } node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, sizeof(CERTCertListNode)); @@ -2865,7 +2865,18 @@ CERT_LockCertTrust(const CERTCertificate *cert) { PORT_Assert(certTrustLock != NULL); PZ_Lock(certTrustLock); - return; +} + +static PZLock *certTempPermLock = NULL; + +/* + * Acquire the cert temp/perm lock + */ +void +CERT_LockCertTempPerm(const CERTCertificate *cert) +{ + PORT_Assert(certTempPermLock != NULL); + PZ_Lock(certTempPermLock); } SECStatus @@ -2889,6 +2900,18 @@ cert_InitLocks(void) } } + if (certTempPermLock == NULL) { + certTempPermLock = PZ_NewLock(nssILockCertDB); + PORT_Assert(certTempPermLock != NULL); + if (!certTempPermLock) { + PZ_DestroyLock(certTrustLock); + PZ_DestroyLock(certRefCountLock); + certRefCountLock = NULL; + certTrustLock = NULL; + return SECFailure; + } + } + return SECSuccess; } @@ -2912,6 +2935,14 @@ cert_DestroyLocks(void) } else { rv = SECFailure; } + + PORT_Assert(certTempPermLock != NULL); + if (certTempPermLock) { + PZ_DestroyLock(certTempPermLock); + certTempPermLock = NULL; + } else { + rv = SECFailure; + } return rv; } @@ -2934,6 +2965,23 @@ CERT_UnlockCertTrust(const CERTCertificate *cert) } /* + * Free the temp/perm lock + */ +void +CERT_UnlockCertTempPerm(const CERTCertificate *cert) +{ + PORT_Assert(certTempPermLock != NULL); +#ifdef DEBUG + { + PRStatus prstat = PZ_Unlock(certTempPermLock); + PORT_Assert(prstat == PR_SUCCESS); + } +#else + (void)PZ_Unlock(certTempPermLock); +#endif +} + +/* * Get the StatusConfig data for this handle */ CERTStatusConfig * diff --git a/nss/lib/certdb/certi.h b/nss/lib/certdb/certi.h index 1cdf4b8..456f2fc 100644 --- a/nss/lib/certdb/certi.h +++ b/nss/lib/certdb/certi.h @@ -378,4 +378,27 @@ PRUint32 cert_CountDNSPatterns(CERTGeneralName* firstName); SECStatus cert_CheckLeafTrust(CERTCertificate* cert, SECCertUsage usage, unsigned int* failedFlags, PRBool* isTrusted); +/* + * Acquire the cert temp/perm lock + */ +void CERT_LockCertTempPerm(const CERTCertificate* cert); + +/* + * Release the temp/perm lock + */ +void CERT_UnlockCertTempPerm(const CERTCertificate* cert); + +/* + * Acquire the cert trust lock + * There is currently one global lock for all certs, but I'm putting a cert + * arg here so that it will be easy to make it per-cert in the future if + * that turns out to be necessary. + */ +void CERT_LockCertTrust(const CERTCertificate* cert); + +/* + * Release the cert trust lock + */ +void CERT_UnlockCertTrust(const CERTCertificate* cert); + #endif /* _CERTI_H_ */ diff --git a/nss/lib/certdb/genname.c b/nss/lib/certdb/genname.c index b8f6654..644913c 100644 --- a/nss/lib/certdb/genname.c +++ b/nss/lib/certdb/genname.c @@ -1588,10 +1588,10 @@ done: STRING_TO_SECITEM(CA##_NAME_CONSTRAINTS) \ } -/* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ - /* clang-format off */ +/* Agence Nationale de la Securite des Systemes d'Information (ANSSI) */ + #define ANSSI_SUBJECT_DN \ "\x30\x81\x85" \ "\x31\x0B\x30\x09\x06\x03\x55\x04\x06\x13\x02" "FR" /* C */ \ @@ -1619,10 +1619,39 @@ done: "\x30\x05\x82\x03" ".nc" \ "\x30\x05\x82\x03" ".tf" +/* TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 */ + +#define TUBITAK1_SUBJECT_DN \ + "\x30\x81\xd2" \ + "\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02" \ + /* C */ "TR" \ + "\x31\x18\x30\x16\x06\x03\x55\x04\x07\x13\x0f" \ + /* L */ "Gebze - Kocaeli" \ + "\x31\x42\x30\x40\x06\x03\x55\x04\x0a\x13\x39" \ + /* O */ "Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK" \ + "\x31\x2d\x30\x2b\x06\x03\x55\x04\x0b\x13\x24" \ + /* OU */ "Kamu Sertifikasyon Merkezi - Kamu SM" \ + "\x31\x36\x30\x34\x06\x03\x55\x04\x03\x13\x2d" \ + /* CN */ "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" + +#define TUBITAK1_NAME_CONSTRAINTS \ + "\x30\x65\xa0\x63" \ + "\x30\x09\x82\x07" ".gov.tr" \ + "\x30\x09\x82\x07" ".k12.tr" \ + "\x30\x09\x82\x07" ".pol.tr" \ + "\x30\x09\x82\x07" ".mil.tr" \ + "\x30\x09\x82\x07" ".tsk.tr" \ + "\x30\x09\x82\x07" ".kep.tr" \ + "\x30\x09\x82\x07" ".bel.tr" \ + "\x30\x09\x82\x07" ".edu.tr" \ + "\x30\x09\x82\x07" ".org.tr" + /* clang-format on */ -static const SECItem builtInNameConstraints[][2] = { NAME_CONSTRAINTS_ENTRY( - ANSSI) }; +static const SECItem builtInNameConstraints[][2] = { + NAME_CONSTRAINTS_ENTRY(ANSSI), + NAME_CONSTRAINTS_ENTRY(TUBITAK1) +}; SECStatus CERT_GetImposedNameConstraints(const SECItem *derSubject, SECItem *extensions) diff --git a/nss/lib/certdb/stanpcertdb.c b/nss/lib/certdb/stanpcertdb.c index 2b1aa97..4d42bd5 100644 --- a/nss/lib/certdb/stanpcertdb.c +++ b/nss/lib/certdb/stanpcertdb.c @@ -91,7 +91,7 @@ CERT_GetCertTrust(const CERTCertificate *cert, CERTCertTrust *trust) { SECStatus rv; CERT_LockCertTrust(cert); - if (cert->trust == NULL) { + if (!cert || cert->trust == NULL) { rv = SECFailure; } else { *trust = *cert->trust; @@ -304,8 +304,10 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, CERT_MapStanError(); return SECFailure; } + CERT_LockCertTempPerm(cert); cert->istemp = PR_FALSE; cert->isperm = PR_TRUE; + CERT_UnlockCertTempPerm(cert); if (!trust) { return SECSuccess; } @@ -436,8 +438,10 @@ CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, return NULL; } + CERT_LockCertTempPerm(cc); cc->istemp = PR_TRUE; cc->isperm = PR_FALSE; + CERT_UnlockCertTempPerm(cc); return cc; loser: /* Perhaps this should be nssCertificate_Destroy(c) */ @@ -515,28 +519,25 @@ CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID) { CERTCertList *list; CERTCertificate *cert = NULL; - CERTCertListNode *node, *head; + CERTCertListNode *node; list = CERT_CreateSubjectCertList(NULL, handle, name, 0, PR_FALSE); if (list == NULL) return NULL; - node = head = CERT_LIST_HEAD(list); - if (head) { - do { - if (node->cert && - SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID)) { - cert = CERT_DupCertificate(node->cert); - goto done; - } - node = CERT_LIST_NEXT(node); - } while (node && head != node); + node = CERT_LIST_HEAD(list); + while (!CERT_LIST_END(node, list)) { + if (node->cert && + SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID)) { + cert = CERT_DupCertificate(node->cert); + goto done; + } + node = CERT_LIST_NEXT(node); } PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); + done: - if (list) { - CERT_DestroyCertList(list); - } + CERT_DestroyCertList(list); return cert; } @@ -635,8 +636,7 @@ common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, if (certlist) { SECStatus rv = CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE); - if (SECSuccess == rv && - !CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) { + if (SECSuccess == rv && !CERT_LIST_EMPTY(certlist)) { cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert); } CERT_DestroyCertList(certlist); @@ -915,6 +915,7 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, { const char *emailAddr; SECStatus rv; + PRBool isperm = PR_FALSE; if (!cert) { return SECFailure; @@ -936,7 +937,11 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, } } - if (cert->slot && cert->isperm && CERT_IsUserCert(cert) && + rv = CERT_GetCertIsPerm(cert, &isperm); + if (rv != SECSuccess) { + return SECFailure; + } + if (cert->slot && isperm && CERT_IsUserCert(cert) && (!emailProfile || !emailProfile->len)) { /* Don't clobber emailProfile for user certs. */ return SECSuccess; @@ -990,6 +995,32 @@ CERT_FindSMimeProfile(CERTCertificate *cert) return rvItem; } +SECStatus +CERT_GetCertIsPerm(const CERTCertificate *cert, PRBool *isperm) +{ + if (cert == NULL) { + return SECFailure; + } + + CERT_LockCertTempPerm(cert); + *isperm = cert->isperm; + CERT_UnlockCertTempPerm(cert); + return SECSuccess; +} + +SECStatus +CERT_GetCertIsTemp(const CERTCertificate *cert, PRBool *istemp) +{ + if (cert == NULL) { + return SECFailure; + } + + CERT_LockCertTempPerm(cert); + *istemp = cert->istemp; + CERT_UnlockCertTempPerm(cert); + return SECSuccess; +} + /* * deprecated functions that are now just stubs. */ diff --git a/nss/lib/certhigh/certhigh.c b/nss/lib/certhigh/certhigh.c index 5525989..7ae80b1 100644 --- a/nss/lib/certhigh/certhigh.c +++ b/nss/lib/certhigh/certhigh.c @@ -11,6 +11,7 @@ #include "cert.h" #include "certxutl.h" +#include "certi.h" #include "nsspki.h" #include "pki.h" #include "pkit.h" @@ -289,7 +290,7 @@ CERT_FindUserCertByUsage(CERTCertDBHandle *handle, goto loser; } - if (!CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) { + if (!CERT_LIST_EMPTY(certList)) { cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert); } @@ -872,6 +873,7 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool PRBool isca; char *nickname; unsigned int certtype; + PRBool istemp = PR_FALSE; handle = CERT_GetDefaultCertDB(); @@ -949,7 +951,11 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool } /* if the cert is temp, make it perm; otherwise we're done */ - if (cert->istemp) { + rv = CERT_GetCertIsTemp(cert, &istemp); + if (rv != SECSuccess) { + goto loser; + } + if (istemp) { /* get a default nickname for it */ nickname = CERT_MakeCANickname(cert); @@ -963,9 +969,6 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool rv = SECSuccess; } - CERT_DestroyCertificate(cert); - cert = NULL; - if (rv != SECSuccess) { goto loser; } @@ -1080,7 +1083,10 @@ CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, derCert.len = (unsigned int)stanCert->encoding.size; derCert.data = (unsigned char *)stanCert->encoding.data; derCert.type = siBuffer; - SECITEM_CopyItem(arena, &chain->certs[i], &derCert); + if (SECITEM_CopyItem(arena, &chain->certs[i], &derCert) != SECSuccess) { + CERT_DestroyCertificate(cCert); + goto loser; + } stanCert = stanChain[++i]; if (!stanCert && !cCert->isRoot) { /* reached the end of the chain, but the final cert is diff --git a/nss/lib/certhigh/certhtml.c b/nss/lib/certhigh/certhtml.c index a522f69..2d708cc 100644 --- a/nss/lib/certhigh/certhtml.c +++ b/nss/lib/certhigh/certhtml.c @@ -102,6 +102,8 @@ CERT_FormatName(CERTName *name) goto loser; } len += cn->len; + // cn will always have BREAK after it + len += BREAKLEN; break; case SEC_OID_AVA_COUNTRY_NAME: if (country) { @@ -112,6 +114,10 @@ CERT_FormatName(CERTName *name) goto loser; } len += country->len; + // country may have COMMA after it (if we over-count len, + // that's fine - we'll just allocate a buffer larger than we + // need) + len += COMMALEN; break; case SEC_OID_AVA_LOCALITY: if (loc) { @@ -122,6 +128,8 @@ CERT_FormatName(CERTName *name) goto loser; } len += loc->len; + // loc may have COMMA after it + len += COMMALEN; break; case SEC_OID_AVA_STATE_OR_PROVINCE: if (state) { @@ -132,6 +140,9 @@ CERT_FormatName(CERTName *name) goto loser; } len += state->len; + // state currently won't have COMMA after it, but this is a + // (probably vain) attempt to future-proof this code + len += COMMALEN; break; case SEC_OID_AVA_ORGANIZATION_NAME: if (org) { @@ -142,6 +153,8 @@ CERT_FormatName(CERTName *name) goto loser; } len += org->len; + // org will have BREAK after it + len += BREAKLEN; break; case SEC_OID_AVA_DN_QUALIFIER: if (dq) { @@ -152,6 +165,8 @@ CERT_FormatName(CERTName *name) goto loser; } len += dq->len; + // dq will have BREAK after it + len += BREAKLEN; break; case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: if (ou_count < MAX_OUS) { @@ -160,6 +175,8 @@ CERT_FormatName(CERTName *name) goto loser; } len += orgunit[ou_count++]->len; + // each ou will have BREAK after it + len += BREAKLEN; } break; case SEC_OID_AVA_DC: @@ -169,6 +186,8 @@ CERT_FormatName(CERTName *name) goto loser; } len += dc[dc_count++]->len; + // each dc will have BREAK after it + len += BREAKLEN; } break; case SEC_OID_PKCS9_EMAIL_ADDRESS: @@ -181,6 +200,8 @@ CERT_FormatName(CERTName *name) goto loser; } len += email->len; + // email will have BREAK after it + len += BREAKLEN; break; default: break; @@ -188,8 +209,8 @@ CERT_FormatName(CERTName *name) } } - /* XXX - add some for formatting */ - len += 128; + // there may be a final BREAK + len += BREAKLEN; /* allocate buffer */ buf = (char *)PORT_Alloc(len); diff --git a/nss/lib/certhigh/ocsp.c b/nss/lib/certhigh/ocsp.c index 1048513..cea8456 100644 --- a/nss/lib/certhigh/ocsp.c +++ b/nss/lib/certhigh/ocsp.c @@ -2195,7 +2195,7 @@ SetRequestExts(void *object, CERTCertExtension **exts) request->tbsRequest->requestExtensions = exts; } -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(NSS_NO_GCC48) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wvarargs" #endif @@ -2265,7 +2265,7 @@ loser: (void)CERT_FinishExtensions(extHandle); return rv; } -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(NSS_NO_GCC48) #pragma GCC diagnostic pop #endif diff --git a/nss/lib/ckfw/builtins/builtins.gyp b/nss/lib/ckfw/builtins/builtins.gyp index d854425..f8dbc11 100644 --- a/nss/lib/ckfw/builtins/builtins.gyp +++ b/nss/lib/ckfw/builtins/builtins.gyp @@ -19,7 +19,7 @@ 'btoken.c', 'ckbiver.c', 'constants.c', - '<(INTERMEDIATE_DIR)/certdata.c' + '<(certdata_c)', ], 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports', @@ -30,23 +30,25 @@ { 'msvs_cygwin_shell': 0, 'action': [ - 'perl', - 'certdata.perl', + 'python', + 'certdata.py', 'certdata.txt', '<@(_outputs)', ], 'inputs': [ + 'certdata.py', 'certdata.perl', 'certdata.txt' ], 'outputs': [ - '<(INTERMEDIATE_DIR)/certdata.c' + '<(certdata_c)' ], 'action_name': 'generate_certdata_c' } ], 'variables': { - 'mapfile': 'nssckbi.def' + 'mapfile': 'nssckbi.def', + 'certdata_c': '<(INTERMEDIATE_DIR)/certdata.c', } } ], diff --git a/nss/lib/ckfw/builtins/certdata.py b/nss/lib/ckfw/builtins/certdata.py new file mode 100755 index 0000000..0778247 --- /dev/null +++ b/nss/lib/ckfw/builtins/certdata.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# +# 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/. + +import subprocess +import os +import sys + +def main(): + args = [os.path.realpath(x) for x in sys.argv[1:]] + script = os.path.dirname(os.path.abspath(__file__))+'/certdata.perl' + subprocess.check_call([os.environ.get('PERL', 'perl'), script] + args, + env=os.environ) + +if __name__ == '__main__': + main() diff --git a/nss/lib/ckfw/builtins/certdata.txt b/nss/lib/ckfw/builtins/certdata.txt index 24df334..020db76 100644 --- a/nss/lib/ckfw/builtins/certdata.txt +++ b/nss/lib/ckfw/builtins/certdata.txt @@ -191,6 +191,7 @@ CKA_VALUE MULTILINE_OCTAL \034\305\037\244\200\157\025\040\311\336\014\210\012\035\326\146 \125\342\374\110\311\051\046\151\340 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GlobalSign Root CA" # Issuer: CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE @@ -324,6 +325,7 @@ CKA_VALUE MULTILINE_OCTAL \035\111\367\252\336\225\317\040\170\302\140\022\333\045\100\214 \152\374\176\102\070\100\144\022\367\236\201\341\223\056 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GlobalSign Root CA - R2" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R2 @@ -479,6 +481,7 @@ CKA_VALUE MULTILINE_OCTAL \363\334\017\337\012\207\304\357\206\005\325\070\024\140\231\243 \113\336\006\226\161\054\362\333\266\037\244\357\077\356 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Verisign Class 1 Public Primary Certification Authority - G3" # Issuer: CN=VeriSign Class 1 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -643,6 +646,7 @@ CKA_VALUE MULTILINE_OCTAL \377\343\030\174\211\213\063\135\254\063\327\247\371\332\072\125 \311\130\020\371\252\357\132\266\317\113\113\337\052 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Verisign Class 2 Public Primary Certification Authority - G3" # Issuer: CN=VeriSign Class 2 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -807,6 +811,7 @@ CKA_VALUE MULTILINE_OCTAL \200\332\267\155\027\217\235\036\201\144\341\376\305\105\272\255 \153\271\012\172\116\117\113\204\356\113\361\175\335\021 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Verisign Class 3 Public Primary Certification Authority - G3" # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3,OU="(c) 1999 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -1081,6 +1086,7 @@ CKA_VALUE MULTILINE_OCTAL \334\200\220\215\263\147\233\157\110\010\025\126\317\277\361\053 \174\136\232\166\351\131\220\305\174\203\065\021\145\121 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Entrust.net Premium 2048 Secure Server CA" # Issuer: CN=Entrust.net Certification Authority (2048),OU=(c) 1999 Entrust.net Limited,OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.),O=Entrust.net @@ -1218,6 +1224,7 @@ CKA_VALUE MULTILINE_OCTAL \107\322\070\056\320\376\201\334\062\152\036\265\356\074\325\374 \347\201\035\031\303\044\102\352\143\071\251 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Baltimore CyberTrust Root" # Issuer: CN=Baltimore CyberTrust Root,OU=CyberTrust,O=Baltimore,C=IE @@ -1361,6 +1368,7 @@ CKA_VALUE MULTILINE_OCTAL \213\343\161\314\036\033\040\104\010\300\172\266\100\375\304\344 \065\341\035\026\034\320\274\053\216\326\161\331 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AddTrust Low-Value Services Root" # Issuer: CN=AddTrust Class 1 CA Root,OU=AddTrust TTP Network,O=AddTrust AB,C=SE @@ -1509,6 +1517,7 @@ CKA_VALUE MULTILINE_OCTAL \232\171\017\040\012\056\325\236\143\046\036\125\222\224\330\202 \027\132\173\320\274\307\217\116\206\004 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AddTrust External Root" # Issuer: CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE @@ -1654,6 +1663,7 @@ CKA_VALUE MULTILINE_OCTAL \137\107\022\347\316\137\135\372\330\252\261\063\055\331\166\362 \116\072\063\014\053\263\055\220\006 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AddTrust Public Services Root" # Issuer: CN=AddTrust Public CA Root,OU=AddTrust TTP Network,O=AddTrust AB,C=SE @@ -1799,6 +1809,7 @@ CKA_VALUE MULTILINE_OCTAL \074\047\067\177\203\256\236\167\317\360\060\261\377\113\231\350 \306\241 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AddTrust Qualified Certificates Root" # Issuer: CN=AddTrust Qualified CA Root,OU=AddTrust TTP Network,O=AddTrust AB,C=SE @@ -1961,6 +1972,7 @@ CKA_VALUE MULTILINE_OCTAL \322\367\127\160\066\263\277\374\050\257\161\045\205\133\023\376 \036\177\132\264\074 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Entrust Root Certification Authority" # Issuer: CN=Entrust Root Certification Authority,OU="(c) 2006 Entrust, Inc.",OU=www.entrust.net/CPS is incorporated by reference,O="Entrust, Inc.",C=US @@ -2094,6 +2106,7 @@ CKA_VALUE MULTILINE_OCTAL \331\027\264\321\343\121\053\136\165\350\325\320\334\117\064\355 \302\005\146\200\241\313\346\063 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GeoTrust Global CA" # Issuer: CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US @@ -2221,6 +2234,7 @@ CKA_VALUE MULTILINE_OCTAL \107\112\126\230\321\132\205\037\214\365\042\277\253\316\203\363 \342\042\051\256\175\203\100\250\272\154 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GeoTrust Global CA 2" # Issuer: CN=GeoTrust Global CA 2,O=GeoTrust Inc.,C=US @@ -2380,6 +2394,7 @@ CKA_VALUE MULTILINE_OCTAL \247\110\301\134\220\017\313\310\077\372\346\062\341\215\033\157 \244\346\216\330\371\051\110\212\316\163\376\054 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GeoTrust Universal CA" # Issuer: CN=GeoTrust Universal CA,O=GeoTrust Inc.,C=US @@ -2539,6 +2554,7 @@ CKA_VALUE MULTILINE_OCTAL \370\351\242\054\114\246\321\046\137\176\257\132\114\332\037\246 \362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GeoTrust Universal CA 2" # Issuer: CN=GeoTrust Universal CA 2,O=GeoTrust Inc.,C=US @@ -2675,6 +2691,7 @@ CKA_VALUE MULTILINE_OCTAL \337\337\063\234\317\343\255\256\216\324\216\346\117\121\257\026 \222\340\134\366\007\017 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Visa eCommerce Root" # Issuer: CN=Visa eCommerce Root,OU=Visa International Service Association,O=VISA,C=US @@ -2797,6 +2814,7 @@ CKA_VALUE MULTILINE_OCTAL \355\200\316\211\100\110\152\016\065\312\051\146\025\041\224\054 \350\140\052\233\205\112\100\363\153\212\044\354\006\026\054\163 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Certum Root CA" # Issuer: CN=Certum CA,O=Unizeto Sp. z o.o.,C=PL @@ -2942,6 +2960,7 @@ CKA_VALUE MULTILINE_OCTAL \262\143\342\365\142\054\202\324\152\000\101\120\361\071\203\237 \225\351\066\226\230\156 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Comodo AAA Services root" # Issuer: CN=AAA Certificate Services,O=Comodo CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -3092,6 +3111,7 @@ CKA_VALUE MULTILINE_OCTAL \241\137\015\274\161\274\016\254\013\035\107\105\035\301\354\174 \354\375\051 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Comodo Secure Services root" # Issuer: CN=Secure Certificate Services,O=Comodo CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -3244,6 +3264,7 @@ CKA_VALUE MULTILINE_OCTAL \005\107\165\152\132\041\263\243\030\317\116\367\056\127\267\230 \160\136\310\304\170\260\142 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Comodo Trusted Services root" # Issuer: CN=Trusted Certificate Services,O=Comodo CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -3422,6 +3443,7 @@ CKA_VALUE MULTILINE_OCTAL \207\051\317\362\211\115\324\354\305\342\346\172\320\066\043\212 \112\164\066\371 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "QuoVadis Root CA" # Issuer: CN=QuoVadis Root Certification Authority,OU=Root Certification Authority,O=QuoVadis Limited,C=BM @@ -3590,6 +3612,7 @@ CKA_VALUE MULTILINE_OCTAL \361\343\261\357\337\221\217\124\052\013\045\301\046\031\304\122 \020\005\145\325\202\020\352\302\061\315\056 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "QuoVadis Root CA 2" # Issuer: CN=QuoVadis Root CA 2,O=QuoVadis Limited,C=BM @@ -3769,6 +3792,7 @@ CKA_VALUE MULTILINE_OCTAL \341\045\141\063\262\131\033\342\156\327\067\127\266\015\251\022 \332 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "QuoVadis Root CA 3" # Issuer: CN=QuoVadis Root CA 3,O=QuoVadis Limited,C=BM @@ -3897,6 +3921,7 @@ CKA_VALUE MULTILINE_OCTAL \214\154\041\314\164\102\355\123\377\063\213\217\017\127\001\026 \057\317\246\356\311\160\042\024\275\375\276\154\013\003 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Security Communication Root CA" # Issuer: OU=Security Communication RootCA1,O=SECOM Trust.net,C=JP @@ -4019,6 +4044,7 @@ CKA_VALUE MULTILINE_OCTAL \072\216\013\252\062\156\333\374\117\045\237\331\062\307\226\132 \160\254\337\114 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Sonera Class 2 Root CA" # Issuer: CN=Sonera Class2 CA,O=Sonera,C=FI @@ -4180,6 +4206,7 @@ CKA_VALUE MULTILINE_OCTAL \370\320\216\362\363\306\256\050\133\247\360\363\066\027\374\303 \005\323\312\003\112\124 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "UTN USERFirst Email Root CA" # Issuer: CN=UTN-USERFirst-Client Authentication and Email,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US @@ -4343,6 +4370,7 @@ CKA_VALUE MULTILINE_OCTAL \152\236\121\015\052\121\236\201\371\324\073\136\160\022\177\020 \062\234\036\273\235\370\146\250 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "UTN USERFirst Hardware Root CA" # Issuer: CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US @@ -4503,6 +4531,7 @@ CKA_VALUE MULTILINE_OCTAL \122\037\224\337\027\224\163\303\263\301\301\161\005\040\000\170 \275\023\122\035\250\076\315\000\037\310 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "UTN USERFirst Object Root CA" # Issuer: CN=UTN-USERFirst-Object,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US @@ -4666,6 +4695,7 @@ CKA_VALUE MULTILINE_OCTAL \264\145\232\041\220\340\252\320\230\274\070\265\163\074\213\370 \334 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Camerfirma Chambers of Commerce Root" # Issuer: CN=Chambers of Commerce Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU @@ -4825,6 +4855,7 @@ CKA_VALUE MULTILINE_OCTAL \001\212\005\132\223\276\241\301\377\370\347\016\147\244\107\111 \166\135\165\220\032\365\046\217\360 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Camerfirma Global Chambersign Root" # Issuer: CN=Global Chambersign Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU @@ -4977,6 +5008,7 @@ CKA_VALUE MULTILINE_OCTAL \073\356\304\114\364\354\047\174\102\302\164\174\202\212\011\311 \264\003\045\274 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "XRamp Global CA Root" # Issuer: CN=XRamp Global Certification Authority,O=XRamp Security Services Inc,OU=www.xrampsecurity.com,C=US @@ -5123,6 +5155,7 @@ CKA_VALUE MULTILINE_OCTAL \105\346\015\237\050\234\261\271\052\132\127\255\067\017\257\035 \177\333\275\237 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Go Daddy Class 2 CA" # Issuer: OU=Go Daddy Class 2 Certification Authority,O="The Go Daddy Group, Inc.",C=US @@ -5267,6 +5300,7 @@ CKA_VALUE MULTILINE_OCTAL \370\267\100\021\106\232\037\171\016\142\277\017\227\354\340\057 \037\027\224 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Starfield Class 2 CA" # Issuer: OU=Starfield Class 2 Certification Authority,O="Starfield Technologies, Inc.",C=US @@ -5472,6 +5506,7 @@ CKA_VALUE MULTILINE_OCTAL \064\353\005\377\232\042\256\233\175\077\361\145\121\012\246\060 \152\263\364\210\034\200\015\374\162\212\350\203\136 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "StartCom Certification Authority" # Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL @@ -5636,6 +5671,7 @@ CKA_VALUE MULTILINE_OCTAL \020\002\356\047\214\204\377\254\105\015\023\134\203\062\340\045 \245\206\054\174\364\022 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Taiwan GRCA" # Issuer: O=Government Root Certification Authority,C=TW @@ -5808,6 +5844,7 @@ CKA_VALUE MULTILINE_OCTAL \201\310\213\237\071\124\003\045\323\026\065\216\204\320\137\372 \060\032\365\232\154\364\016\123\371\072\133\321\034 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Swisscom Root CA 1" # Issuer: CN=Swisscom Root CA 1,OU=Digital Certificate Services,O=Swisscom,C=ch @@ -5948,6 +5985,7 @@ CKA_VALUE MULTILINE_OCTAL \020\161\235\255\342\303\371\303\231\121\267\053\007\010\316\056 \346\120\262\247\372\012\105\057\242\360\362 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "DigiCert Assured ID Root CA" # Issuer: CN=DigiCert Assured ID Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -6088,6 +6126,7 @@ CKA_VALUE MULTILINE_OCTAL \001\022\255\310\210\306\230\064\137\215\012\074\306\351\325\225 \225\155\336 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "DigiCert Global Root CA" # Issuer: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -6229,6 +6268,7 @@ CKA_VALUE MULTILINE_OCTAL \315\354\107\252\045\047\147\240\067\363\000\202\175\124\327\251 \370\351\056\023\243\167\350\037\112 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "DigiCert High Assurance EV Root CA" # Issuer: CN=DigiCert High Assurance EV Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -6361,6 +6401,7 @@ CKA_VALUE MULTILINE_OCTAL \010\346\236\005\115\107\030\325\026\351\261\326\266\020\325\273 \227\277\242\216\264\124 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Certplus Class 2 Primary CA" # Issuer: CN=Class 2 Primary CA,O=Certplus,C=FR @@ -6487,6 +6528,7 @@ CKA_VALUE MULTILINE_OCTAL \071\277\025\145\034\310\366\167\226\152\012\215\167\013\330\221 \013\004\216\007\333\051\266\012\356\235\202\065\065\020 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "DST Root CA X3" # Issuer: CN=DST Root CA X3,O=Digital Signature Trust Co. @@ -6628,6 +6670,7 @@ CKA_VALUE MULTILINE_OCTAL \367\016\013\114\234\150\170\173\161\061\307\353\036\340\147\101 \363\267\240\247\315\345\172\063\066\152\372\232\053 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "DST ACES CA X6" # Issuer: CN=DST ACES CA X6,OU=DST ACES,O=Digital Signature Trust,C=US @@ -6795,6 +6838,7 @@ CKA_VALUE MULTILINE_OCTAL \060\245\311\215\330\253\061\201\037\337\302\146\067\323\223\251 \205\206\171\145\322 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "SwissSign Platinum CA - G2" # Issuer: CN=SwissSign Platinum CA - G2,O=SwissSign AG,C=CH @@ -6959,6 +7003,7 @@ CKA_VALUE MULTILINE_OCTAL \101\317\001\261\351\270\311\146\364\333\046\363\072\244\164\362 \111\044\133\311\260\320\127\301\372\076\172\341\227\311 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "SwissSign Gold CA - G2" # Issuer: CN=SwissSign Gold CA - G2,O=SwissSign AG,C=CH @@ -7124,6 +7169,7 @@ CKA_VALUE MULTILINE_OCTAL \036\354\344\012\273\052\114\353\011\140\071\316\312\142\330\056 \156 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "SwissSign Silver CA - G2" # Issuer: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH @@ -7255,6 +7301,7 @@ CKA_VALUE MULTILINE_OCTAL \001\076\200\360\102\240\225\007\136\155\315\314\113\244\105\215 \253\022\350\263\336\132\345\240\174\350\017\042\035\132\351\131 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GeoTrust Primary Certification Authority" # Issuer: CN=GeoTrust Primary Certification Authority,O=GeoTrust Inc.,C=US @@ -7409,6 +7456,7 @@ CKA_VALUE MULTILINE_OCTAL \302\047\060\356\247\020\135\067\217\134\071\053\344\004\360\173 \215\126\214\150 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "thawte Primary Root CA" # Issuer: CN=thawte Primary Root CA,OU="(c) 2006 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US @@ -7583,6 +7631,7 @@ CKA_VALUE MULTILINE_OCTAL \030\077\150\134\362\102\112\205\070\124\203\137\321\350\054\362 \254\021\326\250\355\143\152 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G5" # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -7725,6 +7774,7 @@ CKA_VALUE MULTILINE_OCTAL \143\032\157\004\326\370\306\114\243\232\261\067\264\215\345\050 \113\035\236\054\302\270\150\274\355\002\356\061 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "SecureTrust CA" # Issuer: CN=SecureTrust CA,O=SecureTrust Corporation,C=US @@ -7859,6 +7909,7 @@ CKA_VALUE MULTILINE_OCTAL \032\257\014\015\125\144\064\110\270\222\271\361\264\120\051\362 \117\043\037\332\154\254\037\104\341\335\043\170\121\133\307\026 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Secure Global CA" # Issuer: CN=Secure Global CA,O=SecureTrust Corporation,C=US @@ -8008,6 +8059,7 @@ CKA_VALUE MULTILINE_OCTAL \050\276\060\105\061\036\307\170\276\130\141\070\254\073\342\001 \145 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "COMODO Certification Authority" # Issuer: CN=COMODO Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -8153,6 +8205,7 @@ CKA_VALUE MULTILINE_OCTAL \224\265\324\314\271\275\152\065\126\041\336\330\303\353\373\313 \244\140\114\260\125\240\240\173\127\262 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Network Solutions Certificate Authority" # Issuer: CN=Network Solutions Certificate Authority,O=Network Solutions L.L.C.,C=US @@ -8193,167 +8246,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "WellsSecure Public Root Certificate Authority" -# -# Issuer: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US -# Serial Number: 1 (0x1) -# Subject: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US -# Not Valid Before: Thu Dec 13 17:07:54 2007 -# Not Valid After : Wed Dec 14 00:07:54 2022 -# Fingerprint (MD5): 15:AC:A5:C2:92:2D:79:BC:E8:7F:CB:67:ED:02:CF:36 -# Fingerprint (SHA1): E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "WellsSecure Public Root Certificate Authority" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163 -\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165 -\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154 -\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101 -\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163 -\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157 -\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101 -\165\164\150\157\162\151\164\171 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163 -\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165 -\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154 -\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101 -\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163 -\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157 -\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101 -\165\164\150\157\162\151\164\171 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\275\060\202\003\245\240\003\002\001\002\002\001\001 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123\061 -\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163\040 -\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165\162 -\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154\154 -\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101\061 -\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163\123 -\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157\157 -\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165 -\164\150\157\162\151\164\171\060\036\027\015\060\067\061\062\061 -\063\061\067\060\067\065\064\132\027\015\062\062\061\062\061\064 -\060\060\060\067\065\064\132\060\201\205\061\013\060\011\006\003 -\125\004\006\023\002\125\123\061\040\060\036\006\003\125\004\012 -\014\027\127\145\154\154\163\040\106\141\162\147\157\040\127\145 -\154\154\163\123\145\143\165\162\145\061\034\060\032\006\003\125 -\004\013\014\023\127\145\154\154\163\040\106\141\162\147\157\040 -\102\141\156\153\040\116\101\061\066\060\064\006\003\125\004\003 -\014\055\127\145\154\154\163\123\145\143\165\162\145\040\120\165 -\142\154\151\143\040\122\157\157\164\040\103\145\162\164\151\146 -\151\143\141\164\145\040\101\165\164\150\157\162\151\164\171\060 -\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001 -\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000 -\356\157\264\275\171\342\217\010\041\236\070\004\101\045\357\253 -\133\034\123\222\254\155\236\335\302\304\056\105\224\003\065\210 -\147\164\127\343\337\214\270\247\166\217\073\367\250\304\333\051 -\143\016\221\150\066\212\227\216\212\161\150\011\007\344\350\324 -\016\117\370\326\053\114\244\026\371\357\103\230\217\263\236\122 -\337\155\221\071\217\070\275\167\213\103\143\353\267\223\374\060 -\114\034\001\223\266\023\373\367\241\037\277\045\341\164\067\054 -\036\244\136\074\150\370\113\277\015\271\036\056\066\350\251\344 -\247\370\017\313\202\165\174\065\055\042\326\302\277\013\363\264 -\374\154\225\141\036\127\327\004\201\062\203\122\171\346\203\143 -\317\267\313\143\213\021\342\275\136\353\366\215\355\225\162\050 -\264\254\022\142\351\112\063\346\203\062\256\005\165\225\275\204 -\225\333\052\134\233\216\056\014\270\201\053\101\346\070\126\237 -\111\233\154\166\372\212\135\367\001\171\201\174\301\203\100\005 -\376\161\375\014\077\314\116\140\011\016\145\107\020\057\001\300 -\005\077\217\370\263\101\357\132\102\176\131\357\322\227\014\145 -\002\003\001\000\001\243\202\001\064\060\202\001\060\060\017\006 -\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\071 -\006\003\125\035\037\004\062\060\060\060\056\240\054\240\052\206 -\050\150\164\164\160\072\057\057\143\162\154\056\160\153\151\056 -\167\145\154\154\163\146\141\162\147\157\056\143\157\155\057\167 -\163\160\162\143\141\056\143\162\154\060\016\006\003\125\035\017 -\001\001\377\004\004\003\002\001\306\060\035\006\003\125\035\016 -\004\026\004\024\046\225\031\020\331\350\241\227\221\377\334\031 -\331\265\004\076\322\163\012\152\060\201\262\006\003\125\035\043 -\004\201\252\060\201\247\200\024\046\225\031\020\331\350\241\227 -\221\377\334\031\331\265\004\076\322\163\012\152\241\201\213\244 -\201\210\060\201\205\061\013\060\011\006\003\125\004\006\023\002 -\125\123\061\040\060\036\006\003\125\004\012\014\027\127\145\154 -\154\163\040\106\141\162\147\157\040\127\145\154\154\163\123\145 -\143\165\162\145\061\034\060\032\006\003\125\004\013\014\023\127 -\145\154\154\163\040\106\141\162\147\157\040\102\141\156\153\040 -\116\101\061\066\060\064\006\003\125\004\003\014\055\127\145\154 -\154\163\123\145\143\165\162\145\040\120\165\142\154\151\143\040 -\122\157\157\164\040\103\145\162\164\151\146\151\143\141\164\145 -\040\101\165\164\150\157\162\151\164\171\202\001\001\060\015\006 -\011\052\206\110\206\367\015\001\001\005\005\000\003\202\001\001 -\000\271\025\261\104\221\314\043\310\053\115\167\343\370\232\173 -\047\015\315\162\273\231\000\312\174\146\031\120\306\325\230\355 -\253\277\003\132\345\115\345\036\310\117\161\227\206\325\343\035 -\375\220\311\074\165\167\127\172\175\370\336\364\324\325\367\225 -\346\164\156\035\074\256\174\235\333\002\003\005\054\161\113\045 -\076\007\343\136\232\365\146\027\051\210\032\070\237\317\252\101 -\003\204\227\153\223\070\172\312\060\104\033\044\104\063\320\344 -\321\334\050\070\364\023\103\065\065\051\143\250\174\242\265\255 -\070\244\355\255\375\306\232\037\377\227\163\376\373\263\065\247 -\223\206\306\166\221\000\346\254\121\026\304\047\062\134\333\163 -\332\245\223\127\216\076\155\065\046\010\131\325\347\104\327\166 -\040\143\347\254\023\147\303\155\261\160\106\174\325\226\021\075 -\211\157\135\250\241\353\215\012\332\303\035\063\154\243\352\147 -\031\232\231\177\113\075\203\121\052\035\312\057\206\014\242\176 -\020\055\053\324\026\225\013\007\252\056\024\222\111\267\051\157 -\330\155\061\175\365\374\241\020\007\207\316\057\131\334\076\130 -\333 -END - -# Trust for Certificate "WellsSecure Public Root Certificate Authority" -# Issuer: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US -# Serial Number: 1 (0x1) -# Subject: CN=WellsSecure Public Root Certificate Authority,OU=Wells Fargo Bank NA,O=Wells Fargo WellsSecure,C=US -# Not Valid Before: Thu Dec 13 17:07:54 2007 -# Not Valid After : Wed Dec 14 00:07:54 2022 -# Fingerprint (MD5): 15:AC:A5:C2:92:2D:79:BC:E8:7F:CB:67:ED:02:CF:36 -# Fingerprint (SHA1): E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "WellsSecure Public Root Certificate Authority" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\347\264\366\235\141\354\220\151\333\176\220\247\100\032\074\364 -\175\117\350\356 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\025\254\245\302\222\055\171\274\350\177\313\147\355\002\317\066 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\205\061\013\060\011\006\003\125\004\006\023\002\125\123 -\061\040\060\036\006\003\125\004\012\014\027\127\145\154\154\163 -\040\106\141\162\147\157\040\127\145\154\154\163\123\145\143\165 -\162\145\061\034\060\032\006\003\125\004\013\014\023\127\145\154 -\154\163\040\106\141\162\147\157\040\102\141\156\153\040\116\101 -\061\066\060\064\006\003\125\004\003\014\055\127\145\154\154\163 -\123\145\143\165\162\145\040\120\165\142\154\151\143\040\122\157 -\157\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101 -\165\164\150\157\162\151\164\171 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\001 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# # Certificate "COMODO ECC Certification Authority" # # Issuer: CN=COMODO ECC Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -8439,6 +8331,7 @@ CKA_VALUE MULTILINE_OCTAL \030\067\200\123\376\335\040\340\065\232\066\321\307\001\271\346 \334\335\363\377\035\054\072\026\127\331\222\071\326 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "COMODO ECC Certification Authority" # Issuer: CN=COMODO ECC Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -8746,6 +8639,7 @@ CKA_VALUE MULTILINE_OCTAL \310\074\255\010\311\260\230\100\243\052\347\210\203\355\167\217 \164 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Security Communication EV RootCA1" # Issuer: OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP @@ -8893,6 +8787,7 @@ CKA_VALUE MULTILINE_OCTAL \130\123\265\234\273\157\237\134\305\030\354\335\057\341\230\311 \374\276\337\012\015 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "OISTE WISeKey Global Root GA CA" # Issuer: CN=OISTE WISeKey Global Root GA CA,OU=OISTE Foundation Endorsed,OU=Copyright (c) 2005,O=WISeKey,C=CH @@ -8935,212 +8830,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "Microsec e-Szigno Root CA" -# -# Issuer: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU -# Serial Number:00:cc:b8:e7:bf:4e:29:1a:fd:a2:dc:66:a5:1c:2c:0f:11 -# Subject: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU -# Not Valid Before: Wed Apr 06 12:28:44 2005 -# Not Valid After : Thu Apr 06 12:28:44 2017 -# Fingerprint (MD5): F0:96:B6:2F:C5:10:D5:67:8E:83:25:32:E8:5E:2E:E5 -# Fingerprint (SHA1): 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Microsec e-Szigno Root CA" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061 -\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145 -\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143 -\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003 -\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101 -\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157 -\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157 -\164\040\103\101 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061 -\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145 -\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143 -\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003 -\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101 -\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157 -\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157 -\164\040\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\314\270\347\277\116\051\032\375\242\334\146\245\034 -\054\017\021 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\007\250\060\202\006\220\240\003\002\001\002\002\021\000 -\314\270\347\277\116\051\032\375\242\334\146\245\034\054\017\021 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061\021 -\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145\163 -\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143\162 -\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003\125 -\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101\061 -\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157\163 -\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157\164 -\040\103\101\060\036\027\015\060\065\060\064\060\066\061\062\062 -\070\064\064\132\027\015\061\067\060\064\060\066\061\062\062\070 -\064\064\132\060\162\061\013\060\011\006\003\125\004\006\023\002 -\110\125\061\021\060\017\006\003\125\004\007\023\010\102\165\144 -\141\160\145\163\164\061\026\060\024\006\003\125\004\012\023\015 -\115\151\143\162\157\163\145\143\040\114\164\144\056\061\024\060 -\022\006\003\125\004\013\023\013\145\055\123\172\151\147\156\157 -\040\103\101\061\042\060\040\006\003\125\004\003\023\031\115\151 -\143\162\157\163\145\143\040\145\055\123\172\151\147\156\157\040 -\122\157\157\164\040\103\101\060\202\001\042\060\015\006\011\052 -\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060 -\202\001\012\002\202\001\001\000\355\310\000\325\201\173\315\070 -\000\107\314\333\204\301\041\151\054\164\220\014\041\331\123\207 -\355\076\103\104\123\257\253\370\200\233\074\170\215\324\215\256 -\270\357\323\021\334\201\346\317\073\226\214\326\157\025\306\167 -\176\241\057\340\137\222\266\047\327\166\232\035\103\074\352\331 -\354\057\356\071\363\152\147\113\213\202\317\042\370\145\125\376 -\054\313\057\175\110\172\075\165\371\252\240\047\273\170\302\006 -\312\121\302\176\146\113\257\315\242\247\115\002\202\077\202\254 -\205\306\341\017\220\107\231\224\012\161\162\223\052\311\246\300 -\276\074\126\114\163\222\047\361\153\265\365\375\374\060\005\140 -\222\306\353\226\176\001\221\302\151\261\036\035\173\123\105\270 -\334\101\037\311\213\161\326\124\024\343\213\124\170\077\276\364 -\142\073\133\365\243\354\325\222\164\342\164\060\357\001\333\341 -\324\253\231\233\052\153\370\275\246\034\206\043\102\137\354\111 -\336\232\213\133\364\162\072\100\305\111\076\245\276\216\252\161 -\353\154\372\365\032\344\152\375\173\175\125\100\357\130\156\346 -\331\325\274\044\253\301\357\267\002\003\001\000\001\243\202\004 -\067\060\202\004\063\060\147\006\010\053\006\001\005\005\007\001 -\001\004\133\060\131\060\050\006\010\053\006\001\005\005\007\060 -\001\206\034\150\164\164\160\163\072\057\057\162\143\141\056\145 -\055\163\172\151\147\156\157\056\150\165\057\157\143\163\160\060 -\055\006\010\053\006\001\005\005\007\060\002\206\041\150\164\164 -\160\072\057\057\167\167\167\056\145\055\163\172\151\147\156\157 -\056\150\165\057\122\157\157\164\103\101\056\143\162\164\060\017 -\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060 -\202\001\163\006\003\125\035\040\004\202\001\152\060\202\001\146 -\060\202\001\142\006\014\053\006\001\004\001\201\250\030\002\001 -\001\001\060\202\001\120\060\050\006\010\053\006\001\005\005\007 -\002\001\026\034\150\164\164\160\072\057\057\167\167\167\056\145 -\055\163\172\151\147\156\157\056\150\165\057\123\132\123\132\057 -\060\202\001\042\006\010\053\006\001\005\005\007\002\002\060\202 -\001\024\036\202\001\020\000\101\000\040\000\164\000\141\000\156 -\000\372\000\163\000\355\000\164\000\166\000\341\000\156\000\171 -\000\040\000\351\000\162\000\164\000\145\000\154\000\155\000\145 -\000\172\000\351\000\163\000\351\000\150\000\145\000\172\000\040 -\000\351\000\163\000\040\000\145\000\154\000\146\000\157\000\147 -\000\141\000\144\000\341\000\163\000\341\000\150\000\157\000\172 -\000\040\000\141\000\040\000\123\000\172\000\157\000\154\000\147 -\000\341\000\154\000\164\000\141\000\164\000\363\000\040\000\123 -\000\172\000\157\000\154\000\147\000\341\000\154\000\164\000\141 -\000\164\000\341\000\163\000\151\000\040\000\123\000\172\000\141 -\000\142\000\341\000\154\000\171\000\172\000\141\000\164\000\141 -\000\040\000\163\000\172\000\145\000\162\000\151\000\156\000\164 -\000\040\000\153\000\145\000\154\000\154\000\040\000\145\000\154 -\000\152\000\341\000\162\000\156\000\151\000\072\000\040\000\150 -\000\164\000\164\000\160\000\072\000\057\000\057\000\167\000\167 -\000\167\000\056\000\145\000\055\000\163\000\172\000\151\000\147 -\000\156\000\157\000\056\000\150\000\165\000\057\000\123\000\132 -\000\123\000\132\000\057\060\201\310\006\003\125\035\037\004\201 -\300\060\201\275\060\201\272\240\201\267\240\201\264\206\041\150 -\164\164\160\072\057\057\167\167\167\056\145\055\163\172\151\147 -\156\157\056\150\165\057\122\157\157\164\103\101\056\143\162\154 -\206\201\216\154\144\141\160\072\057\057\154\144\141\160\056\145 -\055\163\172\151\147\156\157\056\150\165\057\103\116\075\115\151 -\143\162\157\163\145\143\045\062\060\145\055\123\172\151\147\156 -\157\045\062\060\122\157\157\164\045\062\060\103\101\054\117\125 -\075\145\055\123\172\151\147\156\157\045\062\060\103\101\054\117 -\075\115\151\143\162\157\163\145\143\045\062\060\114\164\144\056 -\054\114\075\102\165\144\141\160\145\163\164\054\103\075\110\125 -\077\143\145\162\164\151\146\151\143\141\164\145\122\145\166\157 -\143\141\164\151\157\156\114\151\163\164\073\142\151\156\141\162 -\171\060\016\006\003\125\035\017\001\001\377\004\004\003\002\001 -\006\060\201\226\006\003\125\035\021\004\201\216\060\201\213\201 -\020\151\156\146\157\100\145\055\163\172\151\147\156\157\056\150 -\165\244\167\060\165\061\043\060\041\006\003\125\004\003\014\032 -\115\151\143\162\157\163\145\143\040\145\055\123\172\151\147\156 -\303\263\040\122\157\157\164\040\103\101\061\026\060\024\006\003 -\125\004\013\014\015\145\055\123\172\151\147\156\303\263\040\110 -\123\132\061\026\060\024\006\003\125\004\012\023\015\115\151\143 -\162\157\163\145\143\040\113\146\164\056\061\021\060\017\006\003 -\125\004\007\023\010\102\165\144\141\160\145\163\164\061\013\060 -\011\006\003\125\004\006\023\002\110\125\060\201\254\006\003\125 -\035\043\004\201\244\060\201\241\200\024\307\240\111\165\026\141 -\204\333\061\113\204\322\361\067\100\220\357\116\334\367\241\166 -\244\164\060\162\061\013\060\011\006\003\125\004\006\023\002\110 -\125\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141 -\160\145\163\164\061\026\060\024\006\003\125\004\012\023\015\115 -\151\143\162\157\163\145\143\040\114\164\144\056\061\024\060\022 -\006\003\125\004\013\023\013\145\055\123\172\151\147\156\157\040 -\103\101\061\042\060\040\006\003\125\004\003\023\031\115\151\143 -\162\157\163\145\143\040\145\055\123\172\151\147\156\157\040\122 -\157\157\164\040\103\101\202\021\000\314\270\347\277\116\051\032 -\375\242\334\146\245\034\054\017\021\060\035\006\003\125\035\016 -\004\026\004\024\307\240\111\165\026\141\204\333\061\113\204\322 -\361\067\100\220\357\116\334\367\060\015\006\011\052\206\110\206 -\367\015\001\001\005\005\000\003\202\001\001\000\323\023\234\146 -\143\131\056\312\134\160\014\374\203\274\125\261\364\216\007\154 -\146\047\316\301\073\040\251\034\273\106\124\160\356\132\314\240 -\167\352\150\104\047\353\362\051\335\167\251\325\373\343\324\247 -\004\304\225\270\013\341\104\150\140\007\103\060\061\102\141\345 -\356\331\345\044\325\033\337\341\112\033\252\237\307\137\370\172 -\021\352\023\223\000\312\212\130\261\356\355\016\115\264\327\250 -\066\046\174\340\072\301\325\127\202\361\165\266\375\211\137\332 -\363\250\070\237\065\006\010\316\042\225\276\315\325\374\276\133 -\336\171\153\334\172\251\145\146\276\261\045\132\137\355\176\323 -\254\106\155\114\364\062\207\264\040\004\340\154\170\260\167\321 -\205\106\113\246\022\267\165\350\112\311\126\154\327\222\253\235 -\365\111\070\322\117\123\343\125\220\021\333\230\226\306\111\362 -\076\364\237\033\340\367\210\334\045\142\231\104\330\163\277\077 -\060\363\014\067\076\324\302\050\200\163\261\001\267\235\132\226 -\024\001\113\251\021\235\051\152\056\320\135\201\300\317\262\040 -\103\307\003\340\067\116\135\012\334\131\040\045 -END - -# Trust for Certificate "Microsec e-Szigno Root CA" -# Issuer: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU -# Serial Number:00:cc:b8:e7:bf:4e:29:1a:fd:a2:dc:66:a5:1c:2c:0f:11 -# Subject: CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU -# Not Valid Before: Wed Apr 06 12:28:44 2005 -# Not Valid After : Thu Apr 06 12:28:44 2017 -# Fingerprint (MD5): F0:96:B6:2F:C5:10:D5:67:8E:83:25:32:E8:5E:2E:E5 -# Fingerprint (SHA1): 23:88:C9:D3:71:CC:9E:96:3D:FF:7D:3C:A7:CE:FC:D6:25:EC:19:0D -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "Microsec e-Szigno Root CA" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\043\210\311\323\161\314\236\226\075\377\175\074\247\316\374\326 -\045\354\031\015 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\360\226\266\057\305\020\325\147\216\203\045\062\350\136\056\345 -END -CKA_ISSUER MULTILINE_OCTAL -\060\162\061\013\060\011\006\003\125\004\006\023\002\110\125\061 -\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145 -\163\164\061\026\060\024\006\003\125\004\012\023\015\115\151\143 -\162\157\163\145\143\040\114\164\144\056\061\024\060\022\006\003 -\125\004\013\023\013\145\055\123\172\151\147\156\157\040\103\101 -\061\042\060\040\006\003\125\004\003\023\031\115\151\143\162\157 -\163\145\143\040\145\055\123\172\151\147\156\157\040\122\157\157 -\164\040\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\021\000\314\270\347\277\116\051\032\375\242\334\146\245\034 -\054\017\021 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# # Certificate "Certigna" # # Issuer: CN=Certigna,O=Dhimyotis,C=FR @@ -9233,6 +8922,7 @@ CKA_VALUE MULTILINE_OCTAL \133\041\374\021\221\064\276\101\357\173\235\227\165\377\227\225 \300\226\130\057\352\273\106\327\273\344\331\056 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Certigna" # Issuer: CN=Certigna,O=Dhimyotis,C=FR @@ -9414,6 +9104,7 @@ CKA_VALUE MULTILINE_OCTAL \053\257\134\331\355\107\167\140\016\073\017\036\322\300\334\144 \005\211\374\170\326\134\054\046\103\251 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AC Raiz Certicamara S.A." # Issuer: CN=AC Ra..z Certic..mara S.A.,O=Sociedad Cameral de Certificaci..n Digital - Certic..mara S.A.,C=CO @@ -9571,6 +9262,7 @@ CKA_VALUE MULTILINE_OCTAL \346\222\303\201\301\063\273\210\036\241\347\342\264\275\061\154 \016\121\075\157\373\226\126\200\342\066\027\321\334\344 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "TC TrustCenter Class 3 CA II" # Issuer: CN=TC TrustCenter Class 3 CA II,OU=TC TrustCenter Class 3 CA,O=TC TrustCenter GmbH,C=DE @@ -9711,6 +9403,7 @@ CKA_VALUE MULTILINE_OCTAL \012\155\272\071\143\050\206\222\363\030\204\330\373\321\317\005 \126\144\127 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Deutsche Telekom Root CA 2" # Issuer: CN=Deutsche Telekom Root CA 2,OU=T-TeleSec Trust Center,O=Deutsche Telekom AG,C=DE @@ -9843,6 +9536,7 @@ CKA_VALUE MULTILINE_OCTAL \214\160\250\337\145\062\364\244\100\214\241\302\104\003\016\224 \000\147\240\161\000\202\110 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "ComSign CA" # Issuer: C=IL,O=ComSign,CN=ComSign CA @@ -9973,6 +9667,7 @@ CKA_VALUE MULTILINE_OCTAL \072\064\127\120\072\157\201\136\006\306\365\076\174\116\216\053 \316\145\006\056\135\322\052\123\164\136\323\156\047\236\217 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "ComSign Secured CA" # Issuer: C=IL,O=ComSign,CN=ComSign Secured CA @@ -10102,6 +9797,7 @@ CKA_VALUE MULTILINE_OCTAL \130\275\126\061\022\116\021\310\041\340\263\021\221\145\333\264 \246\210\070\316\125 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Cybertrust Global Root" # Issuer: CN=Cybertrust Global Root,O="Cybertrust, Inc" @@ -10268,6 +9964,7 @@ CKA_VALUE MULTILINE_OCTAL \204\324\076\040\205\367\112\075\053\234\375\052\012\011\115\352 \201\370\021\234 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "ePKI Root Certification Authority" # Issuer: OU=ePKI Root Certification Authority,O="Chunghwa Telecom Co., Ltd.",C=TW @@ -10452,6 +10149,7 @@ CKA_VALUE MULTILINE_OCTAL \202\176\044\014\235\375\201\067\343\045\250\355\066\116\225\054 \311\234\220\332\354\251\102\074\255\266\002 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "TUBITAK UEKAE Kok Sertifika Hizmet Saglayicisi - Surum 3" # Issuer: CN=T..B..TAK UEKAE K..k Sertifika Hizmet Sa..lay..c..s.. - S..r..m ...,OU=Kamu Sertifikasyon Merkezi,OU=Ulusal Elektronik ve Kriptoloji Ara..t..rma Enstit..s.. - UEKAE,O=T..rkiye Bilimsel ve Teknolojik Ara..t..rma Kurumu - T..B..TAK,L=Gebze - Kocaeli,C=TR @@ -10588,6 +10286,7 @@ CKA_VALUE MULTILINE_OCTAL \025\147\336\236\166\020\142\040\276\125\151\225\103\000\071\115 \366\356\260\132\116\111\104\124\130\137\102\203 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "certSIGN ROOT CA" # Issuer: OU=certSIGN ROOT CA,O=certSIGN,C=RO @@ -10711,6 +10410,7 @@ CKA_VALUE MULTILINE_OCTAL \056\042\224\011\310\134\352\074\201\135\026\052\003\227\026\125 \011\333\212\101\202\236\146\233\021 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "CNNIC ROOT" # Issuer: CN=CNNIC ROOT,O=CNNIC,C=CN @@ -10747,137 +10447,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "ApplicationCA - Japanese Government" -# -# Issuer: OU=ApplicationCA,O=Japanese Government,C=JP -# Serial Number: 49 (0x31) -# Subject: OU=ApplicationCA,O=Japanese Government,C=JP -# Not Valid Before: Wed Dec 12 15:00:00 2007 -# Not Valid After : Tue Dec 12 15:00:00 2017 -# Fingerprint (MD5): 7E:23:4E:5B:A7:A5:B4:25:E9:00:07:74:11:62:AE:D6 -# Fingerprint (SHA1): 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74 -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "ApplicationCA - Japanese Government" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061 -\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145 -\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060 -\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164 -\151\157\156\103\101 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061 -\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145 -\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060 -\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164 -\151\157\156\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\061 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\003\240\060\202\002\210\240\003\002\001\002\002\001\061 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 -\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061\034 -\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145\163 -\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060\024 -\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164\151 -\157\156\103\101\060\036\027\015\060\067\061\062\061\062\061\065 -\060\060\060\060\132\027\015\061\067\061\062\061\062\061\065\060 -\060\060\060\132\060\103\061\013\060\011\006\003\125\004\006\023 -\002\112\120\061\034\060\032\006\003\125\004\012\023\023\112\141 -\160\141\156\145\163\145\040\107\157\166\145\162\156\155\145\156 -\164\061\026\060\024\006\003\125\004\013\023\015\101\160\160\154 -\151\143\141\164\151\157\156\103\101\060\202\001\042\060\015\006 -\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017 -\000\060\202\001\012\002\202\001\001\000\247\155\340\164\116\207 -\217\245\006\336\150\242\333\206\231\113\144\015\161\360\012\005 -\233\216\252\341\314\056\322\152\073\301\172\264\227\141\215\212 -\276\306\232\234\006\264\206\121\344\067\016\164\170\176\137\212 -\177\224\244\327\107\010\375\120\132\126\344\150\254\050\163\240 -\173\351\177\030\222\100\117\055\235\365\256\104\110\163\066\006 -\236\144\054\073\064\043\333\134\046\344\161\171\217\324\156\171 -\042\271\223\301\312\315\301\126\355\210\152\327\240\071\041\004 -\127\054\242\365\274\107\101\117\136\064\042\225\265\037\051\155 -\136\112\363\115\162\276\101\126\040\207\374\351\120\107\327\060 -\024\356\134\214\125\272\131\215\207\374\043\336\223\320\004\214 -\375\357\155\275\320\172\311\245\072\152\162\063\306\112\015\005 -\027\052\055\173\261\247\330\326\360\276\364\077\352\016\050\155 -\101\141\043\166\170\303\270\145\244\363\132\256\314\302\252\331 -\347\130\336\266\176\235\205\156\237\052\012\157\237\003\051\060 -\227\050\035\274\267\317\124\051\116\121\061\371\047\266\050\046 -\376\242\143\346\101\026\360\063\230\107\002\003\001\000\001\243 -\201\236\060\201\233\060\035\006\003\125\035\016\004\026\004\024 -\124\132\313\046\077\161\314\224\106\015\226\123\352\153\110\320 -\223\376\102\165\060\016\006\003\125\035\017\001\001\377\004\004 -\003\002\001\006\060\131\006\003\125\035\021\004\122\060\120\244 -\116\060\114\061\013\060\011\006\003\125\004\006\023\002\112\120 -\061\030\060\026\006\003\125\004\012\014\017\346\227\245\346\234 -\254\345\233\275\346\224\277\345\272\234\061\043\060\041\006\003 -\125\004\013\014\032\343\202\242\343\203\227\343\203\252\343\202 -\261\343\203\274\343\202\267\343\203\247\343\203\263\103\101\060 -\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377 -\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\003 -\202\001\001\000\071\152\104\166\167\070\072\354\243\147\106\017 -\371\213\006\250\373\152\220\061\316\176\354\332\321\211\174\172 -\353\056\014\275\231\062\347\260\044\326\303\377\365\262\210\011 -\207\054\343\124\341\243\246\262\010\013\300\205\250\310\322\234 -\161\366\035\237\140\374\070\063\023\341\236\334\013\137\332\026 -\120\051\173\057\160\221\017\231\272\064\064\215\225\164\305\176 -\170\251\146\135\275\312\041\167\102\020\254\146\046\075\336\221 -\253\375\025\360\157\355\154\137\020\370\363\026\366\003\212\217 -\247\022\021\014\313\375\077\171\301\234\375\142\356\243\317\124 -\014\321\053\137\027\076\343\076\277\300\053\076\011\233\376\210 -\246\176\264\222\027\374\043\224\201\275\156\247\305\214\302\353 -\021\105\333\370\101\311\226\166\352\160\137\171\022\153\344\243 -\007\132\005\357\047\111\317\041\237\212\114\011\160\146\251\046 -\301\053\021\116\063\322\016\374\326\154\322\016\062\144\150\377 -\255\005\170\137\003\035\250\343\220\254\044\340\017\100\247\113 -\256\213\050\267\202\312\030\007\346\267\133\164\351\040\031\177 -\262\033\211\124 -END - -# Trust for Certificate "ApplicationCA - Japanese Government" -# Issuer: OU=ApplicationCA,O=Japanese Government,C=JP -# Serial Number: 49 (0x31) -# Subject: OU=ApplicationCA,O=Japanese Government,C=JP -# Not Valid Before: Wed Dec 12 15:00:00 2007 -# Not Valid After : Tue Dec 12 15:00:00 2017 -# Fingerprint (MD5): 7E:23:4E:5B:A7:A5:B4:25:E9:00:07:74:11:62:AE:D6 -# Fingerprint (SHA1): 7F:8A:B0:CF:D0:51:87:6A:66:F3:36:0F:47:C8:8D:8C:D3:35:FC:74 -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "ApplicationCA - Japanese Government" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\177\212\260\317\320\121\207\152\146\363\066\017\107\310\215\214 -\323\065\374\164 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\176\043\116\133\247\245\264\045\351\000\007\164\021\142\256\326 -END -CKA_ISSUER MULTILINE_OCTAL -\060\103\061\013\060\011\006\003\125\004\006\023\002\112\120\061 -\034\060\032\006\003\125\004\012\023\023\112\141\160\141\156\145 -\163\145\040\107\157\166\145\162\156\155\145\156\164\061\026\060 -\024\006\003\125\004\013\023\015\101\160\160\154\151\143\141\164 -\151\157\156\103\101 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\001\061 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# # Certificate "GeoTrust Primary Certification Authority - G3" # # Issuer: CN=GeoTrust Primary Certification Authority - G3,OU=(c) 2008 GeoTrust Inc. - For authorized use only,O=GeoTrust Inc.,C=US @@ -10989,6 +10558,7 @@ CKA_VALUE MULTILINE_OCTAL \262\231\042\341\301\053\307\234\370\363\137\250\202\022\353\031 \021\055 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GeoTrust Primary Certification Authority - G3" # Issuer: CN=GeoTrust Primary Certification Authority - G3,OU=(c) 2008 GeoTrust Inc. - For authorized use only,O=GeoTrust Inc.,C=US @@ -11117,6 +10687,7 @@ CKA_VALUE MULTILINE_OCTAL \135\235\312\256\275\023\051\104\015\047\133\250\347\150\234\022 \367\130\077\056\162\002\127\243\217\241\024\056 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "thawte Primary Root CA - G2" # Issuer: CN=thawte Primary Root CA - G2,OU="(c) 2007 thawte, Inc. - For authorized use only",O="thawte, Inc.",C=US @@ -11276,6 +10847,7 @@ CKA_VALUE MULTILINE_OCTAL \034\302\171\334\166\051\257\316\305\054\144\004\136\210\066\156 \061\324\100\032\142\064\066\077\065\001\256\254\143\240 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "thawte Primary Root CA - G3" # Issuer: CN=thawte Primary Root CA - G3,OU="(c) 2008 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US @@ -11411,6 +10983,7 @@ CKA_VALUE MULTILINE_OCTAL \254\076\250\201\022\320\313\272\320\222\013\266\236\226\252\004 \017\212 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GeoTrust Primary Certification Authority - G2" # Issuer: CN=GeoTrust Primary Certification Authority - G2,OU=(c) 2007 GeoTrust Inc. - For authorized use only,O=GeoTrust Inc.,C=US @@ -11580,6 +11153,7 @@ CKA_VALUE MULTILINE_OCTAL \377\303\125\210\203\113\357\005\222\006\161\362\270\230\223\267 \354\315\202\141\361\070\346\117\227\230\052\132\215 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "VeriSign Universal Root Certification Authority" # Issuer: CN=VeriSign Universal Root Certification Authority,OU="(c) 2008 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -11734,6 +11308,7 @@ CKA_VALUE MULTILINE_OCTAL \051\337\033\052\141\173\161\321\336\363\300\345\015\072\112\252 \055\247\330\206\052\335\056\020 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "VeriSign Class 3 Public Primary Certification Authority - G4" # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4,OU="(c) 2007 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -11893,6 +11468,7 @@ CKA_VALUE MULTILINE_OCTAL \264\056\165\225\200\121\152\113\060\246\260\142\241\223\361\233 \330\316\304\143\165\077\131\107\261 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "NetLock Arany (Class Gold) FÅ‘tanúsÃtvány" # Issuer: CN=NetLock Arany (Class Gold) F..tan..s..tv..ny,OU=Tan..s..tv..nykiad..k (Certification Services),O=NetLock Kft.,L=Budapest,C=HU @@ -12066,6 +11642,7 @@ CKA_VALUE MULTILINE_OCTAL \203\213\235\036\322\122\244\314\035\157\260\230\155\224\061\265 \370\161\012\334\271\374\175\062\140\346\353\257\212\001 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Staat der Nederlanden Root CA - G2" # Issuer: CN=Staat der Nederlanden Root CA - G2,O=Staat der Nederlanden,C=NL @@ -12191,6 +11768,7 @@ CKA_VALUE MULTILINE_OCTAL \237\123\330\103\016\135\326\143\202\161\035\200\164\312\366\342 \002\153\331\132 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Hongkong Post Root CA 1" # Issuer: CN=Hongkong Post Root CA 1,O=Hongkong Post,C=HK @@ -12321,6 +11899,7 @@ CKA_VALUE MULTILINE_OCTAL \101\047\111\100\356\336\346\043\104\071\334\241\042\326\272\003 \362 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "SecureSign RootCA11" # Issuer: CN=SecureSign RootCA11,O="Japan Certification Services, Inc.",C=JP @@ -12486,6 +12065,7 @@ CKA_VALUE MULTILINE_OCTAL \147\116\151\206\103\223\070\373\266\333\117\203\221\324\140\176 \113\076\053\070\007\125\230\136\244 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "ACEDICOM Root" # Issuer: C=ES,O=EDICOM,OU=PKI,CN=ACEDICOM Root @@ -12632,6 +12212,7 @@ CKA_VALUE MULTILINE_OCTAL \034\303\165\106\256\065\005\246\366\134\075\041\356\126\360\311 \202\042\055\172\124\253\160\303\175\042\145\202\160\226 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Microsec e-Szigno Root CA 2009" # Issuer: E=info@e-szigno.hu,CN=Microsec e-Szigno Root CA 2009,O=Microsec Ltd.,L=Budapest,C=HU @@ -12763,6 +12344,7 @@ CKA_VALUE MULTILINE_OCTAL \316\323\142\120\145\036\353\222\227\203\061\331\263\265\312\107 \130\077\137 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "GlobalSign Root CA - R3" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R3 @@ -12935,6 +12517,7 @@ CKA_VALUE MULTILINE_OCTAL \214\263\042\350\113\174\125\306\235\372\243\024\273\145\205\156 \156\117\022\176\012\074\235\225 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Autoridad de Certificacion Firmaprofesional CIF A62634068" # Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068,C=ES @@ -13103,6 +12686,7 @@ CKA_VALUE MULTILINE_OCTAL \377\356\336\200\330\055\321\070\325\136\055\013\230\175\076\154 \333\374\046\210\307 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Izenpe.com" # Issuer: CN=Izenpe.com,O=IZENPE S.A.,C=ES @@ -13307,6 +12891,7 @@ CKA_VALUE MULTILINE_OCTAL \006\274\046\020\155\067\235\354\335\170\214\174\200\305\360\331 \167\110\320 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Chambers of Commerce Root - 2008" # Issuer: CN=Chambers of Commerce Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU @@ -13515,6 +13100,7 @@ CKA_VALUE MULTILINE_OCTAL \043\167\330\106\113\171\155\366\214\355\072\177\140\021\170\364 \351\233\256\325\124\300\164\200\321\013\102\237\301 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Global Chambersign Root - 2008" # Issuer: CN=Global Chambersign Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU @@ -15381,6 +14967,7 @@ CKA_VALUE MULTILINE_OCTAL \026\262\103\011\014\115\366\247\153\264\231\204\145\312\172\210 \342\342\104\276\134\367\352\034\365 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Go Daddy Root Certificate Authority - G2" # Issuer: CN=Go Daddy Root Certificate Authority - G2,O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US @@ -15530,6 +15117,7 @@ CKA_VALUE MULTILINE_OCTAL \241\365\146\005\056\177\071\025\251\052\373\120\213\216\205\151 \364 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Starfield Root Certificate Authority - G2" # Issuer: CN=Starfield Root Certificate Authority - G2,O="Starfield Technologies, Inc.",L=Scottsdale,ST=Arizona,C=US @@ -15681,6 +15269,7 @@ CKA_VALUE MULTILINE_OCTAL \157\002\213\147\015\115\046\127\161\332\040\374\301\112\120\215 \261\050\272 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Starfield Services Root Certificate Authority - G2" # Issuer: CN=Starfield Services Root Certificate Authority - G2,O="Starfield Technologies, Inc.",L=Scottsdale,ST=Arizona,C=US @@ -15811,6 +15400,7 @@ CKA_VALUE MULTILINE_OCTAL \236\132\116\145\265\224\256\033\337\051\260\026\361\277\000\236 \007\072\027\144\265\004\265\043\041\231\012\225\073\227\174\357 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AffirmTrust Commercial" # Issuer: CN=AffirmTrust Commercial,O=AffirmTrust,C=US @@ -15936,6 +15526,7 @@ CKA_VALUE MULTILINE_OCTAL \307\167\257\144\250\223\337\366\151\203\202\140\362\111\102\064 \355\132\000\124\205\034\026\066\222\014\134\372\246\255\277\333 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AffirmTrust Networking" # Issuer: CN=AffirmTrust Networking,O=AffirmTrust,C=US @@ -16093,6 +15684,7 @@ CKA_VALUE MULTILINE_OCTAL \200\064\375\277\357\006\243\335\130\305\205\075\076\217\376\236 \051\340\266\270\011\150\031\034\030\103 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AffirmTrust Premium" # Issuer: CN=AffirmTrust Premium,O=AffirmTrust,C=US @@ -16198,6 +15790,7 @@ CKA_VALUE MULTILINE_OCTAL \157\256\144\372\130\345\213\036\343\143\276\265\201\315\157\002 \214\171 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "AffirmTrust Premium ECC" # Issuer: CN=AffirmTrust Premium ECC,O=AffirmTrust,C=US @@ -16336,6 +15929,7 @@ CKA_VALUE MULTILINE_OCTAL \013\047\002\065\051\261\100\225\347\371\350\234\125\210\031\106 \326\267\064\365\176\316\071\232\331\070\361\121\367\117\054 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Certum Trusted Network CA" # Issuer: CN=Certum Trusted Network CA,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL @@ -16505,6 +16099,7 @@ CKA_VALUE MULTILINE_OCTAL \331\027\026\026\012\053\206\337\217\001\031\032\345\273\202\143 \377\276\013\166\026\136\067\067\346\330\164\227\242\231\105\171 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Certinomis - Autorité Racine" # Issuer: CN=Certinomis - Autorit.. Racine,OU=0002 433998903,O=Certinomis,C=FR @@ -16639,6 +16234,7 @@ CKA_VALUE MULTILINE_OCTAL \142\047\254\145\042\327\323\074\306\345\216\262\123\314\111\316 \274\060\376\173\016\063\220\373\355\322\024\221\037\007\257 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "TWCA Root Certification Authority" # Issuer: CN=TWCA Root Certification Authority,OU=Root CA,O=TAIWAN-CA,C=TW @@ -18029,6 +17625,7 @@ CKA_VALUE MULTILINE_OCTAL \112\071\321\005\111\013\247\266\067\201\245\135\214\252\063\136 \201\050\174\247\175\047\353\000\256\215\067 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Security Communication RootCA2" # Issuer: OU=Security Communication RootCA2,O="SECOM Trust Systems CO.,LTD.",C=JP @@ -18211,6 +17808,7 @@ CKA_VALUE MULTILINE_OCTAL \234\235\245\140\225\072\122\177\365\321\253\010\156\363\356\133 \371\210\075\176\270\157\156\003\344\102 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "EC-ACC" # Issuer: CN=EC-ACC,OU=Jerarquia Entitats de Certificacio Catalanes,OU=Vegeu https://www.catcert.net/verarrel (c)03,OU=Serveis Publics de Certificacio,O=Agencia Catalana de Certificacio (NIF Q-0801176-I),C=ES @@ -18373,6 +17971,7 @@ CKA_VALUE MULTILINE_OCTAL \227\265\235\232\231\115\260\074\370\112\000\233\144\335\237\071 \113\321\047\327\270 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for Certificate "Hellenic Academic and Research Institutions RootCA 2011" # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR @@ -18608,6 +18207,7 @@ CKA_VALUE MULTILINE_OCTAL \056\163\352\146\050\170\315\035\024\277\240\217\057\056\270\056 \216\362\024\212\314\351\265\174\373\154\235\014\245\341\226 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Actalis Authentication Root CA" # Issuer: CN=Actalis Authentication Root CA,O=Actalis S.p.A./03358520967,L=Milan,C=IT @@ -18738,6 +18338,7 @@ CKA_VALUE MULTILINE_OCTAL \373\072\162\035\315\366\045\210\036\227\314\041\234\051\001\015 \145\353\127\331\363\127\226\273\110\315\201 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Trustis FPS Root CA" # Issuer: OU=Trustis FPS Root CA,O=Trustis Limited,C=GB @@ -18938,6 +18539,7 @@ CKA_VALUE MULTILINE_OCTAL \266\323\173\002\366\343\270\324\011\156\153\236\165\204\071\346 \177\045\245\362\110\000\300\244\001\332\077 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "StartCom Certification Authority" # Issuer: CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL @@ -19102,6 +18704,7 @@ CKA_VALUE MULTILINE_OCTAL \301\332\070\133\343\251\352\346\241\272\171\357\163\330\266\123 \127\055\366\320\341\327\110 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "StartCom Certification Authority G2" # Issuer: CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL @@ -19261,6 +18864,7 @@ CKA_VALUE MULTILINE_OCTAL \143\135\132\130\342\057\343\035\344\251\326\320\012\320\236\277 \327\201\011\361\311\307\046\015\254\230\026\126\240 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Buypass Class 2 Root CA" # Issuer: CN=Buypass Class 2 Root CA,O=Buypass AS-983163327,C=NO @@ -19419,6 +19023,7 @@ CKA_VALUE MULTILINE_OCTAL \343\370\073\273\334\115\327\144\362\121\276\346\252\253\132\351 \061\356\006\274\163\277\023\142\012\237\307\271\227 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Buypass Class 3 Root CA" # Issuer: CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO @@ -19560,6 +19165,7 @@ CKA_VALUE MULTILINE_OCTAL \321\106\232\073\074\170\270\157\241\320\015\144\242\170\036\051 \116\223\303\244\124\024\133 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "T-TeleSec GlobalRoot Class 3" # Issuer: CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE @@ -19708,6 +19314,7 @@ CKA_VALUE MULTILINE_OCTAL \031\120\211\140\314\351\044\225\017\302\313\035\362\157\166\220 \307\314\165\301\226\305\235 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "EE Certification Centre Root CA" # Issuer: E=pki@sk.ee,CN=EE Certification Centre Root CA,O=AS Sertifitseerimiskeskus,C=EE @@ -19937,6 +19544,7 @@ CKA_VALUE MULTILINE_OCTAL \062\015\135\010\125\164\377\214\230\320\012\246\204\152\321\071 \175 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "TURKTRUST Certificate Services Provider Root 2007" # Issuer: O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A...,L=Ankara,C=TR,CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. @@ -20085,6 +19693,7 @@ CKA_VALUE MULTILINE_OCTAL \046\210\160\327\352\221\315\076\271\312\300\220\156\132\306\136 \164\145\327\134\376\243\342 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "D-TRUST Root Class 3 CA 2 2009" # Issuer: CN=D-TRUST Root Class 3 CA 2 2009,O=D-Trust GmbH,C=DE @@ -20228,6 +19837,7 @@ CKA_VALUE MULTILINE_OCTAL \075\323\056\243\025\274\250\346\046\345\157\303\334\270\003\041 \352\237\026\361\054\124\265 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "D-TRUST Root Class 3 CA 2 EV 2009" # Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009,O=D-Trust GmbH,C=DE @@ -20477,6 +20087,7 @@ CKA_VALUE MULTILINE_OCTAL \316\035\222\233\321\151\263\377\277\361\222\012\141\065\077\335 \376\206\364\274\340\032\161\263\142\246 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "PSCProcert" # Issuer: E=acraiz@suscerte.gob.ve,OU=Superintendencia de Servicios de Certificacion Electronica,O=Sistema Nacional de Certificacion Electronica,ST=Distrito Capital,L=Caracas,C=VE,CN=Autoridad de Certificacion Raiz del Estado Venezolano @@ -20635,6 +20246,7 @@ CKA_VALUE MULTILINE_OCTAL \126\254\366\267\355\057\233\041\051\307\070\266\225\304\004\362 \303\055\375\024\052\220\231\271\007\314\237 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "China Internet Network Information Center EV Certificates Root" # Issuer: CN=China Internet Network Information Center EV Certificates Root,O=China Internet Network Information Center,C=CN @@ -20810,6 +20422,7 @@ CKA_VALUE MULTILINE_OCTAL \311\051\041\123\234\046\105\252\023\027\344\347\315\170\342\071 \301\053\022\236\246\236\033\305\346\016\331\061\331 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Swisscom Root CA 2" # Issuer: CN=Swisscom Root CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch @@ -20985,6 +20598,7 @@ CKA_VALUE MULTILINE_OCTAL \043\355\244\263\035\026\162\103\113\040\341\131\176\302\350\255 \046\277\242\367 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Swisscom Root EV CA 2" # Issuer: CN=Swisscom Root EV CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch @@ -21149,6 +20763,7 @@ CKA_VALUE MULTILINE_OCTAL \016\353\264\261\274\267\114\311\153\277\241\363\331\364\355\342 \360\343\355\144\236\075\057\226\122\117\200\123\213 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "CA Disig Root R1" # Issuer: CN=CA Disig Root R1,O=Disig a.s.,L=Bratislava,C=SK @@ -21311,6 +20926,7 @@ CKA_VALUE MULTILINE_OCTAL \044\304\123\031\351\036\051\025\357\346\155\260\177\055\147\375 \363\154\033\165\106\243\345\112\027\351\244\327\013 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "CA Disig Root R2" # Issuer: CN=CA Disig Root R2,O=Disig a.s.,L=Bratislava,C=SK @@ -21510,6 +21126,7 @@ CKA_VALUE MULTILINE_OCTAL \302\130\200\033\240\227\241\374\131\215\351\021\366\321\017\113 \125\064\106\052\213\206\073 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "ACCVRAIZ1" # Issuer: C=ES,O=ACCV,OU=PKIACCV,CN=ACCVRAIZ1 @@ -21669,6 +21286,7 @@ CKA_VALUE MULTILINE_OCTAL \311\014\277\317\022\216\027\055\043\150\224\347\253\376\251\262 \053\006\320\004\315 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "TWCA Global Root CA" # Issuer: CN=TWCA Global Root CA,OU=Root CA,O=TAIWAN-CA,C=TW @@ -21825,6 +21443,7 @@ CKA_VALUE MULTILINE_OCTAL \141\124\310\034\272\312\301\312\341\271\040\114\217\072\223\211 \245\240\314\277\323\366\165\244\165\226\155\126 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "TeliaSonera Root CA v1" # Issuer: CN=TeliaSonera Root CA v1,O=TeliaSonera @@ -22012,6 +21631,7 @@ CKA_VALUE MULTILINE_OCTAL \064\277\376\043\227\067\322\071\372\075\015\006\013\264\333\073 \243\253\157\134\035\266\176\350\263\202\064\355\006\134\044 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "E-Tugra Certification Authority" # Issuer: CN=E-Tugra Certification Authority,OU=E-Tugra Sertifikasyon Merkezi,O=E-Tu..ra EBG Bili..im Teknolojileri ve Hizmetleri A....,L=Ankara,C=TR @@ -22160,6 +21780,7 @@ CKA_VALUE MULTILINE_OCTAL \332\320\031\056\252\074\361\373\063\200\166\344\315\255\031\117 \005\047\216\023\241\156\302 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "T-TeleSec GlobalRoot Class 2" # Issuer: CN=T-TeleSec GlobalRoot Class 2,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE @@ -22290,6 +21911,7 @@ CKA_VALUE MULTILINE_OCTAL \052\267\030\076\247\031\331\013\175\261\067\101\102\260\272\140 \035\362\376\011\021\260\360\207\173\247\235 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Atos TrustedRoot 2011" # Issuer: C=DE,O=Atos,CN=Atos TrustedRoot 2011 @@ -22449,6 +22071,7 @@ CKA_VALUE MULTILINE_OCTAL \172\340\113\266\144\226\143\225\204\302\112\315\034\056\044\207 \063\140\345\303 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "QuoVadis Root CA 1 G3" # Issuer: CN=QuoVadis Root CA 1 G3,O=QuoVadis Limited,C=BM @@ -22610,6 +22233,7 @@ CKA_VALUE MULTILINE_OCTAL \261\154\064\311\035\354\110\053\073\170\355\146\304\216\171\151 \203\336\177\214 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "QuoVadis Root CA 2 G3" # Issuer: CN=QuoVadis Root CA 2 G3,O=QuoVadis Limited,C=BM @@ -22771,6 +22395,7 @@ CKA_VALUE MULTILINE_OCTAL \177\175\256\200\365\007\114\266\076\234\161\124\231\004\113\375 \130\371\230\364 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "QuoVadis Root CA 3 G3" # Issuer: CN=QuoVadis Root CA 3 G3,O=QuoVadis Limited,C=BM @@ -22907,6 +22532,7 @@ CKA_VALUE MULTILINE_OCTAL \314\303\177\252\004\047\273\323\167\270\142\333\027\174\234\050 \042\023\163\154\317\046\365\212\051\347 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "DigiCert Assured ID Root G2" # Issuer: CN=DigiCert Assured ID Root G2,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -23024,6 +22650,7 @@ CKA_VALUE MULTILINE_OCTAL \136\221\023\247\335\244\156\222\314\062\326\365\041\146\307\057 \352\226\143\152\145\105\222\225\001\264 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "DigiCert Assured ID Root G3" # Issuer: CN=DigiCert Assured ID Root G3,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -23162,6 +22789,7 @@ CKA_VALUE MULTILINE_OCTAL \166\356\074\215\304\135\126\133\242\331\146\156\263\065\067\345 \062\266 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "DigiCert Global Root G2" # Issuer: CN=DigiCert Global Root G2,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -23279,6 +22907,7 @@ CKA_VALUE MULTILINE_OCTAL \053\250\232\251\212\305\321\000\275\370\124\342\232\345\133\174 \263\047\027 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "DigiCert Global Root G3" # Issuer: CN=DigiCert Global Root G3,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -23449,6 +23078,7 @@ CKA_VALUE MULTILINE_OCTAL \336\214\201\041\255\007\020\107\021\255\207\075\007\321\165\274 \317\363\146\176 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "DigiCert Trusted Root G4" # Issuer: CN=DigiCert Trusted Root G4,OU=www.digicert.com,O=DigiCert Inc,C=US @@ -23615,6 +23245,7 @@ CKA_VALUE MULTILINE_OCTAL \376\314\040\164\243\055\251\056\153\313\300\202\021\041\265\223 \171\356\104\206\276\327\036\344\036\373 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "WoSign" # Issuer: CN=Certification Authority of WoSign,O=WoSign CA Limited,C=CN @@ -23776,6 +23407,7 @@ CKA_VALUE MULTILINE_OCTAL \330\253\361\002\142\301\261\176\125\141\317\023\327\046\260\327 \234\313\051\213\070\112\013\016\220\215\272\241 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "WoSign China" # Issuer: CN=CA ...............,O=WoSign CA Limited,C=CN @@ -23952,6 +23584,7 @@ CKA_VALUE MULTILINE_OCTAL \265\024\151\146\016\202\347\315\316\310\055\246\121\177\041\301 \065\123\205\006\112\135\237\255\273\033\137\164 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "COMODO RSA Certification Authority" # Issuer: CN=COMODO RSA Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB @@ -24133,6 +23766,7 @@ CKA_VALUE MULTILINE_OCTAL \216\074\103\152\035\247\030\336\175\075\026\361\142\371\312\220 \250\375 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "USERTrust RSA Certification Authority" # Issuer: CN=USERTrust RSA Certification Authority,O=The USERTRUST Network,L=Jersey City,ST=New Jersey,C=US @@ -24261,6 +23895,7 @@ CKA_VALUE MULTILINE_OCTAL \242\106\201\210\152\072\106\321\251\233\115\311\141\332\321\135 \127\152\030 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "USERTrust ECC Certification Authority" # Issuer: CN=USERTrust ECC Certification Authority,O=The USERTRUST Network,L=Jersey City,ST=New Jersey,C=US @@ -24372,6 +24007,7 @@ CKA_VALUE MULTILINE_OCTAL \322\267\156\033\002\000\027\252\147\246\025\221\336\372\224\354 \173\013\370\237\204 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "GlobalSign ECC Root CA - R4" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign ECC Root CA - R4 @@ -24484,6 +24120,7 @@ CKA_VALUE MULTILINE_OCTAL \307\014\274\247\141\151\361\367\073\341\052\313\371\053\363\146 \220\067 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "GlobalSign ECC Root CA - R5" # Issuer: CN=GlobalSign,O=GlobalSign,OU=GlobalSign ECC Root CA - R5 @@ -24658,6 +24295,7 @@ CKA_VALUE MULTILINE_OCTAL \013\344\271\257\221\373\120\114\014\272\300\044\047\321\025\333 \145\110\041\012\057\327\334\176\240\314\145\176\171 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "VeriSign-C3SSA-G2-temporary-intermediate-after-1024bit-removal" # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US @@ -24829,6 +24467,7 @@ CKA_VALUE MULTILINE_OCTAL \254\035\152\335\071\151\344\341\171\170\276\316\005\277\241\014 \367\200\173\041\147\047\060\131 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Staat der Nederlanden Root CA - G3" # Issuer: CN=Staat der Nederlanden Root CA - G3,O=Staat der Nederlanden,C=NL @@ -24992,6 +24631,7 @@ CKA_VALUE MULTILINE_OCTAL \220\003\244\352\044\207\077\331\275\331\351\362\137\120\111\034 \356\354\327\056 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Staat der Nederlanden EV Root CA" # Issuer: CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL @@ -25153,6 +24793,7 @@ CKA_VALUE MULTILINE_OCTAL \037\220\032\325\112\234\356\321\160\154\314\356\364\127\370\030 \272\204\156\207 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "IdenTrust Commercial Root CA 1" # Issuer: CN=IdenTrust Commercial Root CA 1,O=IdenTrust,C=US @@ -25314,6 +24955,7 @@ CKA_VALUE MULTILINE_OCTAL \113\034\144\347\374\346\153\220\335\151\175\151\375\000\126\245 \267\254\266\255\267\312\076\001\357\234 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "IdenTrust Public Sector Root CA 1" # Issuer: CN=IdenTrust Public Sector Root CA 1,O=IdenTrust,C=US @@ -25458,6 +25100,7 @@ CKA_VALUE MULTILINE_OCTAL \052\062\215\241\342\072\321\020\040\042\071\175\064\105\157\161 \073\303\035\374\377\262\117\250\342\366\060\036 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "S-TRUST Universal Root CA" # Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE @@ -25620,6 +25263,7 @@ CKA_VALUE MULTILINE_OCTAL \261\211\241\177\164\203\232\111\327\334\116\173\212\110\157\213 \105\366 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Entrust Root Certification Authority - G2" # Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US @@ -25764,6 +25408,7 @@ CKA_VALUE MULTILINE_OCTAL \216\046\010\350\174\222\150\155\163\330\157\046\254\041\002\270 \231\267\046\101\133\045\140\256\320\110\032\356\006 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Entrust Root Certification Authority - EC1" # Issuer: CN=Entrust Root Certification Authority - EC1,OU="(c) 2012 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US @@ -25936,6 +25581,7 @@ CKA_VALUE MULTILINE_OCTAL \226\017\112\065\347\116\102\300\165\315\007\317\346\054\353\173 \056 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "CFCA EV ROOT" # Issuer: CN=CFCA EV ROOT,O=China Financial Certification Authority,C=CN @@ -26233,6 +25879,7 @@ CKA_VALUE MULTILINE_OCTAL \261\312\161\115\023\027\071\046\305\051\041\053\223\051\152\226 \372\253\101\341\113\266\065\013\300\233\025 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H5" # Issuer: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H5,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR @@ -26277,166 +25924,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # -# Certificate "TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H6" -# -# Issuer: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR -# Serial Number:7d:a1:f2:65:ec:8a -# Subject: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR -# Not Valid Before: Wed Dec 18 09:04:10 2013 -# Not Valid After : Sat Dec 16 09:04:10 2023 -# Fingerprint (SHA-256): 8D:E7:86:55:E1:BE:7F:78:47:80:0B:93:F6:94:D2:1D:36:8C:C0:6E:03:3E:7F:AB:04:BB:5E:B9:9D:A6:B7:00 -# Fingerprint (SHA1): 8A:5C:8C:EE:A5:03:E6:05:56:BA:D8:1B:D4:F6:C9:B0:ED:E5:2F:E0 -CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H6" -CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 -CKA_SUBJECT MULTILINE_OCTAL -\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122 -\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162 -\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122 -\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154 -\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305 -\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040 -\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056 -\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113 -\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153 -\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145 -\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304 -\261\040\110\066 -END -CKA_ID UTF8 "0" -CKA_ISSUER MULTILINE_OCTAL -\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122 -\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162 -\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122 -\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154 -\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305 -\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040 -\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056 -\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113 -\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153 -\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145 -\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304 -\261\040\110\066 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\006\175\241\362\145\354\212 -END -CKA_VALUE MULTILINE_OCTAL -\060\202\004\046\060\202\003\016\240\003\002\001\002\002\006\175 -\241\362\145\354\212\060\015\006\011\052\206\110\206\367\015\001 -\001\013\005\000\060\201\261\061\013\060\011\006\003\125\004\006 -\023\002\124\122\061\017\060\015\006\003\125\004\007\014\006\101 -\156\153\141\162\141\061\115\060\113\006\003\125\004\012\014\104 -\124\303\234\122\113\124\122\125\123\124\040\102\151\154\147\151 -\040\304\260\154\145\164\151\305\237\151\155\040\166\145\040\102 -\151\154\151\305\237\151\155\040\107\303\274\166\145\156\154\151 -\304\237\151\040\110\151\172\155\145\164\154\145\162\151\040\101 -\056\305\236\056\061\102\060\100\006\003\125\004\003\014\071\124 -\303\234\122\113\124\122\125\123\124\040\105\154\145\153\164\162 -\157\156\151\153\040\123\145\162\164\151\146\151\153\141\040\110 -\151\172\155\145\164\040\123\141\304\237\154\141\171\304\261\143 -\304\261\163\304\261\040\110\066\060\036\027\015\061\063\061\062 -\061\070\060\071\060\064\061\060\132\027\015\062\063\061\062\061 -\066\060\071\060\064\061\060\132\060\201\261\061\013\060\011\006 -\003\125\004\006\023\002\124\122\061\017\060\015\006\003\125\004 -\007\014\006\101\156\153\141\162\141\061\115\060\113\006\003\125 -\004\012\014\104\124\303\234\122\113\124\122\125\123\124\040\102 -\151\154\147\151\040\304\260\154\145\164\151\305\237\151\155\040 -\166\145\040\102\151\154\151\305\237\151\155\040\107\303\274\166 -\145\156\154\151\304\237\151\040\110\151\172\155\145\164\154\145 -\162\151\040\101\056\305\236\056\061\102\060\100\006\003\125\004 -\003\014\071\124\303\234\122\113\124\122\125\123\124\040\105\154 -\145\153\164\162\157\156\151\153\040\123\145\162\164\151\146\151 -\153\141\040\110\151\172\155\145\164\040\123\141\304\237\154\141 -\171\304\261\143\304\261\163\304\261\040\110\066\060\202\001\042 -\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 -\202\001\017\000\060\202\001\012\002\202\001\001\000\235\260\150 -\326\350\275\024\226\243\000\012\232\361\364\307\314\221\115\161 -\170\167\271\367\041\046\025\163\121\026\224\011\107\005\342\063 -\365\150\232\065\377\334\113\057\062\307\260\355\342\202\345\157 -\332\332\352\254\306\006\317\045\015\101\201\366\301\070\042\275 -\371\261\245\246\263\001\274\077\120\027\053\366\351\146\125\324 -\063\263\134\370\103\040\170\223\125\026\160\031\062\346\211\327 -\144\353\275\110\120\375\366\320\101\003\302\164\267\375\366\200 -\317\133\305\253\244\326\225\022\233\347\227\023\062\003\351\324 -\253\103\133\026\355\063\042\144\051\266\322\223\255\057\154\330 -\075\266\366\035\016\064\356\322\175\251\125\017\040\364\375\051 -\273\221\133\034\175\306\102\070\155\102\050\155\324\001\373\315 -\210\227\111\176\270\363\203\370\265\230\057\263\047\013\110\136 -\126\347\116\243\063\263\104\326\245\362\030\224\355\034\036\251 -\225\134\142\112\370\015\147\121\251\257\041\325\370\062\235\171 -\272\032\137\345\004\125\115\023\106\377\362\317\164\307\032\143 -\155\303\037\027\022\303\036\020\076\140\010\263\061\002\003\001 -\000\001\243\102\060\100\060\035\006\003\125\035\016\004\026\004 -\024\335\125\027\023\366\254\350\110\041\312\357\265\257\321\000 -\062\355\236\214\265\060\016\006\003\125\035\017\001\001\377\004 -\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004 -\005\060\003\001\001\377\060\015\006\011\052\206\110\206\367\015 -\001\001\013\005\000\003\202\001\001\000\157\130\015\227\103\252 -\026\124\076\277\251\337\222\105\077\205\013\273\126\323\014\122 -\314\310\277\166\147\136\346\252\263\247\357\271\254\264\020\024 -\015\164\176\075\155\255\321\175\320\232\251\245\312\030\073\002 -\100\056\052\234\120\024\213\376\127\176\127\134\021\011\113\066 -\105\122\367\075\254\024\375\104\337\213\227\043\324\303\301\356 -\324\123\225\376\054\112\376\015\160\252\273\213\057\055\313\062 -\243\202\362\124\337\330\362\335\327\110\162\356\112\243\051\226 -\303\104\316\156\265\222\207\166\244\273\364\222\154\316\054\024 -\011\146\216\215\255\026\265\307\033\011\141\073\343\040\242\003 -\200\216\255\176\121\000\116\307\226\206\373\103\230\167\175\050 -\307\217\330\052\156\347\204\157\227\101\051\000\026\136\115\342 -\023\352\131\300\143\147\072\104\373\230\374\004\323\060\162\246 -\366\207\011\127\255\166\246\035\143\232\375\327\145\310\170\203 -\053\165\073\245\133\270\015\135\177\276\043\256\126\125\224\130 -\357\037\201\214\052\262\315\346\233\143\236\030\274\345\153\006 -\264\013\230\113\050\136\257\210\130\313 -END - -# Trust for "TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H6" -# Issuer: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR -# Serial Number:7d:a1:f2:65:ec:8a -# Subject: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H6,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR -# Not Valid Before: Wed Dec 18 09:04:10 2013 -# Not Valid After : Sat Dec 16 09:04:10 2023 -# Fingerprint (SHA-256): 8D:E7:86:55:E1:BE:7F:78:47:80:0B:93:F6:94:D2:1D:36:8C:C0:6E:03:3E:7F:AB:04:BB:5E:B9:9D:A6:B7:00 -# Fingerprint (SHA1): 8A:5C:8C:EE:A5:03:E6:05:56:BA:D8:1B:D4:F6:C9:B0:ED:E5:2F:E0 -CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST -CKA_TOKEN CK_BBOOL CK_TRUE -CKA_PRIVATE CK_BBOOL CK_FALSE -CKA_MODIFIABLE CK_BBOOL CK_FALSE -CKA_LABEL UTF8 "TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H6" -CKA_CERT_SHA1_HASH MULTILINE_OCTAL -\212\134\214\356\245\003\346\005\126\272\330\033\324\366\311\260 -\355\345\057\340 -END -CKA_CERT_MD5_HASH MULTILINE_OCTAL -\370\305\356\052\153\276\225\215\010\367\045\112\352\161\076\106 -END -CKA_ISSUER MULTILINE_OCTAL -\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122 -\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162 -\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122 -\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154 -\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305 -\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040 -\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056 -\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113 -\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153 -\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145 -\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304 -\261\040\110\066 -END -CKA_SERIAL_NUMBER MULTILINE_OCTAL -\002\006\175\241\362\145\354\212 -END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST -CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE - -# # Certificate "Certinomis - Root CA" # # Issuer: CN=Certinomis - Root CA,OU=0002 433998903,O=Certinomis,C=FR @@ -26564,6 +26051,7 @@ CKA_VALUE MULTILINE_OCTAL \210\025\106\317\355\151\065\377\165\015\106\363\316\161\341\305 \153\206\102\006\271\101 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Certinomis - Root CA" # Issuer: CN=Certinomis - Root CA,OU=0002 433998903,O=Certinomis,C=FR @@ -26702,6 +26190,7 @@ CKA_VALUE MULTILINE_OCTAL \313\216\075\103\151\234\232\130\320\044\073\337\033\100\226\176 \065\255\201\307\116\161\272\210\023 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "OISTE WISeKey Global Root GB CA" # Issuer: CN=OISTE WISeKey Global Root GB CA,OU=OISTE Foundation Endorsed,O=WISeKey,C=CH @@ -26836,6 +26325,7 @@ CKA_VALUE MULTILINE_OCTAL \135\107\267\041\362\215\321\012\231\216\343\156\076\255\160\340 \217\271\312\314\156\201\061\366\173\234\172\171\344\147\161\030 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Certification Authority of WoSign G2" # Issuer: CN=Certification Authority of WoSign G2,O=WoSign CA Limited,C=CN @@ -26944,6 +26434,7 @@ CKA_VALUE MULTILINE_OCTAL \177\336\126\364\220\261\025\021\330\262\042\025\320\057\303\046 \056\153\361\221\262\220\145\364\232\346\220\356\112 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "CA WoSign ECC Root" # Issuer: CN=CA WoSign ECC Root,O=WoSign CA Limited,C=CN @@ -27076,6 +26567,7 @@ CKA_VALUE MULTILINE_OCTAL \056\365\251\013\077\324\135\341\317\204\237\342\031\302\137\212 \326\040\036\343\163\267 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "SZAFIR ROOT CA2" # Issuer: CN=SZAFIR ROOT CA2,O=Krajowa Izba Rozliczeniowa S.A.,C=PL @@ -27253,6 +26745,7 @@ CKA_VALUE MULTILINE_OCTAL \103\150\010\152\137\073\360\166\143\373\314\006\054\246\306\342 \016\265\271\276\044\217 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Certum Trusted Network CA 2" # Issuer: CN=Certum Trusted Network CA 2,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL @@ -27439,6 +26932,7 @@ CKA_VALUE MULTILINE_OCTAL \251\220\227\015\255\123\322\132\035\207\152\000\227\145\142\264 \276\157\152\247\365\054\102\355\062\255\266\041\236\276\274 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Hellenic Academic and Research Institutions RootCA 2015" # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR @@ -27574,6 +27068,7 @@ CKA_VALUE MULTILINE_OCTAL \162\041\027\313\042\101\016\214\023\230\070\232\124\155\233\312 \342\174\352\002\130\042\221 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Hellenic Academic and Research Institutions ECC RootCA 2015" # Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015,O=Hellenic Academic and Research Institutions Cert. Authority,L=Athens,C=GR @@ -27738,6 +27233,7 @@ CKA_VALUE MULTILINE_OCTAL \244\335\327\131\364\156\335\376\252\303\221\320\056\102\007\300 \014\115\123\315\044\261\114\133\036\121\364\337\351\222\372 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Certplus Root CA G1" # Issuer: CN=Certplus Root CA G1,O=Certplus,C=FR @@ -27843,6 +27339,7 @@ CKA_VALUE MULTILINE_OCTAL \345\274\371\171\151\334\255\105\053\367\266\061\163\314\006\245 \123\223\221\032\223\256\160\152\147\272\327\236\345\141\032\137 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Certplus Root CA G2" # Issuer: CN=Certplus Root CA G2,O=Certplus,C=FR @@ -28004,6 +27501,7 @@ CKA_VALUE MULTILINE_OCTAL \315\340\103\207\326\344\272\112\303\154\022\177\376\052\346\043 \326\214\161 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "OpenTrust Root CA G1" # Issuer: CN=OpenTrust Root CA G1,O=OpenTrust,C=FR @@ -28166,6 +27664,7 @@ CKA_VALUE MULTILINE_OCTAL \174\053\067\324\172\321\167\064\217\347\371\102\367\074\201\014 \113\122\012 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "OpenTrust Root CA G2" # Issuer: CN=OpenTrust Root CA G2,O=OpenTrust,C=FR @@ -28275,6 +27774,7 @@ CKA_VALUE MULTILINE_OCTAL \342\174\151\345\135\232\370\101\037\073\071\223\223\235\125\352 \315\215\361\373\301 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "OpenTrust Root CA G3" # Issuer: CN=OpenTrust Root CA G3,O=OpenTrust,C=FR @@ -28438,6 +27938,7 @@ CKA_VALUE MULTILINE_OCTAL \317\245\124\064\167\275\354\211\233\351\027\103\337\133\333\137 \376\216\036\127\242\315\100\235\176\142\042\332\336\030\047 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "ISRG Root X1" # Issuer: CN=ISRG Root X1,O=Internet Security Research Group,C=US @@ -28600,6 +28101,7 @@ CKA_VALUE MULTILINE_OCTAL \272\357\060\167\344\124\342\270\204\231\130\200\252\023\213\121 \072\117\110\366\213\266\263 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "AC RAIZ FNMT-RCM" # Issuer: OU=AC RAIZ FNMT-RCM,O=FNMT-RCM,C=ES @@ -28724,6 +28226,7 @@ CKA_VALUE MULTILINE_OCTAL \256\245\321\175\272\020\236\206\154\033\212\271\131\063\370\353 \304\220\276\361\271 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Amazon Root CA 1" # Issuer: CN=Amazon Root CA 1,O=Amazon,C=US @@ -28880,6 +28383,7 @@ CKA_VALUE MULTILINE_OCTAL \137\041\020\307\371\363\272\002\012\047\007\305\361\326\307\323 \340\373\011\140\154 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Amazon Root CA 2" # Issuer: CN=Amazon Root CA 2,O=Amazon,C=US @@ -28979,6 +28483,7 @@ CKA_VALUE MULTILINE_OCTAL \263\226\371\353\306\052\370\266\054\376\072\220\024\026\327\214 \143\044\110\034\337\060\175\325\150\073 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Amazon Root CA 3" # Issuer: CN=Amazon Root CA 3,O=Amazon,C=US @@ -29082,6 +28587,7 @@ CKA_VALUE MULTILINE_OCTAL \324\254\213\153\153\111\022\123\063\255\327\344\276\044\374\265 \012\166\324\245\274\020 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Amazon Root CA 4" # Issuer: CN=Amazon Root CA 4,O=Amazon,C=US @@ -29248,6 +28754,7 @@ CKA_VALUE MULTILINE_OCTAL \334\066\052\341\224\150\223\307\146\162\104\017\200\041\062\154 \045\307\043\200\203\012\353 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "LuxTrust Global Root 2" # Issuer: CN=LuxTrust Global Root 2,O=LuxTrust S.A.,C=LU @@ -29396,6 +28903,7 @@ CKA_VALUE MULTILINE_OCTAL \007\277\164\340\230\070\025\125\170\356\162\000\134\031\243\364 \322\063\340\377\275\321\124\071\051\017 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Symantec Class 1 Public Primary Certification Authority - G6" # Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -29549,6 +29057,7 @@ CKA_VALUE MULTILINE_OCTAL \124\276\142\273\071\254\150\022\110\221\040\245\313\261\335\376 \157\374\132\344\202\125\131\257\061\251 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Symantec Class 2 Public Primary Certification Authority - G6" # Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G6,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -29681,6 +29190,7 @@ CKA_VALUE MULTILINE_OCTAL \046\235\011\075\367\155\220\321\005\104\057\260\274\203\223\150 \362\014\105\111\071\277\231\004\034\323\020\240 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Symantec Class 1 Public Primary Certification Authority - G4" # Issuer: CN=Symantec Class 1 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -29813,6 +29323,7 @@ CKA_VALUE MULTILINE_OCTAL \000\130\123\317\176\261\113\015\345\120\206\353\236\153\337\377 \051\246\330\107\331\240\226\030\333\362\105\263 END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE # Trust for "Symantec Class 2 Public Primary Certification Authority - G4" # Issuer: CN=Symantec Class 2 Public Primary Certification Authority - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US @@ -29854,3 +29365,313 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "D-TRUST Root CA 3 2013" +# +# Issuer: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE +# Serial Number: 1039788 (0xfddac) +# Subject: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE +# Not Valid Before: Fri Sep 20 08:25:51 2013 +# Not Valid After : Wed Sep 20 08:25:51 2028 +# Fingerprint (SHA-256): A1:A8:6D:04:12:1E:B8:7F:02:7C:66:F5:33:03:C2:8E:57:39:F9:43:FC:84:B3:8A:D6:AF:00:90:35:DD:94:57 +# Fingerprint (SHA1): 6C:7C:CC:E7:D4:AE:51:5F:99:08:CD:3F:F6:E8:C3:78:DF:6F:EF:97 +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "D-TRUST Root CA 3 2013" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105\061 +\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165\163 +\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003\014 +\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103\101 +\040\063\040\062\060\061\063 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105\061 +\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165\163 +\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003\014 +\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103\101 +\040\063\040\062\060\061\063 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\003\017\335\254 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\004\016\060\202\002\366\240\003\002\001\002\002\003\017 +\335\254\060\015\006\011\052\206\110\206\367\015\001\001\013\005 +\000\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105 +\061\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165 +\163\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003 +\014\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103 +\101\040\063\040\062\060\061\063\060\036\027\015\061\063\060\071 +\062\060\060\070\062\065\065\061\132\027\015\062\070\060\071\062 +\060\060\070\062\065\065\061\132\060\105\061\013\060\011\006\003 +\125\004\006\023\002\104\105\061\025\060\023\006\003\125\004\012 +\014\014\104\055\124\162\165\163\164\040\107\155\142\110\061\037 +\060\035\006\003\125\004\003\014\026\104\055\124\122\125\123\124 +\040\122\157\157\164\040\103\101\040\063\040\062\060\061\063\060 +\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001 +\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000 +\304\173\102\222\202\037\354\355\124\230\216\022\300\312\011\337 +\223\156\072\223\134\033\344\020\167\236\116\151\210\154\366\341 +\151\362\366\233\242\141\261\275\007\040\164\230\145\361\214\046 +\010\315\250\065\312\200\066\321\143\155\350\104\172\202\303\154 +\136\336\273\350\066\322\304\150\066\214\237\062\275\204\042\340 +\334\302\356\020\106\071\155\257\223\071\256\207\346\303\274\011 +\311\054\153\147\133\331\233\166\165\114\013\340\273\305\327\274 +\076\171\362\137\276\321\220\127\371\256\366\146\137\061\277\323 +\155\217\247\272\112\363\043\145\273\267\357\243\045\327\012\352 +\130\266\357\210\372\372\171\262\122\130\325\360\254\214\241\121 +\164\051\225\252\121\073\220\062\003\237\034\162\164\220\336\075 +\355\141\322\345\343\375\144\107\345\271\267\112\251\367\037\256 +\226\206\004\254\057\343\244\201\167\267\132\026\377\330\017\077 +\366\267\170\314\244\257\372\133\074\022\133\250\122\211\162\357 +\210\363\325\104\201\206\225\043\237\173\335\274\331\064\357\174 +\224\074\252\300\101\302\343\235\120\032\300\344\031\042\374\263 +\002\003\001\000\001\243\202\001\005\060\202\001\001\060\017\006 +\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060\035 +\006\003\125\035\016\004\026\004\024\077\220\310\175\307\025\157 +\363\044\217\251\303\057\113\242\017\041\262\057\347\060\016\006 +\003\125\035\017\001\001\377\004\004\003\002\001\006\060\201\276 +\006\003\125\035\037\004\201\266\060\201\263\060\164\240\162\240 +\160\206\156\154\144\141\160\072\057\057\144\151\162\145\143\164 +\157\162\171\056\144\055\164\162\165\163\164\056\156\145\164\057 +\103\116\075\104\055\124\122\125\123\124\045\062\060\122\157\157 +\164\045\062\060\103\101\045\062\060\063\045\062\060\062\060\061 +\063\054\117\075\104\055\124\162\165\163\164\045\062\060\107\155 +\142\110\054\103\075\104\105\077\143\145\162\164\151\146\151\143 +\141\164\145\162\145\166\157\143\141\164\151\157\156\154\151\163 +\164\060\073\240\071\240\067\206\065\150\164\164\160\072\057\057 +\143\162\154\056\144\055\164\162\165\163\164\056\156\145\164\057 +\143\162\154\057\144\055\164\162\165\163\164\137\162\157\157\164 +\137\143\141\137\063\137\062\060\061\063\056\143\162\154\060\015 +\006\011\052\206\110\206\367\015\001\001\013\005\000\003\202\001 +\001\000\016\131\016\130\344\164\110\043\104\317\064\041\265\234 +\024\032\255\232\113\267\263\210\155\134\251\027\160\360\052\237 +\215\173\371\173\205\372\307\071\350\020\010\260\065\053\137\317 +\002\322\323\234\310\013\036\356\005\124\256\067\223\004\011\175 +\154\217\302\164\274\370\034\224\276\061\001\100\055\363\044\040 +\267\204\125\054\134\310\365\164\112\020\031\213\243\307\355\065 +\326\011\110\323\016\300\272\071\250\260\106\002\260\333\306\210 +\131\302\276\374\173\261\053\317\176\142\207\125\226\314\001\157 +\233\147\041\225\065\213\370\020\374\161\033\267\113\067\151\246 +\073\326\354\213\356\301\260\363\045\311\217\222\175\241\352\303 +\312\104\277\046\245\164\222\234\343\164\353\235\164\331\313\115 +\207\330\374\264\151\154\213\240\103\007\140\170\227\351\331\223 +\174\302\106\274\233\067\122\243\355\212\074\023\251\173\123\113 +\111\232\021\005\054\013\156\126\254\037\056\202\154\340\151\147 +\265\016\155\055\331\344\300\025\361\077\372\030\162\341\025\155 +\047\133\055\060\050\053\237\110\232\144\053\231\357\362\165\111 +\137\134 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "D-TRUST Root CA 3 2013" +# Issuer: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE +# Serial Number: 1039788 (0xfddac) +# Subject: CN=D-TRUST Root CA 3 2013,O=D-Trust GmbH,C=DE +# Not Valid Before: Fri Sep 20 08:25:51 2013 +# Not Valid After : Wed Sep 20 08:25:51 2028 +# Fingerprint (SHA-256): A1:A8:6D:04:12:1E:B8:7F:02:7C:66:F5:33:03:C2:8E:57:39:F9:43:FC:84:B3:8A:D6:AF:00:90:35:DD:94:57 +# Fingerprint (SHA1): 6C:7C:CC:E7:D4:AE:51:5F:99:08:CD:3F:F6:E8:C3:78:DF:6F:EF:97 +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "D-TRUST Root CA 3 2013" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\154\174\314\347\324\256\121\137\231\010\315\077\366\350\303\170 +\337\157\357\227 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\267\042\146\230\176\326\003\340\301\161\346\165\315\126\105\277 +END +CKA_ISSUER MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\104\105\061 +\025\060\023\006\003\125\004\012\014\014\104\055\124\162\165\163 +\164\040\107\155\142\110\061\037\060\035\006\003\125\004\003\014 +\026\104\055\124\122\125\123\124\040\122\157\157\164\040\103\101 +\040\063\040\062\060\061\063 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\003\017\335\254 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR +# Serial Number: 1 (0x1) +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR +# Not Valid Before: Mon Nov 25 08:25:55 2013 +# Not Valid After : Sun Oct 25 08:25:55 2043 +# Fingerprint (SHA-256): 46:ED:C3:68:90:46:D5:3A:45:3F:B3:10:4A:B8:0D:CA:EC:65:8B:26:60:EA:16:29:DD:7E:86:79:90:64:87:16 +# Fingerprint (SHA1): 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122 +\061\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145 +\040\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003 +\125\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154 +\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157 +\152\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165 +\162\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055 +\060\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145 +\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153 +\145\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060 +\064\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040 +\113\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040 +\123\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165 +\162\165\155\040\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122 +\061\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145 +\040\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003 +\125\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154 +\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157 +\152\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165 +\162\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055 +\060\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145 +\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153 +\145\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060 +\064\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040 +\113\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040 +\123\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165 +\162\165\155\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\004\143\060\202\003\113\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060 +\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122\061 +\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145\040 +\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003\125 +\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154\151 +\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157\152 +\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165\162 +\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055\060 +\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145\162 +\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153\145 +\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060\064 +\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040\113 +\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040\123 +\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165\162 +\165\155\040\061\060\036\027\015\061\063\061\061\062\065\060\070 +\062\065\065\065\132\027\015\064\063\061\060\062\065\060\070\062 +\065\065\065\132\060\201\322\061\013\060\011\006\003\125\004\006 +\023\002\124\122\061\030\060\026\006\003\125\004\007\023\017\107 +\145\142\172\145\040\055\040\113\157\143\141\145\154\151\061\102 +\060\100\006\003\125\004\012\023\071\124\165\162\153\151\171\145 +\040\102\151\154\151\155\163\145\154\040\166\145\040\124\145\153 +\156\157\154\157\152\151\153\040\101\162\141\163\164\151\162\155 +\141\040\113\165\162\165\155\165\040\055\040\124\125\102\111\124 +\101\113\061\055\060\053\006\003\125\004\013\023\044\113\141\155 +\165\040\123\145\162\164\151\146\151\153\141\163\171\157\156\040 +\115\145\162\153\145\172\151\040\055\040\113\141\155\165\040\123 +\115\061\066\060\064\006\003\125\004\003\023\055\124\125\102\111 +\124\101\113\040\113\141\155\165\040\123\115\040\123\123\114\040 +\113\157\153\040\123\145\162\164\151\146\151\153\141\163\151\040 +\055\040\123\165\162\165\155\040\061\060\202\001\042\060\015\006 +\011\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017 +\000\060\202\001\012\002\202\001\001\000\257\165\060\063\252\273 +\153\323\231\054\022\067\204\331\215\173\227\200\323\156\347\377 +\233\120\225\076\220\225\126\102\327\031\174\046\204\215\222\372 +\001\035\072\017\342\144\070\267\214\274\350\210\371\213\044\253 +\056\243\365\067\344\100\216\030\045\171\203\165\037\073\377\154 +\250\305\306\126\370\264\355\212\104\243\253\154\114\374\035\320 +\334\357\150\275\317\344\252\316\360\125\367\242\064\324\203\153 +\067\174\034\302\376\265\003\354\127\316\274\264\265\305\355\000 +\017\123\067\052\115\364\117\014\203\373\206\317\313\376\214\116 +\275\207\371\247\213\041\127\234\172\337\003\147\211\054\235\227 +\141\247\020\270\125\220\177\016\055\047\070\164\337\347\375\332 +\116\022\343\115\025\042\002\310\340\340\374\017\255\212\327\311 +\124\120\314\073\017\312\026\200\204\320\121\126\303\216\126\177 +\211\042\063\057\346\205\012\275\245\250\033\066\336\323\334\054 +\155\073\307\023\275\131\043\054\346\345\244\367\330\013\355\352 +\220\100\104\250\225\273\223\325\320\200\064\266\106\170\016\037 +\000\223\106\341\356\351\371\354\117\027\002\003\001\000\001\243 +\102\060\100\060\035\006\003\125\035\016\004\026\004\024\145\077 +\307\212\206\306\074\335\074\124\134\065\370\072\355\122\014\107 +\127\310\060\016\006\003\125\035\017\001\001\377\004\004\003\002 +\001\006\060\017\006\003\125\035\023\001\001\377\004\005\060\003 +\001\001\377\060\015\006\011\052\206\110\206\367\015\001\001\013 +\005\000\003\202\001\001\000\052\077\341\361\062\216\256\341\230 +\134\113\136\317\153\036\152\011\322\042\251\022\307\136\127\175 +\163\126\144\200\204\172\223\344\011\271\020\315\237\052\047\341 +\000\167\276\110\310\065\250\201\237\344\270\054\311\177\016\260 +\322\113\067\135\352\271\325\013\136\064\275\364\163\051\303\355 +\046\025\234\176\010\123\212\130\215\320\113\050\337\301\263\337 +\040\363\371\343\343\072\337\314\234\224\330\116\117\303\153\027 +\267\367\162\350\255\146\063\265\045\123\253\340\370\114\251\235 +\375\362\015\272\256\271\331\252\306\153\371\223\273\256\253\270 +\227\074\003\032\272\103\306\226\271\105\162\070\263\247\241\226 +\075\221\173\176\300\041\123\114\207\355\362\013\124\225\121\223 +\325\042\245\015\212\361\223\016\076\124\016\260\330\311\116\334 +\362\061\062\126\352\144\371\352\265\235\026\146\102\162\363\177 +\323\261\061\103\374\244\216\027\361\155\043\253\224\146\370\255 +\373\017\010\156\046\055\177\027\007\011\262\214\373\120\300\237 +\226\215\317\266\375\000\235\132\024\232\277\002\104\365\301\302 +\237\042\136\242\017\241\343 +END +CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE + +# Trust for "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR +# Serial Number: 1 (0x1) +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1,OU=Kamu Sertifikasyon Merkezi - Kamu SM,O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK,L=Gebze - Kocaeli,C=TR +# Not Valid Before: Mon Nov 25 08:25:55 2013 +# Not Valid After : Sun Oct 25 08:25:55 2043 +# Fingerprint (SHA-256): 46:ED:C3:68:90:46:D5:3A:45:3F:B3:10:4A:B8:0D:CA:EC:65:8B:26:60:EA:16:29:DD:7E:86:79:90:64:87:16 +# Fingerprint (SHA1): 31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA +CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\061\103\144\233\354\316\047\354\355\072\077\013\217\015\344\350 +\221\335\356\312 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\334\000\201\334\151\057\076\057\260\073\366\075\132\221\216\111 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\322\061\013\060\011\006\003\125\004\006\023\002\124\122 +\061\030\060\026\006\003\125\004\007\023\017\107\145\142\172\145 +\040\055\040\113\157\143\141\145\154\151\061\102\060\100\006\003 +\125\004\012\023\071\124\165\162\153\151\171\145\040\102\151\154 +\151\155\163\145\154\040\166\145\040\124\145\153\156\157\154\157 +\152\151\153\040\101\162\141\163\164\151\162\155\141\040\113\165 +\162\165\155\165\040\055\040\124\125\102\111\124\101\113\061\055 +\060\053\006\003\125\004\013\023\044\113\141\155\165\040\123\145 +\162\164\151\146\151\153\141\163\171\157\156\040\115\145\162\153 +\145\172\151\040\055\040\113\141\155\165\040\123\115\061\066\060 +\064\006\003\125\004\003\023\055\124\125\102\111\124\101\113\040 +\113\141\155\165\040\123\115\040\123\123\114\040\113\157\153\040 +\123\145\162\164\151\146\151\153\141\163\151\040\055\040\123\165 +\162\165\155\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE diff --git a/nss/lib/ckfw/builtins/nssckbi.h b/nss/lib/ckfw/builtins/nssckbi.h index 4f1e357..6e7aa2b 100644 --- a/nss/lib/ckfw/builtins/nssckbi.h +++ b/nss/lib/ckfw/builtins/nssckbi.h @@ -22,31 +22,32 @@ * to the list of trusted certificates. * * The NSS_BUILTINS_LIBRARY_VERSION_MINOR macro needs to be bumped - * for each NSS minor release AND whenever we change the list of - * trusted certificates. 10 minor versions are allocated for each - * NSS 3.x branch as follows, allowing us to change the list of - * trusted certificates up to 9 times on each branch. - * - NSS 3.5 branch: 3-9 - * - NSS 3.6 branch: 10-19 - * - NSS 3.7 branch: 20-29 - * - NSS 3.8 branch: 30-39 - * - NSS 3.9 branch: 40-49 - * - NSS 3.10 branch: 50-59 - * - NSS 3.11 branch: 60-69 - * ... - * - NSS 3.12 branch: 70-89 - * - NSS 3.13 branch: 90-99 - * - NSS 3.14 branch: 100-109 - * ... - * - NSS 3.29 branch: 250-255 + * whenever we change the list of trusted certificates. + * + * Please use the following rules when increasing the version number: + * + * - starting with version 2.14, NSS_BUILTINS_LIBRARY_VERSION_MINOR + * must always be an EVEN number (e.g. 16, 18, 20 etc.) + * + * - whenever possible, if older branches require a modification to the + * list, these changes should be made on the main line of development (trunk), + * and the older branches should update to the most recent list. + * + * - ODD minor version numbers are reserved to indicate a snapshot that has + * deviated from the main line of development, e.g. if it was necessary + * to modify the list on a stable branch. + * Once the version has been changed to an odd number (e.g. 2.13) on a branch, + * it should remain unchanged on that branch, even if further changes are + * made on that branch. * * NSS_BUILTINS_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear * whether we may use its full range (0-255) or only 0-99 because * of the comment in the CK_VERSION type definition. + * It's recommend to switch back to 0 after having reached version 98/99. */ #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2 -#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 11 -#define NSS_BUILTINS_LIBRARY_VERSION "2.11" +#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 14 +#define NSS_BUILTINS_LIBRARY_VERSION "2.14" /* These version numbers detail the semantic changes to the ckfw engine. */ #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 diff --git a/nss/lib/cryptohi/dsautil.c b/nss/lib/cryptohi/dsautil.c index db397df..df4d9a9 100644 --- a/nss/lib/cryptohi/dsautil.c +++ b/nss/lib/cryptohi/dsautil.c @@ -166,12 +166,16 @@ static SECItem * common_DecodeDerSig(const SECItem *item, unsigned int len) { SECItem *result = NULL; + PORTCheapArenaPool arena; SECStatus status; DSA_ASN1Signature sig; SECItem dst; PORT_Memset(&sig, 0, sizeof(sig)); + /* Make enough room for r + s. */ + PORT_InitCheapArena(&arena, PR_MAX(2 * MAX_ECKEY_LEN, DSA_MAX_SIGNATURE_LEN)); + result = PORT_ZNew(SECItem); if (result == NULL) goto loser; @@ -183,7 +187,7 @@ common_DecodeDerSig(const SECItem *item, unsigned int len) sig.r.type = siUnsignedInteger; sig.s.type = siUnsignedInteger; - status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item); + status = SEC_QuickDERDecodeItem(&arena.arena, &sig, DSA_SignatureTemplate, item); if (status != SECSuccess) goto loser; @@ -202,10 +206,7 @@ common_DecodeDerSig(const SECItem *item, unsigned int len) goto loser; done: - if (sig.r.data != NULL) - PORT_Free(sig.r.data); - if (sig.s.data != NULL) - PORT_Free(sig.s.data); + PORT_DestroyCheapArena(&arena); return result; diff --git a/nss/lib/cryptohi/keyi.h b/nss/lib/cryptohi/keyi.h index 374a4ad..f8f5f7f 100644 --- a/nss/lib/cryptohi/keyi.h +++ b/nss/lib/cryptohi/keyi.h @@ -17,13 +17,6 @@ KeyType seckey_GetKeyType(SECOidTag pubKeyOid); SECStatus sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg); -/* - * Set the point encoding of a SECKEYPublicKey from the OID. - * This has to be called on any SECKEYPublicKey holding a SECKEYECPublicKey - * before it can be used. The encoding is used to dermine the public key size. - */ -SECStatus seckey_SetPointEncoding(PLArenaPool *arena, SECKEYPublicKey *pubKey); - SEC_END_PROTOS #endif /* _KEYHI_H_ */ diff --git a/nss/lib/cryptohi/keythi.h b/nss/lib/cryptohi/keythi.h index 1555ce2..f6170bb 100644 --- a/nss/lib/cryptohi/keythi.h +++ b/nss/lib/cryptohi/keythi.h @@ -125,9 +125,9 @@ typedef SECItem SECKEYECParams; struct SECKEYECPublicKeyStr { SECKEYECParams DEREncodedParams; - int size; /* size in bits */ - SECItem publicValue; /* encoded point */ - ECPointEncoding encoding; + int size; /* size in bits */ + SECItem publicValue; /* encoded point */ + ECPointEncoding encoding; /* deprecated, ignored */ }; typedef struct SECKEYECPublicKeyStr SECKEYECPublicKey; @@ -209,7 +209,7 @@ typedef struct SECKEYPublicKeyStr SECKEYPublicKey; (0 != (key->staticflags & SECKEY_Attributes_Cached)) ? (0 != (key->staticflags & SECKEY_##attribute)) : PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute, PR_FALSE) #define SECKEY_HAS_ATTRIBUTE_SET_LOCK(key, attribute, haslock) \ - (0 != (key->staticflags & SECKEY_Attributes_Cached)) ? (0 != (key->staticflags & SECKEY_##attribute)) : PK11_HasAttributeSet(key->pkcs11Slot, key->pkcs11ID, attribute, haslock) + (0 != (key->staticflags & SECKEY_Attributes_Cached)) ? (0 != (key->staticflags & SECKEY_##attribute)) : pk11_HasAttributeSet_Lock(key->pkcs11Slot, key->pkcs11ID, attribute, haslock) /* ** A generic key structure diff --git a/nss/lib/cryptohi/seckey.c b/nss/lib/cryptohi/seckey.c index 1f053e5..9ea48b7 100644 --- a/nss/lib/cryptohi/seckey.c +++ b/nss/lib/cryptohi/seckey.c @@ -547,6 +547,23 @@ CERT_GetCertKeyType(const CERTSubjectPublicKeyInfo *spki) return seckey_GetKeyType(SECOID_GetAlgorithmTag(&spki->algorithm)); } +/* Ensure pubKey contains an OID */ +static SECStatus +seckey_HasCurveOID(const SECKEYPublicKey *pubKey) +{ + SECItem oid; + SECStatus rv; + PORTCheapArenaPool tmpArena; + + PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE); + /* If we can decode it, an OID is available. */ + rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid, + SEC_ASN1_GET(SEC_ObjectIDTemplate), + &pubKey->u.ec.DEREncodedParams); + PORT_DestroyCheapArena(&tmpArena); + return rv; +} + static SECKEYPublicKey * seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki) { @@ -639,7 +656,8 @@ seckey_ExtractPublicKey(const CERTSubjectPublicKeyInfo *spki) if (rv != SECSuccess) { break; } - rv = seckey_SetPointEncoding(arena, pubk); + pubk->u.ec.encoding = ECPoint_Undefined; + rv = seckey_HasCurveOID(pubk); if (rv == SECSuccess) { return pubk; } @@ -1162,16 +1180,16 @@ SECKEY_CopyPublicKey(const SECKEYPublicKey *pubk) break; case ecKey: copyk->u.ec.size = pubk->u.ec.size; - rv = SECITEM_CopyItem(arena, ©k->u.ec.DEREncodedParams, - &pubk->u.ec.DEREncodedParams); + rv = seckey_HasCurveOID(pubk); if (rv != SECSuccess) { break; } - rv = seckey_SetPointEncoding(arena, copyk); + rv = SECITEM_CopyItem(arena, ©k->u.ec.DEREncodedParams, + &pubk->u.ec.DEREncodedParams); if (rv != SECSuccess) { break; } - PORT_Assert(copyk->u.ec.encoding == pubk->u.ec.encoding); + copyk->u.ec.encoding = ECPoint_Undefined; rv = SECITEM_CopyItem(arena, ©k->u.ec.publicValue, &pubk->u.ec.publicValue); break; @@ -1242,6 +1260,19 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk) break; return pubk; break; + case ecKey: + rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, + CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams); + if (rv != SECSuccess) { + break; + } + rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, + CKA_EC_POINT, arena, &pubk->u.ec.publicValue); + if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) { + break; + } + pubk->u.ec.encoding = ECPoint_Undefined; + return pubk; default: break; } @@ -1943,39 +1974,3 @@ SECKEY_GetECCOid(const SECKEYECParams *params) return oidData->offset; } - -/* Set curve encoding in SECKEYECPublicKey in pubKey from OID. - * If the encoding is not set, determining the key size of EC public keys will - * fail. - */ -SECStatus -seckey_SetPointEncoding(PLArenaPool *arena, SECKEYPublicKey *pubKey) -{ - SECItem oid; - SECOidTag tag; - SECStatus rv; - - /* decode the OID tag */ - rv = SEC_QuickDERDecodeItem(arena, &oid, SEC_ASN1_GET(SEC_ObjectIDTemplate), - &pubKey->u.ec.DEREncodedParams); - if (rv != SECSuccess) { - return SECFailure; - } - - tag = SECOID_FindOIDTag(&oid); - switch (tag) { - case SEC_OID_CURVE25519: - pubKey->u.ec.encoding = ECPoint_XOnly; - break; - case SEC_OID_SECG_EC_SECP256R1: - /* fall through */ - case SEC_OID_SECG_EC_SECP384R1: - /* fall through */ - case SEC_OID_SECG_EC_SECP521R1: - /* fall through */ - default: - /* unknown curve, default to uncompressed */ - pubKey->u.ec.encoding = ECPoint_Uncompressed; - } - return SECSuccess; -} diff --git a/nss/lib/cryptohi/secsign.c b/nss/lib/cryptohi/secsign.c index 1bbdd53..d06cb2e 100644 --- a/nss/lib/cryptohi/secsign.c +++ b/nss/lib/cryptohi/secsign.c @@ -312,24 +312,25 @@ SEC_DerSignData(PLArenaPool *arena, SECItem *result, if (algID == SEC_OID_UNKNOWN) { switch (pk->keyType) { case rsaKey: - algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; + algID = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break; case dsaKey: /* get Signature length (= q_len*2) and work from there */ switch (PK11_SignatureLen(pk)) { + case 320: + algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; + break; case 448: algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; break; case 512: - algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; - break; default: - algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; + algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; break; } break; case ecKey: - algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; + algID = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break; default: PORT_SetError(SEC_ERROR_INVALID_KEY); @@ -468,13 +469,13 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) break; case dsaKey: switch (hashAlgTag) { - case SEC_OID_UNKNOWN: /* default for DSA if not specified */ case SEC_OID_SHA1: sigTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break; case SEC_OID_SHA224: sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; break; + case SEC_OID_UNKNOWN: /* default for DSA if not specified */ case SEC_OID_SHA256: sigTag = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; break; @@ -484,13 +485,13 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) break; case ecKey: switch (hashAlgTag) { - case SEC_OID_UNKNOWN: /* default for ECDSA if not specified */ case SEC_OID_SHA1: sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break; case SEC_OID_SHA224: sigTag = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; break; + case SEC_OID_UNKNOWN: /* default for ECDSA if not specified */ case SEC_OID_SHA256: sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break; diff --git a/nss/lib/dev/dev.h b/nss/lib/dev/dev.h index 7e64e76..26ac895 100644 --- a/nss/lib/dev/dev.h +++ b/nss/lib/dev/dev.h @@ -312,6 +312,15 @@ NSS_EXTERN PRBool nssToken_NeedsPINInitialization( NSSToken *token); +NSS_EXTERN nssCryptokiObject ** +nssToken_FindObjectsByTemplate( + NSSToken *token, + nssSession *sessionOpt, + CK_ATTRIBUTE_PTR obj_template, + CK_ULONG otsize, + PRUint32 maximumOpt, + PRStatus *statusOpt); + NSS_EXTERN nssCryptokiObject * nssToken_ImportCertificate( NSSToken *tok, diff --git a/nss/lib/dev/devslot.c b/nss/lib/dev/devslot.c index 5b0bb37..7e8bfcd 100644 --- a/nss/lib/dev/devslot.c +++ b/nss/lib/dev/devslot.c @@ -31,6 +31,7 @@ nssSlot_Destroy( { if (slot) { if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) { + PK11_FreeSlot(slot->pk11slot); PZ_DestroyLock(slot->base.lock); return nssArena_Destroy(slot->base.arena); } @@ -91,7 +92,7 @@ nssSlot_ResetDelay( } static PRBool -within_token_delay_period(NSSSlot *slot) +within_token_delay_period(const NSSSlot *slot) { PRIntervalTime time, lastTime; /* Set the delay time for checking the token presence */ @@ -103,7 +104,6 @@ within_token_delay_period(NSSSlot *slot) if ((lastTime) && ((time - lastTime) < s_token_delay_time)) { return PR_TRUE; } - slot->lastTokenPing = time; return PR_FALSE; } @@ -136,6 +136,7 @@ nssSlot_IsTokenPresent( nssSlot_ExitMonitor(slot); if (ckrv != CKR_OK) { slot->token->base.name[0] = 0; /* XXX */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } slot->ckFlags = slotInfo.flags; @@ -143,6 +144,7 @@ nssSlot_IsTokenPresent( if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) { if (!slot->token) { /* token was never present */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } session = nssToken_GetDefaultSession(slot->token); @@ -165,6 +167,7 @@ nssSlot_IsTokenPresent( slot->token->base.name[0] = 0; /* XXX */ /* clear the token cache */ nssToken_Remove(slot->token); + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } /* token is present, use the session info to determine if the card @@ -187,8 +190,10 @@ nssSlot_IsTokenPresent( isPresent = session->handle != CK_INVALID_SESSION; nssSession_ExitMonitor(session); /* token not removed, finished */ - if (isPresent) + if (isPresent) { + slot->lastTokenPing = PR_IntervalNow(); return PR_TRUE; + } } /* the token has been removed, and reinserted, or the slot contains * a token it doesn't recognize. invalidate all the old @@ -201,8 +206,11 @@ nssSlot_IsTokenPresent( if (nssrv != PR_SUCCESS) { slot->token->base.name[0] = 0; /* XXX */ slot->ckFlags &= ~CKF_TOKEN_PRESENT; + /* TODO: insert a barrier here to avoid reordering of the assingments */ + slot->lastTokenPing = PR_IntervalNow(); return PR_FALSE; } + slot->lastTokenPing = PR_IntervalNow(); return PR_TRUE; } @@ -217,10 +225,17 @@ NSS_IMPLEMENT NSSToken * nssSlot_GetToken( NSSSlot *slot) { - if (nssSlot_IsTokenPresent(slot)) { - return nssToken_AddRef(slot->token); + NSSToken *rvToken = NULL; + nssSlot_EnterMonitor(slot); + + /* Even if a token should be present, check `slot->token` too as it + * might be gone already. This would happen mostly on shutdown. */ + if (nssSlot_IsTokenPresent(slot) && slot->token) { + rvToken = nssToken_AddRef(slot->token); } - return (NSSToken *)NULL; + + nssSlot_ExitMonitor(slot); + return rvToken; } NSS_IMPLEMENT PRStatus diff --git a/nss/lib/dev/devtoken.c b/nss/lib/dev/devtoken.c index 0adbca8..0d4c3b5 100644 --- a/nss/lib/dev/devtoken.c +++ b/nss/lib/dev/devtoken.c @@ -29,11 +29,16 @@ nssToken_Destroy( { if (tok) { if (PR_ATOMIC_DECREMENT(&tok->base.refCount) == 0) { + PK11_FreeSlot(tok->pk11slot); PZ_DestroyLock(tok->base.lock); nssTokenObjectCache_Destroy(tok->cache); - /* The token holds the first/last reference to the slot. - * When the token is actually destroyed, that ref must go too. - */ + + /* We're going away, let the nssSlot know in case it's held + * alive by someone else. Usually we should hold the last ref. */ + nssSlot_EnterMonitor(tok->slot); + tok->slot->token = NULL; + nssSlot_ExitMonitor(tok->slot); + (void)nssSlot_Destroy(tok->slot); return nssArena_Destroy(tok->base.arena); } @@ -368,8 +373,8 @@ loser: return (nssCryptokiObject **)NULL; } -static nssCryptokiObject ** -find_objects_by_template( +NSS_IMPLEMENT nssCryptokiObject ** +nssToken_FindObjectsByTemplate( NSSToken *token, nssSession *sessionOpt, CK_ATTRIBUTE_PTR obj_template, @@ -581,9 +586,9 @@ nssToken_FindObjects( obj_template, obj_size, maximumOpt, statusOpt); } else { - objects = find_objects_by_template(token, sessionOpt, - obj_template, obj_size, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + obj_template, obj_size, + maximumOpt, statusOpt); } return objects; } @@ -612,9 +617,9 @@ nssToken_FindCertificatesBySubject( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); /* now locate the token certs matching this template */ - objects = find_objects_by_template(token, sessionOpt, - subj_template, stsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + subj_template, stsize, + maximumOpt, statusOpt); return objects; } @@ -642,9 +647,9 @@ nssToken_FindCertificatesByNickname( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize); /* now locate the token certs matching this template */ - objects = find_objects_by_template(token, sessionOpt, - nick_template, ntsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + nick_template, ntsize, + maximumOpt, statusOpt); if (!objects) { /* This is to workaround the fact that PKCS#11 doesn't specify * whether the '\0' should be included. XXX Is that still true? @@ -653,9 +658,9 @@ nssToken_FindCertificatesByNickname( * well, its needed by the builtin token... */ nick_template[0].ulValueLen++; - objects = find_objects_by_template(token, sessionOpt, - nick_template, ntsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + nick_template, ntsize, + maximumOpt, statusOpt); } return objects; } @@ -732,9 +737,9 @@ nssToken_FindCertificatesByID( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_TEMPLATE_FINISH(id_template, attr, idtsize); /* now locate the token certs matching this template */ - objects = find_objects_by_template(token, sessionOpt, - id_template, idtsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + id_template, idtsize, + maximumOpt, statusOpt); return objects; } @@ -822,9 +827,9 @@ nssToken_FindCertificateByIssuerAndSerialNumber( cert_template, ctsize, 1, statusOpt); } else { - objects = find_objects_by_template(token, sessionOpt, - cert_template, ctsize, - 1, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + cert_template, ctsize, + 1, statusOpt); } if (objects) { rvObject = objects[0]; @@ -849,9 +854,9 @@ nssToken_FindCertificateByIssuerAndSerialNumber( cert_template, ctsize, 1, statusOpt); } else { - objects = find_objects_by_template(token, sessionOpt, - cert_template, ctsize, - 1, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + cert_template, ctsize, + 1, statusOpt); } if (objects) { rvObject = objects[0]; @@ -885,9 +890,9 @@ nssToken_FindCertificateByEncodedCertificate( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* get the object handle */ - objects = find_objects_by_template(token, sessionOpt, - cert_template, ctsize, - 1, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + cert_template, ctsize, + 1, statusOpt); if (objects) { rvObject = objects[0]; nss_ZFreeIf(objects); @@ -917,9 +922,9 @@ nssToken_FindPrivateKeys( } NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); - objects = find_objects_by_template(token, sessionOpt, - key_template, ktsize, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + key_template, ktsize, + maximumOpt, statusOpt); return objects; } @@ -942,9 +947,9 @@ nssToken_FindPrivateKeyByID( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); - objects = find_objects_by_template(token, sessionOpt, - key_template, ktsize, - 1, NULL); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + key_template, ktsize, + 1, NULL); if (objects) { rvKey = objects[0]; nss_ZFreeIf(objects); @@ -971,9 +976,9 @@ nssToken_FindPublicKeyByID( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, keyID); NSS_CK_TEMPLATE_FINISH(key_template, attr, ktsize); - objects = find_objects_by_template(token, sessionOpt, - key_template, ktsize, - 1, NULL); + objects = nssToken_FindObjectsByTemplate(token, sessionOpt, + key_template, ktsize, + 1, NULL); if (objects) { rvKey = objects[0]; nss_ZFreeIf(objects); @@ -1130,9 +1135,9 @@ nssToken_FindTrustForCertificate( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, certIssuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, certSerial); NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); - objects = find_objects_by_template(token, session, - tobj_template, tobj_size, - 1, NULL); + objects = nssToken_FindObjectsByTemplate(token, session, + tobj_template, tobj_size, + 1, NULL); if (objects) { object = objects[0]; nss_ZFreeIf(objects); @@ -1215,9 +1220,9 @@ nssToken_FindCRLsBySubject( NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size); - objects = find_objects_by_template(token, session, - crlobj_template, crlobj_size, - maximumOpt, statusOpt); + objects = nssToken_FindObjectsByTemplate(token, session, + crlobj_template, crlobj_size, + maximumOpt, statusOpt); return objects; } diff --git a/nss/lib/freebl/Makefile b/nss/lib/freebl/Makefile index 0ce1425..aa02f4b 100644 --- a/nss/lib/freebl/Makefile +++ b/nss/lib/freebl/Makefile @@ -232,8 +232,6 @@ ifeq ($(CPU_ARCH),x86) DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT DEFINES += -DMP_IS_LITTLE_ENDIAN - # The floating point ECC code doesn't work on Linux x86 (bug 311432). - #ECL_USE_FP = 1 endif ifeq ($(CPU_ARCH),arm) DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE @@ -430,7 +428,6 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv8.s montmulfv8.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL - ECL_USE_FP = 1 endif ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture @@ -443,7 +440,6 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv9.s montmulfv9.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL - ECL_USE_FP = 1 endif else @@ -491,16 +487,7 @@ else endif endif endif # Solaris for non-sparc family CPUs -endif # target == SunOS - -ifndef NSS_DISABLE_ECC - ifdef ECL_USE_FP - #enable floating point ECC code - DEFINES += -DECL_USE_FP - ECL_SRCS += ecp_fp160.c ecp_fp192.c ecp_fp224.c ecp_fp.c - ECL_HDRS += ecp_fp.h - endif -endif +endif # target == SunO # poly1305-donna-x64-sse2-incremental-source.c requires __int128 support # in GCC 4.6.0. @@ -601,7 +588,7 @@ $(ECL_OBJS): $(ECL_HDRS) -$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c os2_rand.c +$(OBJDIR)/sysrand$(OBJ_SUFFIX): sysrand.c unix_rand.c win_rand.c $(OBJDIR)/$(PROG_PREFIX)mpprime$(OBJ_SUFFIX): primes.c diff --git a/nss/lib/freebl/blapi.h b/nss/lib/freebl/blapi.h index 38c3a9f..592624b 100644 --- a/nss/lib/freebl/blapi.h +++ b/nss/lib/freebl/blapi.h @@ -1429,8 +1429,6 @@ extern SECStatus RNG_RandomUpdate(const void *data, size_t bytes); */ extern SECStatus RNG_GenerateGlobalRandomBytes(void *dest, size_t len); -extern SECStatus RNG_ResetForFuzzing(void); - /* Destroy the global RNG context. After a call to RNG_RNGShutdown() ** a call to RNG_RNGInit() is required in order to use the generator again, ** along with seed data (see the comment above RNG_RNGInit()). @@ -1469,6 +1467,12 @@ FIPS186Change_ReduceModQForDSA(const unsigned char *w, const unsigned char *q, unsigned char *xj); +/* To allow NIST KAT tests */ +extern SECStatus +PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *nonce, unsigned int nonce_len, + const PRUint8 *personal_string, unsigned int ps_len); + /* * The following functions are for FIPS poweron self test and FIPS algorithm * testing. @@ -1599,7 +1603,6 @@ extern const SECHashObject *HASH_GetRawHashObject(HASH_HashType hashType); extern void BL_SetForkState(PRBool forked); -#ifndef NSS_DISABLE_ECC /* ** pepare an ECParam structure from DEREncoded params */ @@ -1609,7 +1612,11 @@ extern SECStatus EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); extern SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, const ECParams *srcParams); -#endif + +/* + * use the internal table to get the size in bytes of a single EC point + */ +extern int EC_GetPointSize(const ECParams *params); SEC_END_PROTOS diff --git a/nss/lib/freebl/blapii.h b/nss/lib/freebl/blapii.h index 6ad2e28..0087c78 100644 --- a/nss/lib/freebl/blapii.h +++ b/nss/lib/freebl/blapii.h @@ -9,6 +9,7 @@ #define _BLAPII_H_ #include "blapit.h" +#include "mpi.h" /* max block size of supported block ciphers */ #define MAX_BLOCK_SIZE 16 @@ -58,4 +59,12 @@ SEC_END_PROTOS #undef HAVE_NO_SANITIZE_ATTR +SECStatus RSA_Init(); +SECStatus generate_prime(mp_int *prime, int primeLen); + +/* Freebl state. */ +PRBool aesni_support(); +PRBool clmul_support(); +PRBool avx_support(); + #endif /* _BLAPII_H_ */ diff --git a/nss/lib/freebl/blapit.h b/nss/lib/freebl/blapit.h index 7cf8fc6..2a17b5f 100644 --- a/nss/lib/freebl/blapit.h +++ b/nss/lib/freebl/blapit.h @@ -377,7 +377,6 @@ struct ECParamsStr { SECItem DEREncoding; ECCurveName name; SECItem curveOID; - int pointSize; }; typedef struct ECParamsStr ECParams; diff --git a/nss/lib/freebl/blinit.c b/nss/lib/freebl/blinit.c new file mode 100644 index 0000000..d7f2ec5 --- /dev/null +++ b/nss/lib/freebl/blinit.c @@ -0,0 +1,119 @@ +/* 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/. */ + +#ifdef FREEBL_NO_DEPEND +#include "stubs.h" +#endif + +#include "blapii.h" +#include "mpi.h" +#include "secerr.h" +#include "prtypes.h" +#include "prinit.h" +#include "prenv.h" + +#if defined(_MSC_VER) && !defined(_M_IX86) +#include <intrin.h> /* for _xgetbv() */ +#endif + +static PRCallOnceType coFreeblInit; + +/* State variables. */ +static PRBool aesni_support_ = PR_FALSE; +static PRBool clmul_support_ = PR_FALSE; +static PRBool avx_support_ = PR_FALSE; + +#ifdef NSS_X86_OR_X64 +/* + * Adapted from the example code in "How to detect New Instruction support in + * the 4th generation Intel Core processor family" by Max Locktyukhin. + * + * XGETBV: + * Reads an extended control register (XCR) specified by ECX into EDX:EAX. + */ +static PRBool +check_xcr0_ymm() +{ + PRUint32 xcr0; +#if defined(_MSC_VER) +#if defined(_M_IX86) + __asm { + mov ecx, 0 + xgetbv + mov xcr0, eax + } +#else + xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */ +#endif /* _M_IX86 */ +#else /* _MSC_VER */ + /* Old OSX compilers don't support xgetbv. Use byte form. */ + __asm__(".byte 0x0F, 0x01, 0xd0" + : "=a"(xcr0) + : "c"(0) + : "%edx"); +#endif /* _MSC_VER */ + /* Check if xmm and ymm state are enabled in XCR0. */ + return (xcr0 & 6) == 6; +} + +#define ECX_AESNI (1 << 25) +#define ECX_CLMUL (1 << 1) +#define ECX_XSAVE (1 << 26) +#define ECX_OSXSAVE (1 << 27) +#define ECX_AVX (1 << 28) +#define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX) + +void +CheckX86CPUSupport() +{ + unsigned long eax, ebx, ecx, edx; + char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); + char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL"); + char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX"); + freebl_cpuid(1, &eax, &ebx, &ecx, &edx); + aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL); + clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL); + /* For AVX we check AVX, OSXSAVE, and XSAVE + * as well as XMM and YMM state. */ + avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() && + disable_avx == NULL; +} +#endif /* NSS_X86_OR_X64 */ + +PRBool +aesni_support() +{ + return aesni_support_; +} +PRBool +clmul_support() +{ + return clmul_support_; +} +PRBool +avx_support() +{ + return avx_support_; +} + +static PRStatus +FreeblInit(void) +{ +#ifdef NSS_X86_OR_X64 + CheckX86CPUSupport(); +#endif + return PR_SUCCESS; +} + +SECStatus +BL_Init() +{ + if (PR_CallOnce(&coFreeblInit, FreeblInit) != PR_SUCCESS) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + RSA_Init(); + + return SECSuccess; +} diff --git a/nss/lib/freebl/det_rng.c b/nss/lib/freebl/det_rng.c index fcbf9b3..04fce30 100644 --- a/nss/lib/freebl/det_rng.c +++ b/nss/lib/freebl/det_rng.c @@ -9,10 +9,32 @@ #include "seccomon.h" #include "secerr.h" +#define GLOBAL_BYTES_SIZE 100 +static PRUint8 globalBytes[GLOBAL_BYTES_SIZE]; static unsigned long globalNumCalls = 0; +static PZLock *rng_lock = NULL; SECStatus -prng_ResetForFuzzing(PZLock *rng_lock) +RNG_RNGInit(void) +{ + rng_lock = PZ_NewLock(nssILockOther); + if (!rng_lock) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + /* --- LOCKED --- */ + PZ_Lock(rng_lock); + memset(globalBytes, 0, GLOBAL_BYTES_SIZE); + PZ_Unlock(rng_lock); + /* --- UNLOCKED --- */ + + return SECSuccess; +} + +/* Take min(size, GLOBAL_BYTES_SIZE) bytes from data and use as seed and reset + * the rng state. */ +SECStatus +RNG_RandomUpdate(const void *data, size_t bytes) { /* Check for a valid RNG lock. */ PORT_Assert(rng_lock != NULL); @@ -23,7 +45,11 @@ prng_ResetForFuzzing(PZLock *rng_lock) /* --- LOCKED --- */ PZ_Lock(rng_lock); + memset(globalBytes, 0, GLOBAL_BYTES_SIZE); globalNumCalls = 0; + if (data) { + memcpy(globalBytes, (PRUint8 *)data, PR_MIN(bytes, GLOBAL_BYTES_SIZE)); + } PZ_Unlock(rng_lock); /* --- UNLOCKED --- */ @@ -31,9 +57,9 @@ prng_ResetForFuzzing(PZLock *rng_lock) } SECStatus -prng_GenerateDeterministicRandomBytes(PZLock *rng_lock, void *dest, size_t len) +RNG_GenerateGlobalRandomBytes(void *dest, size_t len) { - static const uint8_t key[32]; + static const uint8_t key[32] = { 0 }; uint8_t nonce[12] = { 0 }; /* Check for a valid RNG lock. */ @@ -58,10 +84,60 @@ prng_GenerateDeterministicRandomBytes(PZLock *rng_lock, void *dest, size_t len) } memset(dest, 0, len); + memcpy(dest, globalBytes, PR_MIN(len, GLOBAL_BYTES_SIZE)); ChaCha20XOR(dest, dest, len, key, nonce, 0); ChaCha20Poly1305_DestroyContext(cx, PR_TRUE); PZ_Unlock(rng_lock); /* --- UNLOCKED --- */ + return SECSuccess; } + +void +RNG_RNGShutdown(void) +{ + PZ_DestroyLock(rng_lock); + rng_lock = NULL; +} + +/* Test functions are not implemented! */ +SECStatus +PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *nonce, unsigned int nonce_len, + const PRUint8 *personal_string, unsigned int ps_len) +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *additional, unsigned int additional_len) +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len, + const PRUint8 *additional, unsigned int additional_len) +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Uninstantiate() +{ + return SECFailure; +} + +SECStatus +PRNGTEST_RunHealthTests() +{ + return SECFailure; +} + +SECStatus +PRNGTEST_Instantiate_Kat() +{ + return SECFailure; +} diff --git a/nss/lib/freebl/dh.c b/nss/lib/freebl/dh.c index 97025c7..587982a 100644 --- a/nss/lib/freebl/dh.c +++ b/nss/lib/freebl/dh.c @@ -14,9 +14,9 @@ #include "secerr.h" #include "blapi.h" +#include "blapii.h" #include "secitem.h" #include "mpi.h" -#include "mpprime.h" #include "secmpi.h" #define KEA_DERIVED_SECRET_LEN 128 @@ -46,9 +46,7 @@ DH_GenParam(int primeLen, DHParams **params) { PLArenaPool *arena; DHParams *dhparams; - unsigned char *pb = NULL; unsigned char *ab = NULL; - unsigned long counter = 0; mp_int p, q, a, h, psub1, test; mp_err err = MP_OKAY; SECStatus rv = SECSuccess; @@ -81,12 +79,7 @@ DH_GenParam(int primeLen, DHParams **params) CHECK_MPI_OK(mp_init(&psub1)); CHECK_MPI_OK(mp_init(&test)); /* generate prime with MPI, uses Miller-Rabin to generate strong prime. */ - pb = PORT_Alloc(primeLen); - CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(pb, primeLen)); - pb[0] |= 0x80; /* set high-order bit */ - pb[primeLen - 1] |= 0x01; /* set low-order bit */ - CHECK_MPI_OK(mp_read_unsigned_octets(&p, pb, primeLen)); - CHECK_MPI_OK(mpp_make_prime(&p, primeLen * 8, PR_TRUE, &counter)); + CHECK_SEC_OK(generate_prime(&p, primeLen)); /* construct Sophie-Germain prime q = (p-1)/2. */ CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1)); CHECK_MPI_OK(mp_div_2(&psub1, &q)); @@ -121,8 +114,6 @@ cleanup: mp_clear(&h); mp_clear(&psub1); mp_clear(&test); - if (pb) - PORT_ZFree(pb, primeLen); if (ab) PORT_ZFree(ab, primeLen); if (err) { diff --git a/nss/lib/freebl/drbg.c b/nss/lib/freebl/drbg.c index 658faa3..224bbe8 100644 --- a/nss/lib/freebl/drbg.c +++ b/nss/lib/freebl/drbg.c @@ -20,10 +20,6 @@ #include "secrng.h" /* for RNG_SystemRNG() */ #include "secmpi.h" -#ifdef UNSAFE_FUZZER_MODE -#include "det_rng.h" -#endif - /* PRNG_SEEDLEN defined in NIST SP 800-90 section 10.1 * for SHA-1, SHA-224, and SHA-256 it's 440 bits. * for SHA-384 and SHA-512 it's 888 bits */ @@ -99,7 +95,8 @@ struct RNGContextStr { * RNG_RandomUpdate. */ PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE]; PRUint32 additionalAvail; - PRBool isValid; /* false if RNG reaches an invalid state */ + PRBool isValid; /* false if RNG reaches an invalid state */ + PRBool isKatTest; /* true if running NIST PRNG KAT tests */ }; typedef struct RNGContextStr RNGContext; @@ -150,7 +147,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return, } /* - * Hash_DRBG Instantiate NIST SP 800-80 10.1.1.2 + * Hash_DRBG Instantiate NIST SP 800-90 10.1.1.2 * * NOTE: bytes & len are entropy || nonce || personalization_string. In * normal operation, NSS calculates them all together in a single call. @@ -158,9 +155,11 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return, static SECStatus prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len) { - if (len < PRNG_SEEDLEN) { - /* if the seedlen is to small, it's probably because we failed to get - * enough random data */ + if (!rng->isKatTest && len < PRNG_SEEDLEN) { + /* If the seedlen is too small, it's probably because we failed to get + * enough random data. + * This is stricter than NIST SP800-90A requires. Don't enforce it for + * tests. */ PORT_SetError(SEC_ERROR_NEED_RANDOM); return SECFailure; } @@ -272,7 +271,7 @@ prng_reseed_test(RNGContext *rng, const PRUint8 *entropy, #define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len, carry) \ PRNG_ADD_BITS(dest, dest_len, add, len, carry) \ - PRNG_ADD_CARRY_ONLY(dest, dest_len - len, carry) + PRNG_ADD_CARRY_ONLY(dest, dest_len - len - 1, carry) /* * This function expands the internal state of the prng to fulfill any number @@ -435,12 +434,13 @@ rng_init(void) globalrng = NULL; return PR_FAILURE; } - if (rv != SECSuccess) { return PR_FAILURE; } + /* the RNG is in a valid state */ globalrng->isValid = PR_TRUE; + globalrng->isKatTest = PR_FALSE; /* fetch one random value so that we can populate rng->oldV for our * continous random number test. */ @@ -654,21 +654,7 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng, SECStatus RNG_GenerateGlobalRandomBytes(void *dest, size_t len) { -#ifdef UNSAFE_FUZZER_MODE - return prng_GenerateDeterministicRandomBytes(globalrng->lock, dest, len); -#else return prng_GenerateGlobalRandomBytes(globalrng, dest, len); -#endif -} - -SECStatus -RNG_ResetForFuzzing(void) -{ -#ifdef UNSAFE_FUZZER_MODE - return prng_ResetForFuzzing(globalrng->lock); -#else - return SECFailure; -#endif } void @@ -696,6 +682,17 @@ RNG_RNGShutdown(void) * entropy we may have previously collected. */ RNGContext testContext; +SECStatus +PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *nonce, unsigned int nonce_len, + const PRUint8 *personal_string, unsigned int ps_len) +{ + testContext.isKatTest = PR_TRUE; + return PRNGTEST_Instantiate(entropy, entropy_len, + nonce, nonce_len, + personal_string, ps_len); +} + /* * Test vector API. Use NIST SP 800-90 general interface so one of the * other NIST SP 800-90 algorithms may be used in the future. diff --git a/nss/lib/freebl/ec.c b/nss/lib/freebl/ec.c index a9b7c05..669c9b1 100644 --- a/nss/lib/freebl/ec.c +++ b/nss/lib/freebl/ec.c @@ -233,7 +233,6 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey, key->ecParams.type = ecParams->type; key->ecParams.fieldID.size = ecParams->fieldID.size; key->ecParams.fieldID.type = ecParams->fieldID.type; - key->ecParams.pointSize = ecParams->pointSize; if (ecParams->fieldID.type == ec_field_GFp || ecParams->fieldID.type == ec_field_plain) { CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.fieldID.u.prime, @@ -262,7 +261,7 @@ ec_NewKey(ECParams *ecParams, ECPrivateKey **privKey, CHECK_SEC_OK(SECITEM_CopyItem(arena, &key->ecParams.curveOID, &ecParams->curveOID)); - SECITEM_AllocItem(arena, &key->publicValue, ecParams->pointSize); + SECITEM_AllocItem(arena, &key->publicValue, EC_GetPointSize(ecParams)); len = ecParams->order.len; SECITEM_AllocItem(arena, &key->privateValue, len); @@ -566,11 +565,20 @@ ECDH_Derive(SECItem *publicValue, return SECFailure; } + /* + * Make sure the point is on the requested curve to avoid + * certain small subgroup attacks. + */ + if (EC_ValidatePublicKey(ecParams, publicValue) != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return SECFailure; + } + /* Perform curve specific multiplication using ECMethod */ if (ecParams->fieldID.type == ec_field_plain) { const ECMethod *method; memset(derivedSecret, 0, sizeof(*derivedSecret)); - derivedSecret = SECITEM_AllocItem(NULL, derivedSecret, ecParams->pointSize); + derivedSecret = SECITEM_AllocItem(NULL, derivedSecret, EC_GetPointSize(ecParams)); if (derivedSecret == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; @@ -581,10 +589,6 @@ ECDH_Derive(SECItem *publicValue, PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); return SECFailure; } - if (method->validate(publicValue) != SECSuccess) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } return method->mul(derivedSecret, privateValue, publicValue); } @@ -600,8 +604,8 @@ ECDH_Derive(SECItem *publicValue, MP_DIGITS(&k) = 0; memset(derivedSecret, 0, sizeof *derivedSecret); len = (ecParams->fieldID.size + 7) >> 3; - pointQ.len = ecParams->pointSize; - if ((pointQ.data = PORT_Alloc(ecParams->pointSize)) == NULL) + pointQ.len = EC_GetPointSize(ecParams); + if ((pointQ.data = PORT_Alloc(pointQ.len)) == NULL) goto cleanup; CHECK_MPI_OK(mp_init(&k)); @@ -648,7 +652,7 @@ cleanup: } if (pointQ.data) { - PORT_ZFree(pointQ.data, ecParams->pointSize); + PORT_ZFree(pointQ.data, pointQ.len); } #else PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); @@ -763,8 +767,8 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, ** ** Compute kG */ - kGpoint.len = ecParams->pointSize; - kGpoint.data = PORT_Alloc(ecParams->pointSize); + kGpoint.len = EC_GetPointSize(ecParams); + kGpoint.data = PORT_Alloc(kGpoint.len); if ((kGpoint.data == NULL) || (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint) != SECSuccess)) goto cleanup; @@ -883,7 +887,7 @@ cleanup: } if (kGpoint.data) { - PORT_ZFree(kGpoint.data, ecParams->pointSize); + PORT_ZFree(kGpoint.data, kGpoint.len); } if (err) { @@ -1002,9 +1006,14 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, } slen = signature->len / 2; - SECITEM_AllocItem(NULL, &pointC, ecParams->pointSize); - if (pointC.data == NULL) + /* + * The incoming point has been verified in sftk_handlePublicKeyObject. + */ + + SECITEM_AllocItem(NULL, &pointC, EC_GetPointSize(ecParams)); + if (pointC.data == NULL) { goto cleanup; + } CHECK_MPI_OK(mp_init(&r_)); CHECK_MPI_OK(mp_init(&s_)); diff --git a/nss/lib/freebl/ecdecode.c b/nss/lib/freebl/ecdecode.c index eda3f0c..54b3e11 100644 --- a/nss/lib/freebl/ecdecode.c +++ b/nss/lib/freebl/ecdecode.c @@ -22,57 +22,6 @@ if (SECSuccess != (rv = func)) \ goto cleanup -/* - * Initializes a SECItem from a hexadecimal string - * - * Warning: This function ignores leading 00's, so any leading 00's - * in the hexadecimal string must be optional. - */ -static SECItem * -hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str) -{ - int i = 0; - int byteval = 0; - int tmp = PORT_Strlen(str); - - PORT_Assert(arena); - PORT_Assert(item); - - if ((tmp % 2) != 0) - return NULL; - - /* skip leading 00's unless the hex string is "00" */ - while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { - str += 2; - tmp -= 2; - } - - item->data = (unsigned char *)PORT_ArenaAlloc(arena, tmp / 2); - if (item->data == NULL) - return NULL; - item->len = tmp / 2; - - while (str[i]) { - if ((str[i] >= '0') && (str[i] <= '9')) - tmp = str[i] - '0'; - else if ((str[i] >= 'a') && (str[i] <= 'f')) - tmp = str[i] - 'a' + 10; - else if ((str[i] >= 'A') && (str[i] <= 'F')) - tmp = str[i] - 'A' + 10; - else - return NULL; - - byteval = byteval * 16 + tmp; - if ((i % 2) != 0) { - item->data[i / 2] = byteval; - byteval = 0; - } - i++; - } - - return item; -} - /* Copy all of the fields from srcParams into dstParams */ SECStatus @@ -85,7 +34,6 @@ EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, dstParams->type = srcParams->type; dstParams->fieldID.size = srcParams->fieldID.size; dstParams->fieldID.type = srcParams->fieldID.type; - dstParams->pointSize = srcParams->pointSize; if (srcParams->fieldID.type == ec_field_GFp || srcParams->fieldID.type == ec_field_plain) { CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime, @@ -121,12 +69,10 @@ cleanup: } static SECStatus -gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params) +gf_populate_params_bytes(ECCurveName name, ECFieldType field_type, ECParams *params) { SECStatus rv = SECFailure; - const ECCurveParams *curveParams; - /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */ - char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; + const ECCurveBytes *curveParams; if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup; @@ -135,27 +81,19 @@ gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params) CHECK_OK(curveParams); params->fieldID.size = curveParams->size; params->fieldID.type = field_type; - params->pointSize = curveParams->pointSize; - if (field_type == ec_field_GFp || - field_type == ec_field_plain) { - CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.prime, - curveParams->irr)); - } else { - CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.poly, - curveParams->irr)); + if (field_type != ec_field_GFp && field_type != ec_field_plain) { + return SECFailure; } - CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, - curveParams->curvea)); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, - curveParams->curveb)); - genenc[0] = '0'; - genenc[1] = '4'; - genenc[2] = '\0'; - strcat(genenc, curveParams->genx); - strcat(genenc, curveParams->geny); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, genenc)); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, - curveParams->order)); + params->fieldID.u.prime.len = curveParams->scalarSize; + params->fieldID.u.prime.data = (unsigned char *)curveParams->irr; + params->curve.a.len = curveParams->scalarSize; + params->curve.a.data = (unsigned char *)curveParams->curvea; + params->curve.b.len = curveParams->scalarSize; + params->curve.b.data = (unsigned char *)curveParams->curveb; + params->base.len = curveParams->pointSize; + params->base.data = (unsigned char *)curveParams->base; + params->order.len = curveParams->scalarSize; + params->order.data = (unsigned char *)curveParams->order; params->cofactor = curveParams->cofactor; rv = SECSuccess; @@ -218,29 +156,30 @@ EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams, /* Populate params for prime256v1 aka secp256r1 * (the NIST P-256 curve) */ - CHECK_SEC_OK(gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp, - params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_X9_62_PRIME_256V1, + ec_field_GFp, params)); break; case SEC_OID_SECG_EC_SECP384R1: /* Populate params for secp384r1 * (the NIST P-384 curve) */ - CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp, - params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_384R1, + ec_field_GFp, params)); break; case SEC_OID_SECG_EC_SECP521R1: /* Populate params for secp521r1 * (the NIST P-521 curve) */ - CHECK_SEC_OK(gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp, - params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve_SECG_PRIME_521R1, + ec_field_GFp, params)); break; case SEC_OID_CURVE25519: /* Populate params for Curve25519 */ - CHECK_SEC_OK(gf_populate_params(ECCurve25519, ec_field_plain, params)); + CHECK_SEC_OK(gf_populate_params_bytes(ECCurve25519, ec_field_plain, + params)); break; default: @@ -294,4 +233,24 @@ EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams) } } +int +EC_GetPointSize(const ECParams *params) +{ + ECCurveName name = params->name; + const ECCurveBytes *curveParams; + + if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve) || + ((curveParams = ecCurve_map[name]) == NULL)) { + /* unknown curve, calculate point size from params. assume standard curves with 2 points + * and a point compression indicator byte */ + int sizeInBytes = (params->fieldID.size + 7) / 8; + return sizeInBytes * 2 + 1; + } + if (name == ECCurve25519) { + /* Only X here */ + return curveParams->scalarSize; + } + return curveParams->pointSize - 1; +} + #endif /* NSS_DISABLE_ECC */ diff --git a/nss/lib/freebl/ecl/README b/nss/lib/freebl/ecl/README index 04a8b3b..2996822 100644 --- a/nss/lib/freebl/ecl/README +++ b/nss/lib/freebl/ecl/README @@ -90,20 +90,6 @@ the linear coefficient in the curve defining equation). ecp_192.c and ecp_224.c provide optimized field arithmetic. -Point Arithmetic over Binary Polynomial Fields ----------------------------------------------- - -ec2_aff.c provides point arithmetic using affine coordinates. - -ec2_proj.c provides point arithmetic using projective coordinates. -(Projective coordinates represent a point (x, y) as (X, Y, Z), where -x=X/Z, y=Y/Z^2). - -ec2_mont.c provides point multiplication using Montgomery projective -coordinates. - -ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field arithmetic. - Field Arithmetic ---------------- @@ -126,18 +112,6 @@ fields defined by nistp192 and nistp224 primes. ecl_gf.c provides wrappers around the basic field operations. -Binary Polynomial Field Arithmetic ----------------------------------- - -../mpi/mp_gf2m.c provides basic binary polynomial field arithmetic, -including addition, multiplication, squaring, mod, and division, as well -as conversion ob polynomial representations between bitstring and int[]. - -ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field mod, mul, -and sqr operations. - -ecl_gf.c provides wrappers around the basic field operations. - Field Encoding -------------- @@ -187,81 +161,3 @@ arithmetic. Instead, they use basic field arithmetic with their optimized reduction (as in ecp_192.c and ecp_224.c). They use the same point multiplication and simultaneous point multiplication algorithms as other curves over prime fields. - -Curves over binary polynomial fields by default use generic field -arithmetic with montgomery point multiplication and basic kP + lQ -computation (multiply, multiply, and add). (Wiring in function -ECGroup_cons_GF2m in ecl.c.) - -Curves over binary polynomial fields that have optimized field -arithmetic (i.e., any 163-, 193, or 233-bit field) use their optimized -field arithmetic. They use the same point multiplication and -simultaneous point multiplication algorithms as other curves over binary -fields. - -Example -------- - -We provide an example for plugging in an optimized implementation for -the Koblitz curve nistk163. - -Suppose the file ec2_k163.c contains the optimized implementation. In -particular it contains a point multiplication function: - - mp_err ec_GF2m_nistk163_pt_mul(const mp_int *n, const mp_int *px, - const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group); - -Since only a pt_mul function is provided, the generic pt_add function -will be used. - -There are two options for handling the optimized field arithmetic used -by the ..._pt_mul function. Say the optimized field arithmetic includes -the following functions: - - mp_err ec_GF2m_nistk163_add(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - mp_err ec_GF2m_nistk163_mul(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - mp_err ec_GF2m_nistk163_sqr(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - mp_err ec_GF2m_nistk163_div(const mp_int *a, const mp_int *b, - mp_int *r, const GFMethod *meth); - -First, the optimized field arithmetic could simply be called directly -by the ..._pt_mul function. This would be accomplished by changing -the ecgroup_fromNameAndHex function in ecl.c to include the following -statements: - - if (name == ECCurve_NIST_K163) { - group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, - &geny, &order, params->cofactor); - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } - MP_CHECKOK( ec_group_set_nistk163(group) ); - } - -and including in ec2_k163.c the following function: - - mp_err ec_group_set_nistk163(ECGroup *group) { - group->point_mul = &ec_GF2m_nistk163_pt_mul; - return MP_OKAY; - } - -As a result, ec_GF2m_pt_add and similar functions would use the -basic binary polynomial field arithmetic ec_GF2m_add, ec_GF2m_mul, -ec_GF2m_sqr, and ec_GF2m_div. - -Alternatively, the optimized field arithmetic could be wired into the -group's GFMethod. This would be accomplished by putting the following -function in ec2_k163.c: - - mp_err ec_group_set_nistk163(ECGroup *group) { - group->meth->field_add = &ec_GF2m_nistk163_add; - group->meth->field_mul = &ec_GF2m_nistk163_mul; - group->meth->field_sqr = &ec_GF2m_nistk163_sqr; - group->meth->field_div = &ec_GF2m_nistk163_div; - group->point_mul = &ec_GF2m_nistk163_pt_mul; - return MP_OKAY; - } - -For an example of functions that use special field encodings, take a -look at ecp_mont.c. diff --git a/nss/lib/freebl/ecl/curve25519_64.c b/nss/lib/freebl/ecl/curve25519_64.c index 89327ad..65f6bd4 100644 --- a/nss/lib/freebl/ecl/curve25519_64.c +++ b/nss/lib/freebl/ecl/curve25519_64.c @@ -206,7 +206,7 @@ fexpand(felem *output, const u8 *in) output[1] = (*((const uint64_t *)(in + 6)) >> 3) & MASK51; output[2] = (*((const uint64_t *)(in + 12)) >> 6) & MASK51; output[3] = (*((const uint64_t *)(in + 19)) >> 1) & MASK51; - output[4] = (*((const uint64_t *)(in + 25)) >> 4) & MASK51; + output[4] = (*((const uint64_t *)(in + 24)) >> 12) & MASK51; } /* Take a fully reduced polynomial form number and contract it into a diff --git a/nss/lib/freebl/ecl/ecl-curve.h b/nss/lib/freebl/ecl/ecl-curve.h index df06139..fc8003f 100644 --- a/nss/lib/freebl/ecl/ecl-curve.h +++ b/nss/lib/freebl/ecl/ecl-curve.h @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "ecl-exp.h" +#include "eclt.h" #include <stdlib.h> #ifndef __ecl_curve_h_ @@ -12,52 +13,201 @@ #define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ #define KU_KEY_AGREEMENT (0x08) /* bit 4 */ -static const ECCurveParams ecCurve_NIST_P256 = { +static const PRUint8 irr256[32] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const PRUint8 a256[32] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC }; +static const PRUint8 b256[32] = + { 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B }; +static const PRUint8 x256[32] = + { 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96 }; +static const PRUint8 y256[32] = + { 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, + 0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 }; +static const PRUint8 order256[32] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 }; +static const PRUint8 base256[66] = + { 0x04, 0x00, + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, + 0x4F, 0xE3, 0x42, 0xE2, 0xFE, 0x1A, 0x7F, 0x9B, 0x8E, 0xE7, 0xEB, 0x4A, + 0x7C, 0x0F, 0x9E, 0x16, 0x2B, 0xCE, 0x33, 0x57, 0x6B, 0x31, 0x5E, 0xCE, + 0xCB, 0xB6, 0x40, 0x68, 0x37, 0xBF, 0x51, 0xF5 }; + +static const ECCurveBytes ecCurve_NIST_P256 = { "NIST-P256", ECField_GFp, 256, - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", - "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", - "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", - "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", - 1, 128, 65, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT + irr256, a256, b256, x256, y256, order256, base256, + 1, 128, 66, 32, + KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT }; -static const ECCurveParams ecCurve_NIST_P384 = { +static const PRUint8 irr384[48] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }; +static const PRUint8 a384[48] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC }; +static const PRUint8 b384[48] = + { 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF }; +static const PRUint8 x384[48] = + { 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7 }; +static const PRUint8 y384[48] = + { 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, + 0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE, + 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F }; +static const PRUint8 order384[48] = + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 }; +static const PRUint8 base384[98] = + { 0x04, 0x00, + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, + 0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, + 0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C, + 0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE, + 0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F }; + +static const ECCurveBytes ecCurve_NIST_P384 = { "NIST-P384", ECField_GFp, 384, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", - "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", - "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", - "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", - 1, 192, 97, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT + irr384, a384, b384, x384, y384, order384, base384, + 1, 192, 98, 48, + KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT }; -static const ECCurveParams ecCurve_NIST_P521 = { +static const PRUint8 irr521[66] = + { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const PRUint8 a521[66] = + { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC }; +static const PRUint8 b521[66] = + { 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00 }; +static const PRUint8 x521[66] = + { 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66 }; +static const PRUint8 y521[66] = + { 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, + 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, + 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, + 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, + 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 }; +static const PRUint8 order521[66] = + { 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 }; +static const PRUint8 base521[134] = + { + 0x04, 0x00, + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, + 0x01, 0x18, 0x39, 0x29, 0x6A, 0x78, 0x9A, 0x3B, 0xC0, 0x04, 0x5C, 0x8A, + 0x5F, 0xB4, 0x2C, 0x7D, 0x1B, 0xD9, 0x98, 0xF5, 0x44, 0x49, 0x57, 0x9B, + 0x44, 0x68, 0x17, 0xAF, 0xBD, 0x17, 0x27, 0x3E, 0x66, 0x2C, 0x97, 0xEE, + 0x72, 0x99, 0x5E, 0xF4, 0x26, 0x40, 0xC5, 0x50, 0xB9, 0x01, 0x3F, 0xAD, + 0x07, 0x61, 0x35, 0x3C, 0x70, 0x86, 0xA2, 0x72, 0xC2, 0x40, 0x88, 0xBE, + 0x94, 0x76, 0x9F, 0xD1, 0x66, 0x50 + }; + +static const ECCurveBytes ecCurve_NIST_P521 = { "NIST-P521", ECField_GFp, 521, - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", - "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", - "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", - "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", - 1, 256, 133, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT + irr521, a521, b521, x521, y521, order521, base521, + 1, 256, 134, 66, + KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT }; -static const ECCurveParams ecCurve25519 = { +static const PRUint8 irr25519[32] = + { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }; +static const PRUint8 a25519[32] = + { 0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const PRUint8 b25519[32] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const PRUint8 x25519[32] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09 }; +static const PRUint8 y25519[32] = + { 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d, + 0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0, + 0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20 }; +static const PRUint8 order25519[32] = + { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, + 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; +static const PRUint8 base25519[66] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, + 0xd9, 0xd3, 0xce, 0x7e, 0xa2, 0xc5, 0xe9, 0x29, 0xb2, 0x61, 0x7c, 0x6d, + 0x7e, 0x4d, 0x3d, 0x92, 0x4c, 0xd1, 0x48, 0x77, 0x2c, 0xdd, 0x1e, 0xe0, + 0xb4, 0x86, 0xa0, 0xb8, 0xa1, 0x19, 0xae, 0x20, 0x00, 0x04 }; + +static const ECCurveBytes ecCurve_25519 = { "Curve25519", ECField_GFp, 255, - "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", - "076D06", - "00", - "0900000000000000000000000000000000000000000000000000000000000000", - "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9", - "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", - 8, 128, 32, KU_KEY_AGREEMENT + irr25519, a25519, b25519, x25519, y25519, order25519, base25519, + 8, 128, 66, 32, + KU_KEY_AGREEMENT }; /* mapping between ECCurveName enum and pointers to ECCurveParams */ -static const ECCurveParams *ecCurve_map[] = { +static const ECCurveBytes *ecCurve_map[] = { NULL, /* ECCurve_noName */ NULL, /* ECCurve_NIST_P192 */ NULL, /* ECCurve_NIST_P224 */ @@ -116,7 +266,7 @@ static const ECCurveParams *ecCurve_map[] = { NULL, /* ECCurve_WTLS_1 */ NULL, /* ECCurve_WTLS_8 */ NULL, /* ECCurve_WTLS_9 */ - &ecCurve25519, /* ECCurve25519 */ + &ecCurve_25519, /* ECCurve25519 */ NULL /* ECCurve_pastLastCurve */ }; diff --git a/nss/lib/freebl/ecl/ecl-priv.h b/nss/lib/freebl/ecl/ecl-priv.h index f43f193..2168559 100644 --- a/nss/lib/freebl/ecl/ecl-priv.h +++ b/nss/lib/freebl/ecl/ecl-priv.h @@ -246,12 +246,5 @@ mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name); /* Optimized point multiplication */ mp_err ec_group_set_gfp256_32(ECGroup *group, ECCurveName name); -/* Optimized floating-point arithmetic */ -#ifdef ECL_USE_FP -mp_err ec_group_set_secp160r1_fp(ECGroup *group); -mp_err ec_group_set_nistp192_fp(ECGroup *group); -mp_err ec_group_set_nistp224_fp(ECGroup *group); -#endif - SECStatus ec_Curve25519_mul(PRUint8 *q, const PRUint8 *s, const PRUint8 *p); #endif /* __ecl_priv_h_ */ diff --git a/nss/lib/freebl/ecl/ecl.c b/nss/lib/freebl/ecl/ecl.c index 3540af7..ca87b49 100644 --- a/nss/lib/freebl/ecl/ecl.c +++ b/nss/lib/freebl/ecl/ecl.c @@ -2,11 +2,16 @@ * 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/. */ +#ifdef FREEBL_NO_DEPEND +#include "../stubs.h" +#endif + #include "mpi.h" #include "mplogic.h" #include "ecl.h" #include "ecl-priv.h" #include "ecp.h" +#include "ecl-curve.h" #include <stdlib.h> #include <string.h> @@ -128,37 +133,16 @@ CLEANUP: return group; } -/* Construct ECGroup from hex parameters and name, if any. Called by - * ECGroup_fromHex and ECGroup_fromName. */ +/* Construct an ECGroup. */ ECGroup * -ecgroup_fromNameAndHex(const ECCurveName name, - const ECCurveParams *params) +construct_ecgroup(const ECCurveName name, mp_int irr, mp_int curvea, + mp_int curveb, mp_int genx, mp_int geny, mp_int order, + int cofactor, ECField field, const char *text) { - mp_int irr, curvea, curveb, genx, geny, order; int bits; ECGroup *group = NULL; mp_err res = MP_OKAY; - /* initialize values */ - MP_DIGITS(&irr) = 0; - MP_DIGITS(&curvea) = 0; - MP_DIGITS(&curveb) = 0; - MP_DIGITS(&genx) = 0; - MP_DIGITS(&geny) = 0; - MP_DIGITS(&order) = 0; - MP_CHECKOK(mp_init(&irr)); - MP_CHECKOK(mp_init(&curvea)); - MP_CHECKOK(mp_init(&curveb)); - MP_CHECKOK(mp_init(&genx)); - MP_CHECKOK(mp_init(&geny)); - MP_CHECKOK(mp_init(&order)); - MP_CHECKOK(mp_read_radix(&irr, params->irr, 16)); - MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16)); - MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16)); - MP_CHECKOK(mp_read_radix(&genx, params->genx, 16)); - MP_CHECKOK(mp_read_radix(&geny, params->geny, 16)); - MP_CHECKOK(mp_read_radix(&order, params->order, 16)); - /* determine number of bits */ bits = mpl_significant_bits(&irr) - 1; if (bits < MP_OKAY) { @@ -167,12 +151,12 @@ ecgroup_fromNameAndHex(const ECCurveName name, } /* determine which optimizations (if any) to use */ - if (params->field == ECField_GFp) { + if (field == ECField_GFp) { switch (name) { case ECCurve_SECG_PRIME_256R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -183,7 +167,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, case ECCurve_SECG_PRIME_521R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -194,7 +178,7 @@ ecgroup_fromNameAndHex(const ECCurveName name, /* use generic arithmetic */ group = ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + &order, cofactor); if (group == NULL) { res = MP_UNDEF; goto CLEANUP; @@ -206,62 +190,95 @@ ecgroup_fromNameAndHex(const ECCurveName name, } /* set name, if any */ - if ((group != NULL) && (params->text != NULL)) { - group->text = strdup(params->text); + if ((group != NULL) && (text != NULL)) { + group->text = strdup(text); if (group->text == NULL) { res = MP_MEM; } } CLEANUP: + if (group && res != MP_OKAY) { + ECGroup_free(group); + return NULL; + } + return group; +} + +/* Construct ECGroup from parameters and name, if any. */ +ECGroup * +ecgroup_fromName(const ECCurveName name, + const ECCurveBytes *params) +{ + mp_int irr, curvea, curveb, genx, geny, order; + ECGroup *group = NULL; + mp_err res = MP_OKAY; + + /* initialize values */ + MP_DIGITS(&irr) = 0; + MP_DIGITS(&curvea) = 0; + MP_DIGITS(&curveb) = 0; + MP_DIGITS(&genx) = 0; + MP_DIGITS(&geny) = 0; + MP_DIGITS(&order) = 0; + MP_CHECKOK(mp_init(&irr)); + MP_CHECKOK(mp_init(&curvea)); + MP_CHECKOK(mp_init(&curveb)); + MP_CHECKOK(mp_init(&genx)); + MP_CHECKOK(mp_init(&geny)); + MP_CHECKOK(mp_init(&order)); + MP_CHECKOK(mp_read_unsigned_octets(&irr, params->irr, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&curvea, params->curvea, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&curveb, params->curveb, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&genx, params->genx, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&geny, params->geny, params->scalarSize)); + MP_CHECKOK(mp_read_unsigned_octets(&order, params->order, params->scalarSize)); + + group = construct_ecgroup(name, irr, curvea, curveb, genx, geny, order, + params->cofactor, params->field, params->text); + +CLEANUP: mp_clear(&irr); mp_clear(&curvea); mp_clear(&curveb); mp_clear(&genx); mp_clear(&geny); mp_clear(&order); - if (res != MP_OKAY) { + if (group && res != MP_OKAY) { ECGroup_free(group); return NULL; } return group; } -/* Construct ECGroup from hexadecimal representations of parameters. */ -ECGroup * -ECGroup_fromHex(const ECCurveParams *params) +/* Construct ECCurveBytes from an ECCurveName */ +const ECCurveBytes * +ec_GetNamedCurveParams(const ECCurveName name) { - return ecgroup_fromNameAndHex(ECCurve_noName, params); + if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) || + (ecCurve_map[name] == NULL)) { + return NULL; + } else { + return ecCurve_map[name]; + } } /* Construct ECGroup from named parameters. */ ECGroup * ECGroup_fromName(const ECCurveName name) { - ECGroup *group = NULL; - ECCurveParams *params = NULL; - mp_err res = MP_OKAY; + const ECCurveBytes *params = NULL; - params = EC_GetNamedCurveParams(name); + /* This doesn't work with Curve25519 but it's not necessary to. */ + PORT_Assert(name != ECCurve25519); + + params = ec_GetNamedCurveParams(name); if (params == NULL) { - res = MP_UNDEF; - goto CLEANUP; + return NULL; } /* construct actual group */ - group = ecgroup_fromNameAndHex(name, params); - if (group == NULL) { - res = MP_UNDEF; - goto CLEANUP; - } - -CLEANUP: - EC_FreeCurveParams(params); - if (res != MP_OKAY) { - ECGroup_free(group); - return NULL; - } - return group; + return ecgroup_fromName(name, params); } /* Validates an EC public key as described in Section 5.2.2 of X9.62. */ diff --git a/nss/lib/freebl/ecl/ecl.h b/nss/lib/freebl/ecl/ecl.h index ddcbb1f..f6d5bc4 100644 --- a/nss/lib/freebl/ecl/ecl.h +++ b/nss/lib/freebl/ecl/ecl.h @@ -11,28 +11,17 @@ #include "blapi.h" #include "ecl-exp.h" #include "mpi.h" +#include "eclt.h" struct ECGroupStr; typedef struct ECGroupStr ECGroup; -/* Construct ECGroup from hexadecimal representations of parameters. */ -ECGroup *ECGroup_fromHex(const ECCurveParams *params); - /* Construct ECGroup from named parameters. */ ECGroup *ECGroup_fromName(const ECCurveName name); /* Free an allocated ECGroup. */ void ECGroup_free(ECGroup *group); -/* Construct ECCurveParams from an ECCurveName */ -ECCurveParams *EC_GetNamedCurveParams(const ECCurveName name); - -/* Duplicates an ECCurveParams */ -ECCurveParams *ECCurveParams_dup(const ECCurveParams *params); - -/* Free an allocated ECCurveParams */ -void EC_FreeCurveParams(ECCurveParams *params); - /* Elliptic curve scalar-point multiplication. Computes Q(x, y) = k * P(x, * y). If x, y = NULL, then P is assumed to be the generator (base point) * of the group of points on the elliptic curve. Input and output values diff --git a/nss/lib/freebl/ecl/ecl_curve.c b/nss/lib/freebl/ecl/ecl_curve.c deleted file mode 100644 index cf090cf..0000000 --- a/nss/lib/freebl/ecl/ecl_curve.c +++ /dev/null @@ -1,93 +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/. */ - -#include "ecl.h" -#include "ecl-curve.h" -#include "ecl-priv.h" -#include <stdlib.h> -#include <string.h> - -#define CHECK(func) \ - if ((func) == NULL) { \ - res = 0; \ - goto CLEANUP; \ - } - -/* Duplicates an ECCurveParams */ -ECCurveParams * -ECCurveParams_dup(const ECCurveParams *params) -{ - int res = 1; - ECCurveParams *ret = NULL; - - CHECK(ret = (ECCurveParams *)calloc(1, sizeof(ECCurveParams))); - if (params->text != NULL) { - CHECK(ret->text = strdup(params->text)); - } - ret->field = params->field; - ret->size = params->size; - if (params->irr != NULL) { - CHECK(ret->irr = strdup(params->irr)); - } - if (params->curvea != NULL) { - CHECK(ret->curvea = strdup(params->curvea)); - } - if (params->curveb != NULL) { - CHECK(ret->curveb = strdup(params->curveb)); - } - if (params->genx != NULL) { - CHECK(ret->genx = strdup(params->genx)); - } - if (params->geny != NULL) { - CHECK(ret->geny = strdup(params->geny)); - } - if (params->order != NULL) { - CHECK(ret->order = strdup(params->order)); - } - ret->cofactor = params->cofactor; - -CLEANUP: - if (res != 1) { - EC_FreeCurveParams(ret); - return NULL; - } - return ret; -} - -#undef CHECK - -/* Construct ECCurveParams from an ECCurveName */ -ECCurveParams * -EC_GetNamedCurveParams(const ECCurveName name) -{ - if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) || - (ecCurve_map[name] == NULL)) { - return NULL; - } else { - return ECCurveParams_dup(ecCurve_map[name]); - } -} - -/* Free the memory allocated (if any) to an ECCurveParams object. */ -void -EC_FreeCurveParams(ECCurveParams *params) -{ - if (params == NULL) - return; - if (params->text != NULL) - free(params->text); - if (params->irr != NULL) - free(params->irr); - if (params->curvea != NULL) - free(params->curvea); - if (params->curveb != NULL) - free(params->curveb); - if (params->genx != NULL) - free(params->genx); - if (params->geny != NULL) - free(params->geny); - if (params->order != NULL) - free(params->order); - free(params); -} diff --git a/nss/lib/freebl/ecl/eclt.h b/nss/lib/freebl/ecl/eclt.h new file mode 100644 index 0000000..e763706 --- /dev/null +++ b/nss/lib/freebl/ecl/eclt.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/. */ + +/* This header holds ECC types and must not be exported publicly. */ + +#ifndef __eclt_h_ +#define __eclt_h_ + +/* byte encoding of curve parameters */ +struct ECCurveBytesStr { + char *text; + ECField field; + size_t size; + const PRUint8 *irr; + const PRUint8 *curvea; + const PRUint8 *curveb; + const PRUint8 *genx; + const PRUint8 *geny; + const PRUint8 *order; + const PRUint8 *base; + int cofactor; + int security; + size_t pointSize; + size_t scalarSize; + unsigned int usage; +}; +typedef struct ECCurveBytesStr ECCurveBytes; + +#endif /* __ecl_h_ */ diff --git a/nss/lib/freebl/ecl/ecp_25519.c b/nss/lib/freebl/ecl/ecp_25519.c index a8d4152..1e7875f 100644 --- a/nss/lib/freebl/ecl/ecp_25519.c +++ b/nss/lib/freebl/ecl/ecp_25519.c @@ -79,8 +79,7 @@ ec_Curve25519_pt_validate(const SECItem *px) 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, }; - /* The point must not be longer than 32 (it can be smaller). */ - if (px->len <= 32) { + if (px->len == 32) { p = px->data; } else { return SECFailure; diff --git a/nss/lib/freebl/ecl/ecp_jm.c b/nss/lib/freebl/ecl/ecp_jm.c index a1106ce..bd13fa0 100644 --- a/nss/lib/freebl/ecl/ecp_jm.c +++ b/nss/lib/freebl/ecl/ecp_jm.c @@ -127,6 +127,17 @@ ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz, MP_CHECKOK(group->meth->field_mul(A, qx, A, group->meth)); MP_CHECKOK(group->meth->field_mul(B, qy, B, group->meth)); + /* Check P == Q */ + if (mp_cmp(A, px) == 0) { + if (mp_cmp(B, py) == 0) { + /* If Px == Qx && Py == Qy, double P. */ + return ec_GFp_pt_dbl_jm(px, py, pz, paz4, rx, ry, rz, raz4, + scratch, group); + } + /* If Px == Qx && Py != Qy, return point at infinity. */ + return ec_GFp_pt_set_inf_jac(rx, ry, rz); + } + /* C = A - px, D = B - py */ MP_CHECKOK(group->meth->field_sub(A, px, C, group->meth)); MP_CHECKOK(group->meth->field_sub(B, py, D, group->meth)); diff --git a/nss/lib/freebl/ecl/tests/ec_naft.c b/nss/lib/freebl/ecl/tests/ec_naft.c deleted file mode 100644 index 61ef15c..0000000 --- a/nss/lib/freebl/ecl/tests/ec_naft.c +++ /dev/null @@ -1,121 +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/. */ - -#include "mpi.h" -#include "mplogic.h" -#include "ecl.h" -#include "ecp.h" -#include "ecl-priv.h" - -#include <sys/types.h> -#include <stdio.h> -#include <time.h> -#include <sys/time.h> -#include <sys/resource.h> - -/* Returns 2^e as an integer. This is meant to be used for small powers of - * two. */ -int ec_twoTo(int e); - -/* Number of bits of scalar to test */ -#define BITSIZE 160 - -/* Time k repetitions of operation op. */ -#define M_TimeOperation(op, k) \ - { \ - double dStart, dNow, dUserTime; \ - struct rusage ru; \ - int i; \ - getrusage(RUSAGE_SELF, &ru); \ - dStart = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - for (i = 0; i < k; i++) { \ - { \ - op; \ - } \ - }; \ - getrusage(RUSAGE_SELF, &ru); \ - dNow = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - dUserTime = dNow - dStart; \ - if (dUserTime) \ - printf(" %-45s\n k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \ - } - -/* Tests wNAF computation. Non-adjacent-form is discussed in the paper: D. - * Hankerson, J. Hernandez and A. Menezes, "Software implementation of - * elliptic curve cryptography over binary fields", Proc. CHES 2000. */ - -mp_err -main(void) -{ - signed char naf[BITSIZE + 1]; - ECGroup *group = NULL; - mp_int k; - mp_int *scalar; - int i, count; - int res; - int w = 5; - char s[1000]; - - /* Get a 160 bit scalar to compute wNAF from */ - group = ECGroup_fromName(ECCurve_SECG_PRIME_160R1); - scalar = &group->genx; - - /* Compute wNAF representation of scalar */ - ec_compute_wNAF(naf, BITSIZE, scalar, w); - - /* Verify correctness of representation */ - mp_init(&k); /* init k to 0 */ - - for (i = BITSIZE; i >= 0; i--) { - mp_add(&k, &k, &k); - /* digits in mp_???_d are unsigned */ - if (naf[i] >= 0) { - mp_add_d(&k, naf[i], &k); - } else { - mp_sub_d(&k, -naf[i], &k); - } - } - - if (mp_cmp(&k, scalar) != 0) { - printf("Error: incorrect NAF value.\n"); - MP_CHECKOK(mp_toradix(&k, s, 16)); - printf("NAF value %s\n", s); - MP_CHECKOK(mp_toradix(scalar, s, 16)); - printf("original value %s\n", s); - goto CLEANUP; - } - - /* Verify digits of representation are valid */ - for (i = 0; i <= BITSIZE; i++) { - if (naf[i] % 2 == 0 && naf[i] != 0) { - printf("Error: Even non-zero digit found.\n"); - goto CLEANUP; - } - if (naf[i] < -(ec_twoTo(w - 1)) || naf[i] >= ec_twoTo(w - 1)) { - printf("Error: Magnitude of naf digit too large.\n"); - goto CLEANUP; - } - } - - /* Verify sparsity of representation */ - count = w - 1; - for (i = 0; i <= BITSIZE; i++) { - if (naf[i] != 0) { - if (count < w - 1) { - printf("Error: Sparsity failed.\n"); - goto CLEANUP; - } - count = 0; - } else - count++; - } - - /* Check timing */ - M_TimeOperation(ec_compute_wNAF(naf, BITSIZE, scalar, w), 10000); - - printf("Test passed.\n"); -CLEANUP: - ECGroup_free(group); - return MP_OKAY; -} diff --git a/nss/lib/freebl/ecl/tests/ecp_test.c b/nss/lib/freebl/ecl/tests/ecp_test.c deleted file mode 100644 index dcec4d7..0000000 --- a/nss/lib/freebl/ecl/tests/ecp_test.c +++ /dev/null @@ -1,409 +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/. */ - -#include "mpi.h" -#include "mplogic.h" -#include "mpprime.h" -#include "ecl.h" -#include "ecl-curve.h" -#include "ecp.h" -#include <stdio.h> -#include <strings.h> -#include <assert.h> - -#include <time.h> -#include <sys/time.h> -#include <sys/resource.h> - -/* Time k repetitions of operation op. */ -#define M_TimeOperation(op, k) \ - { \ - double dStart, dNow, dUserTime; \ - struct rusage ru; \ - int i; \ - getrusage(RUSAGE_SELF, &ru); \ - dStart = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - for (i = 0; i < k; i++) { \ - { \ - op; \ - } \ - }; \ - getrusage(RUSAGE_SELF, &ru); \ - dNow = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec * 0.000001; \ - dUserTime = dNow - dStart; \ - if (dUserTime) \ - printf(" %-45s k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \ - } - -/* Test curve using generic field arithmetic. */ -#define ECTEST_GENERIC_GFP(name_c, name) \ - printf("Testing %s using generic implementation...\n", name_c); \ - params = EC_GetNamedCurveParams(name); \ - if (params == NULL) { \ - printf(" Error: could not construct params.\n"); \ - res = MP_NO; \ - goto CLEANUP; \ - } \ - ECGroup_free(group); \ - group = ECGroup_fromHex(params); \ - if (group == NULL) { \ - printf(" Error: could not construct group.\n"); \ - res = MP_NO; \ - goto CLEANUP; \ - } \ - MP_CHECKOK(ectest_curve_GFp(group, ectestPrint, ectestTime, 1)); \ - printf("... okay.\n"); - -/* Test curve using specific field arithmetic. */ -#define ECTEST_NAMED_GFP(name_c, name) \ - printf("Testing %s using specific implementation...\n", name_c); \ - ECGroup_free(group); \ - group = ECGroup_fromName(name); \ - if (group == NULL) { \ - printf(" Warning: could not construct group.\n"); \ - printf("... failed; continuing with remaining tests.\n"); \ - } else { \ - MP_CHECKOK(ectest_curve_GFp(group, ectestPrint, ectestTime, 0)); \ - printf("... okay.\n"); \ - } - -/* Performs basic tests of elliptic curve cryptography over prime fields. - * If tests fail, then it prints an error message, aborts, and returns an - * error code. Otherwise, returns 0. */ -int -ectest_curve_GFp(ECGroup *group, int ectestPrint, int ectestTime, - int generic) -{ - - mp_int one, order_1, gx, gy, rx, ry, n; - int size; - mp_err res; - char s[1000]; - - /* initialize values */ - MP_CHECKOK(mp_init(&one)); - MP_CHECKOK(mp_init(&order_1)); - MP_CHECKOK(mp_init(&gx)); - MP_CHECKOK(mp_init(&gy)); - MP_CHECKOK(mp_init(&rx)); - MP_CHECKOK(mp_init(&ry)); - MP_CHECKOK(mp_init(&n)); - - MP_CHECKOK(mp_set_int(&one, 1)); - MP_CHECKOK(mp_sub(&group->order, &one, &order_1)); - - /* encode base point */ - if (group->meth->field_dec) { - MP_CHECKOK(group->meth->field_dec(&group->genx, &gx, group->meth)); - MP_CHECKOK(group->meth->field_dec(&group->geny, &gy, group->meth)); - } else { - MP_CHECKOK(mp_copy(&group->genx, &gx)); - MP_CHECKOK(mp_copy(&group->geny, &gy)); - } - if (ectestPrint) { - /* output base point */ - printf(" base point P:\n"); - MP_CHECKOK(mp_toradix(&gx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&gy, s, 16)); - printf(" %s\n", s); - if (group->meth->field_enc) { - printf(" base point P (encoded):\n"); - MP_CHECKOK(mp_toradix(&group->genx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&group->geny, s, 16)); - printf(" %s\n", s); - } - } - -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ec_GFp_pt_mul_aff(&order_1, &group->genx, &group->geny, &rx, &ry, group)); - if (ectestPrint) { - printf(" (order-1)*P (affine):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth)); - if ((mp_cmp(&rx, &group->genx) != 0) || (mp_cmp(&ry, &group->geny) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ec_GFp_pt_mul_jac(&order_1, &group->genx, &group->geny, &rx, &ry, group)); - if (ectestPrint) { - printf(" (order-1)*P (jacobian):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(group->meth->field_neg(&ry, &ry, group->meth)); - if ((mp_cmp(&rx, &group->genx) != 0) || (mp_cmp(&ry, &group->geny) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ECPoint_mul(group, &order_1, NULL, NULL, &rx, &ry)); - if (ectestPrint) { - printf(" (order-1)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); - if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* multiply base point by order - 1 and check for negative of base - * point */ - MP_CHECKOK(ECPoint_mul(group, &order_1, &gx, &gy, &rx, &ry)); - if (ectestPrint) { - printf(" (order-1)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); - if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } - -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ec_GFp_pt_mul_aff(&group->order, &group->genx, &group->geny, &rx, &ry, - group)); - if (ectestPrint) { - printf(" (order)*P (affine):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - -#ifdef ECL_ENABLE_GFP_PT_MUL_JAC - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ec_GFp_pt_mul_jac(&group->order, &group->genx, &group->geny, &rx, &ry, - group)); - if (ectestPrint) { - printf(" (order)*P (jacobian):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } -#endif - - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ECPoint_mul(group, &group->order, NULL, NULL, &rx, &ry)); - if (ectestPrint) { - printf(" (order)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* multiply base point by order and check for point at infinity */ - MP_CHECKOK(ECPoint_mul(group, &group->order, &gx, &gy, &rx, &ry)); - if (ectestPrint) { - printf(" (order)*P (ECPoint_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - if (ec_GFp_pt_is_inf_aff(&rx, &ry) != MP_YES) { - printf(" Error: invalid result (expected point at infinity).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* check that (order-1)P + (order-1)P + P == (order-1)P */ - MP_CHECKOK(ECPoints_mul(group, &order_1, &order_1, &gx, &gy, &rx, &ry)); - MP_CHECKOK(ECPoints_mul(group, &one, &one, &rx, &ry, &rx, &ry)); - if (ectestPrint) { - printf(" (order-1)*P + (order-1)*P + P == (order-1)*P (ECPoints_mul):\n"); - MP_CHECKOK(mp_toradix(&rx, s, 16)); - printf(" %s\n", s); - MP_CHECKOK(mp_toradix(&ry, s, 16)); - printf(" %s\n", s); - } - MP_CHECKOK(mp_submod(&group->meth->irr, &ry, &group->meth->irr, &ry)); - if ((mp_cmp(&rx, &gx) != 0) || (mp_cmp(&ry, &gy) != 0)) { - printf(" Error: invalid result (expected (- base point)).\n"); - res = MP_NO; - goto CLEANUP; - } - - /* test validate_point function */ - if (ECPoint_validate(group, &gx, &gy) != MP_YES) { - printf(" Error: validate point on base point failed.\n"); - res = MP_NO; - goto CLEANUP; - } - MP_CHECKOK(mp_add_d(&gy, 1, &ry)); - if (ECPoint_validate(group, &gx, &ry) != MP_NO) { - printf(" Error: validate point on invalid point passed.\n"); - res = MP_NO; - goto CLEANUP; - } - - if (ectestTime) { - /* compute random scalar */ - size = mpl_significant_bits(&group->meth->irr); - if (size < MP_OKAY) { - goto CLEANUP; - } - MP_CHECKOK(mpp_random_size(&n, (size + ECL_BITS - 1) / ECL_BITS)); - MP_CHECKOK(group->meth->field_mod(&n, &n, group->meth)); - /* timed test */ - if (generic) { -#ifdef ECL_ENABLE_GFP_PT_MUL_AFF - M_TimeOperation(MP_CHECKOK(ec_GFp_pt_mul_aff(&n, &group->genx, &group->geny, &rx, &ry, - group)), - 100); -#endif - M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), - 100); - M_TimeOperation(MP_CHECKOK(ECPoints_mul(group, &n, &n, &gx, &gy, &rx, &ry)), 100); - } else { - M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, NULL, NULL, &rx, &ry)), - 100); - M_TimeOperation(MP_CHECKOK(ECPoint_mul(group, &n, &gx, &gy, &rx, &ry)), - 100); - M_TimeOperation(MP_CHECKOK(ECPoints_mul(group, &n, &n, &gx, &gy, &rx, &ry)), 100); - } - } - -CLEANUP: - mp_clear(&one); - mp_clear(&order_1); - mp_clear(&gx); - mp_clear(&gy); - mp_clear(&rx); - mp_clear(&ry); - mp_clear(&n); - if (res != MP_OKAY) { - printf(" Error: exiting with error value %i\n", res); - } - return res; -} - -/* Prints help information. */ -void -printUsage() -{ - printf("Usage: ecp_test [--print] [--time]\n"); - printf(" --print Print out results of each point arithmetic test.\n"); - printf(" --time Benchmark point operations and print results.\n"); -} - -/* Performs tests of elliptic curve cryptography over prime fields If - * tests fail, then it prints an error message, aborts, and returns an - * error code. Otherwise, returns 0. */ -int -main(int argv, char **argc) -{ - - int ectestTime = 0; - int ectestPrint = 0; - int i; - ECGroup *group = NULL; - ECCurveParams *params = NULL; - mp_err res; - - /* read command-line arguments */ - for (i = 1; i < argv; i++) { - if ((strcasecmp(argc[i], "time") == 0) || (strcasecmp(argc[i], "-time") == 0) || (strcasecmp(argc[i], "--time") == 0)) { - ectestTime = 1; - } else if ((strcasecmp(argc[i], "print") == 0) || (strcasecmp(argc[i], "-print") == 0) || (strcasecmp(argc[i], "--print") == 0)) { - ectestPrint = 1; - } else { - printUsage(); - return 0; - } - } - - /* generic arithmetic tests */ - ECTEST_GENERIC_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); - - /* specific arithmetic tests */ - ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192); - ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224); - ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256); - ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384); - ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3); - ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1); - ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1); - ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2); - ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1); - ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2); - ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); - ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); - ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2); - ECTEST_NAMED_GFP("SECP-192K1", ECCurve_SECG_PRIME_192K1); - ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1); - ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1); - ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1); - ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1); - ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1); - ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1); - ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1); - ECTEST_NAMED_GFP("WTLS-6 (112)", ECCurve_WTLS_6); - ECTEST_NAMED_GFP("WTLS-7 (160)", ECCurve_WTLS_7); - ECTEST_NAMED_GFP("WTLS-8 (112)", ECCurve_WTLS_8); - ECTEST_NAMED_GFP("WTLS-9 (160)", ECCurve_WTLS_9); - ECTEST_NAMED_GFP("WTLS-12 (224)", ECCurve_WTLS_12); - ECTEST_NAMED_GFP("Curve25519", ECCurve25519); - -CLEANUP: - EC_FreeCurveParams(params); - ECGroup_free(group); - if (res != MP_OKAY) { - printf("Error: exiting with error value %i\n", res); - } - return res; -} diff --git a/nss/lib/freebl/ecl/uint128.c b/nss/lib/freebl/ecl/uint128.c index 22cbd02..5465875 100644 --- a/nss/lib/freebl/ecl/uint128.c +++ b/nss/lib/freebl/ecl/uint128.c @@ -31,6 +31,9 @@ init128x(uint64_t x) return ret; } +#define CONSTANT_TIME_CARRY(a, b) \ + ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1)) + /* arithmetic */ uint128_t @@ -38,7 +41,7 @@ add128(uint128_t a, uint128_t b) { uint128_t ret; ret.lo = a.lo + b.lo; - ret.hi = a.hi + b.hi + (ret.lo < b.lo); + ret.hi = a.hi + b.hi + CONSTANT_TIME_CARRY(ret.lo, b.lo); return ret; } diff --git a/nss/lib/freebl/exports.gyp b/nss/lib/freebl/exports.gyp index ef81685..aded6bf 100644 --- a/nss/lib/freebl/exports.gyp +++ b/nss/lib/freebl/exports.gyp @@ -33,6 +33,7 @@ 'ec.h', 'ecl/ecl-curve.h', 'ecl/ecl.h', + 'ecl/eclt.h', 'hmacct.h', 'secmpi.h', 'secrng.h' diff --git a/nss/lib/freebl/freebl.gyp b/nss/lib/freebl/freebl.gyp index f5ae232..f754742 100644 --- a/nss/lib/freebl/freebl.gyp +++ b/nss/lib/freebl/freebl.gyp @@ -32,121 +32,55 @@ '<(DEPTH)/exports.gyp:nss_exports' ] }, + # For test builds, build a static freebl library so we can statically + # link it into the test build binary. This way we don't have to + # dlopen() the shared lib but can directly call freebl functions. { - 'target_name': '<(freebl_name)', - 'type': 'shared_library', - 'sources': [ - 'aeskeywrap.c', - 'alg2268.c', - 'alghmac.c', - 'arcfive.c', - 'arcfour.c', - 'camellia.c', - 'chacha20poly1305.c', - 'ctr.c', - 'cts.c', - 'des.c', - 'desblapi.c', - 'dh.c', - 'drbg.c', - 'dsa.c', - 'ec.c', - 'ecdecode.c', - 'ecl/ec_naf.c', - 'ecl/ecl.c', - 'ecl/ecl_curve.c', - 'ecl/ecl_gf.c', - 'ecl/ecl_mult.c', - 'ecl/ecp_25519.c', - 'ecl/ecp_256.c', - 'ecl/ecp_256_32.c', - 'ecl/ecp_384.c', - 'ecl/ecp_521.c', - 'ecl/ecp_aff.c', - 'ecl/ecp_jac.c', - 'ecl/ecp_jm.c', - 'ecl/ecp_mont.c', - 'fipsfreebl.c', - 'freeblver.c', - 'gcm.c', - 'hmacct.c', - 'jpake.c', - 'ldvector.c', - 'md2.c', - 'md5.c', - 'mpi/mp_gf2m.c', - 'mpi/mpcpucache.c', - 'mpi/mpi.c', - 'mpi/mplogic.c', - 'mpi/mpmontg.c', - 'mpi/mpprime.c', - 'pqg.c', - 'rawhash.c', - 'rijndael.c', - 'rsa.c', - 'rsapkcs.c', - 'seed.c', - 'sha512.c', - 'sha_fast.c', - 'shvfy.c', - 'sysrand.c', - 'tlsprfalg.c' + 'target_name': 'freebl_static', + 'type': 'static_library', + 'includes': [ + 'freebl_base.gypi', + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports', ], 'conditions': [ [ 'OS=="linux"', { - 'sources': [ - 'nsslowhash.c', - 'stubs.c', + 'defines!': [ + 'FREEBL_NO_DEPEND', + 'FREEBL_LOWHASH', + 'USE_HW_AES', + 'INTEL_GCM', ], 'conditions': [ - [ 'test_build==1', { - 'dependencies': [ - '<(DEPTH)/lib/util/util.gyp:nssutil3', - ], - }], [ 'target_arch=="x64"', { - 'sources': [ - 'arcfour-amd64-gas.s', + # The AES assembler code doesn't work in static test builds. + # The linker complains about non-relocatable code, and I + # currently don't know how to fix this properly. + 'sources!': [ 'intel-aes.s', 'intel-gcm.s', - 'mpi/mpi_amd64.c', - 'mpi/mpi_amd64_gas.s', - 'mpi/mp_comba.c', - ], - 'dependencies': [ - 'intel-gcm-wrap_c_lib', - ], - 'conditions': [ - [ 'cc_is_clang==1', { - 'cflags': [ - '-no-integrated-as', - ], - 'cflags_mozilla': [ - '-no-integrated-as', - ], - 'asflags_mozilla': [ - '-no-integrated-as', - ], - }], - ], - }], - [ 'target_arch=="ia32"', { - 'sources': [ - 'mpi/mpi_x86.s', - ], - }], - [ 'target_arch=="arm"', { - 'sources': [ - 'mpi/mpi_arm.c', ], }], ], - }, { - # not Linux + }], + ], + }, + { + 'target_name': '<(freebl_name)', + 'type': 'shared_library', + 'includes': [ + 'freebl_base.gypi', + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports', + ], + 'conditions': [ + [ 'OS!="linux" and OS!="android"', { 'conditions': [ [ 'moz_fold_libs==0', { 'dependencies': [ - '../util/util.gyp:nssutil3', + '<(DEPTH)/lib/util/util.gyp:nssutil3', ], }, { 'libraries': [ @@ -154,97 +88,23 @@ ], }], ], - }], - [ 'OS=="win"', { - 'sources': [ - #TODO: building with mingw should not need this. - 'ecl/uint128.c', - #TODO: clang-cl needs -msse3 here - 'intel-gcm-wrap.c', - ], - 'libraries': [ - 'advapi32.lib', - ], - 'conditions': [ - [ 'target_arch=="x64"', { - 'sources': [ - 'arcfour-amd64-masm.asm', - 'mpi/mpi_amd64.c', - 'mpi/mpi_amd64_masm.asm', - 'mpi/mp_comba_amd64_masm.asm', - 'intel-aes-x64-masm.asm', - 'intel-gcm-x64-masm.asm', - ], - }, { - # not x64 - 'sources': [ - 'mpi/mpi_x86_asm.c', - 'intel-aes-x86-masm.asm', - 'intel-gcm-x86-masm.asm', - ], - }], - ], - }], - ['target_arch=="ia32" or target_arch=="x64"', { - 'sources': [ - # All intel architectures get the 64 bit version - 'ecl/curve25519_64.c', - ], - }, { - 'sources': [ - # All non intel architectures get the generic 32 bit implementation (slow!) - 'ecl/curve25519_32.c', + }, 'target_arch=="x64"', { + 'dependencies': [ + 'intel-gcm-wrap_c_lib', ], }], - #TODO uint128.c - [ 'disable_chachapoly==0', { - 'conditions': [ - [ 'OS!="win" and target_arch=="x64"', { - 'sources': [ - 'chacha20_vec.c', - 'poly1305-donna-x64-sse2-incremental-source.c', - ], - }, { - # not x64 - 'sources': [ - 'chacha20.c', - 'poly1305.c', - ], - }], + [ 'OS=="win" and cc_is_clang==1', { + 'dependencies': [ + 'intel-gcm-wrap_c_lib', ], }], - [ 'fuzz==1', { + [ 'OS=="linux"', { 'sources': [ - 'det_rng.c', - ], - 'defines': [ - 'UNSAFE_FUZZER_MODE', - ], - }], - [ 'test_build==1', { - 'defines': [ - 'CT_VERIF', - ], - }], - [ 'OS=="mac"', { - 'conditions': [ - [ 'target_arch=="ia32"', { - 'sources': [ - 'mpi/mpi_sse2.s', - ], - 'defines': [ - 'MP_USE_UINT_DIGIT', - 'MP_ASSEMBLY_MULTIPLY', - 'MP_ASSEMBLY_SQUARE', - 'MP_ASSEMBLY_DIV_2DX1D', - ], - }], + 'nsslowhash.c', + 'stubs.c', ], }], ], - 'dependencies': [ - '<(DEPTH)/exports.gyp:nss_exports', - ], 'variables': { 'conditions': [ [ 'OS=="linux"', { @@ -254,9 +114,6 @@ }], ] }, - 'ldflags': [ - '-Wl,-Bsymbolic' - ] }, ], 'conditions': [ @@ -301,8 +158,6 @@ 'VCCLCompilerTool': { #TODO: -Ox optimize flags 'PreprocessorDefinitions': [ - 'NSS_X86_OR_X64', - 'NSS_X86', 'MP_ASSEMBLY_MULTIPLY', 'MP_ASSEMBLY_SQUARE', 'MP_ASSEMBLY_DIV_2DX1D', @@ -319,9 +174,7 @@ 'VCCLCompilerTool': { #TODO: -Ox optimize flags 'PreprocessorDefinitions': [ - 'NSS_USE_64', - 'NSS_X86_OR_X64', - 'NSS_X64', + # Should be copied to mingw defines below 'MP_IS_LITTLE_ENDIAN', 'NSS_BEVAND_ARCFOUR', 'MPI_AMD64', @@ -333,13 +186,21 @@ }, }, }], + [ 'cc_use_gnu_ld==1 and OS=="win" and target_arch=="x64"', { + 'defines': [ + 'MP_IS_LITTLE_ENDIAN', + 'NSS_BEVAND_ARCFOUR', + 'MPI_AMD64', + 'MP_ASSEMBLY_MULTIPLY', + 'NSS_USE_COMBA', + 'USE_HW_AES', + 'INTEL_GCM', + ], + }], [ 'OS!="win"', { 'conditions': [ - [ 'target_arch=="x64"', { + [ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', { 'defines': [ - 'NSS_USE_64', - 'NSS_X86_OR_X64', - 'NSS_X64', # The Makefile does version-tests on GCC, but we're not doing that here. 'HAVE_INT128_SUPPORT', ], @@ -348,24 +209,16 @@ 'ecl/uint128.c', ], }], - [ 'target_arch=="ia32"', { - 'defines': [ - 'NSS_X86_OR_X64', - 'NSS_X86', - ], - }], ], }], [ 'OS=="linux"', { 'defines': [ 'FREEBL_LOWHASH', + 'FREEBL_NO_DEPEND', ], + }], + [ 'OS=="linux" or OS=="android"', { 'conditions': [ - [ 'test_build==0', { - 'defines': [ - 'FREEBL_NO_DEPEND', - ], - }], [ 'target_arch=="x64"', { 'defines': [ 'MP_IS_LITTLE_ENDIAN', @@ -375,7 +228,7 @@ 'NSS_USE_COMBA', ], }], - [ 'target_arch=="x64" and use_msan==0', { + [ 'target_arch=="x64"', { 'defines': [ 'USE_HW_AES', 'INTEL_GCM', @@ -396,6 +249,7 @@ 'MP_ASSEMBLY_SQUARE', 'MP_USE_UINT_DIGIT', 'SHA_NO_LONG_LONG', + 'ARMHF', ], }], ], diff --git a/nss/lib/freebl/freebl_base.gypi b/nss/lib/freebl/freebl_base.gypi new file mode 100644 index 0000000..027aa27 --- /dev/null +++ b/nss/lib/freebl/freebl_base.gypi @@ -0,0 +1,201 @@ +# 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/. +{ + 'sources': [ + 'aeskeywrap.c', + 'alg2268.c', + 'alghmac.c', + 'arcfive.c', + 'arcfour.c', + 'camellia.c', + 'chacha20poly1305.c', + 'ctr.c', + 'cts.c', + 'des.c', + 'desblapi.c', + 'dh.c', + 'drbg.c', + 'dsa.c', + 'ec.c', + 'ecdecode.c', + 'ecl/ec_naf.c', + 'ecl/ecl.c', + 'ecl/ecl_gf.c', + 'ecl/ecl_mult.c', + 'ecl/ecp_25519.c', + 'ecl/ecp_256.c', + 'ecl/ecp_256_32.c', + 'ecl/ecp_384.c', + 'ecl/ecp_521.c', + 'ecl/ecp_aff.c', + 'ecl/ecp_jac.c', + 'ecl/ecp_jm.c', + 'ecl/ecp_mont.c', + 'fipsfreebl.c', + 'blinit.c', + 'freeblver.c', + 'gcm.c', + 'hmacct.c', + 'jpake.c', + 'ldvector.c', + 'md2.c', + 'md5.c', + 'mpi/mp_gf2m.c', + 'mpi/mpcpucache.c', + 'mpi/mpi.c', + 'mpi/mplogic.c', + 'mpi/mpmontg.c', + 'mpi/mpprime.c', + 'pqg.c', + 'rawhash.c', + 'rijndael.c', + 'rsa.c', + 'rsapkcs.c', + 'seed.c', + 'sha512.c', + 'sha_fast.c', + 'shvfy.c', + 'sysrand.c', + 'tlsprfalg.c' + ], + 'conditions': [ + [ 'OS=="linux" or OS=="android"', { + 'conditions': [ + [ 'target_arch=="x64"', { + 'sources': [ + 'arcfour-amd64-gas.s', + 'intel-aes.s', + 'intel-gcm.s', + 'mpi/mpi_amd64.c', + 'mpi/mpi_amd64_gas.s', + 'mpi/mp_comba.c', + ], + 'conditions': [ + [ 'cc_is_clang==1', { + 'cflags': [ + '-no-integrated-as', + ], + 'cflags_mozilla': [ + '-no-integrated-as', + ], + 'asflags_mozilla': [ + '-no-integrated-as', + ], + }], + ], + }], + [ 'target_arch=="ia32"', { + 'sources': [ + 'mpi/mpi_x86.s', + ], + }], + [ 'target_arch=="arm"', { + 'sources': [ + 'mpi/mpi_arm.c', + ], + }], + ], + }], + [ 'OS=="win"', { + 'sources': [ + #TODO: building with mingw should not need this. + 'ecl/uint128.c', + ], + 'libraries': [ + 'advapi32.lib', + ], + 'conditions': [ + [ 'cc_use_gnu_ld!=1 and target_arch=="x64"', { + 'sources': [ + 'arcfour-amd64-masm.asm', + 'mpi/mpi_amd64.c', + 'mpi/mpi_amd64_masm.asm', + 'mpi/mp_comba_amd64_masm.asm', + 'intel-aes-x64-masm.asm', + 'intel-gcm-x64-masm.asm', + ], + }], + [ 'cc_use_gnu_ld!=1 and target_arch!="x64"', { + # not x64 + 'sources': [ + 'mpi/mpi_x86_asm.c', + 'intel-aes-x86-masm.asm', + 'intel-gcm-x86-masm.asm', + ], + }], + [ 'cc_is_clang!=1', { + # MSVC + 'sources': [ + 'intel-gcm-wrap.c', + ], + }], + ], + }], + ['target_arch=="ia32" or target_arch=="x64"', { + 'sources': [ + # All intel architectures get the 64 bit version + 'ecl/curve25519_64.c', + ], + }, { + 'sources': [ + # All non intel architectures get the generic 32 bit implementation (slow!) + 'ecl/curve25519_32.c', + ], + }], + #TODO uint128.c + [ 'disable_chachapoly==0', { + 'conditions': [ + [ 'OS!="win" and target_arch=="x64"', { + 'sources': [ + 'chacha20_vec.c', + 'poly1305-donna-x64-sse2-incremental-source.c', + ], + }, { + # not x64 + 'sources': [ + 'chacha20.c', + 'poly1305.c', + ], + }], + ], + }], + [ 'fuzz==1', { + 'sources!': [ 'drbg.c' ], + 'sources': [ 'det_rng.c' ], + }], + [ 'fuzz_tls==1', { + 'defines': [ + 'UNSAFE_FUZZER_MODE', + ], + }], + [ 'ct_verif==1', { + 'defines': [ + 'CT_VERIF', + ], + }], + [ 'only_dev_random==1', { + 'defines': [ + 'SEED_ONLY_DEV_URANDOM', + ] + }], + [ 'OS=="mac"', { + 'conditions': [ + [ 'target_arch=="ia32"', { + 'sources': [ + 'mpi/mpi_sse2.s', + ], + 'defines': [ + 'MP_USE_UINT_DIGIT', + 'MP_ASSEMBLY_MULTIPLY', + 'MP_ASSEMBLY_SQUARE', + 'MP_ASSEMBLY_DIV_2DX1D', + ], + }], + ], + }], + ], + 'ldflags': [ + '-Wl,-Bsymbolic' + ], +} diff --git a/nss/lib/freebl/ldvector.c b/nss/lib/freebl/ldvector.c index fb986a6..2447a0c 100644 --- a/nss/lib/freebl/ldvector.c +++ b/nss/lib/freebl/ldvector.c @@ -294,9 +294,13 @@ static const struct FREEBLVectorStr vector = ChaCha20Poly1305_CreateContext, ChaCha20Poly1305_DestroyContext, ChaCha20Poly1305_Seal, - ChaCha20Poly1305_Open + ChaCha20Poly1305_Open, /* End of Version 3.018 */ + + EC_GetPointSize + + /* End of Version 3.019 */ }; const FREEBLVector* diff --git a/nss/lib/freebl/loader.c b/nss/lib/freebl/loader.c index 84876c1..792171b 100644 --- a/nss/lib/freebl/loader.c +++ b/nss/lib/freebl/loader.c @@ -2116,3 +2116,11 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, ctx, output, outputLen, maxOutputLen, input, inputLen, nonce, nonceLen, ad, adLen); } + +int +EC_GetPointSize(const ECParams *params) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) + return SECFailure; + return (vector->p_EC_GetPointSize)(params); +} diff --git a/nss/lib/freebl/loader.h b/nss/lib/freebl/loader.h index ced03b5..ed392cc 100644 --- a/nss/lib/freebl/loader.h +++ b/nss/lib/freebl/loader.h @@ -10,7 +10,7 @@ #include "blapi.h" -#define FREEBL_VERSION 0x0312 +#define FREEBL_VERSION 0x0313 struct FREEBLVectorStr { @@ -732,6 +732,10 @@ struct FREEBLVectorStr { /* Version 3.018 came to here */ + int (*p_EC_GetPointSize)(const ECParams *); + + /* Version 3.019 came to here */ + /* Add new function pointers at the end of this struct and bump * FREEBL_VERSION at the beginning of this file. */ }; diff --git a/nss/lib/freebl/manifest.mn b/nss/lib/freebl/manifest.mn index 1ef9839..bf81442 100644 --- a/nss/lib/freebl/manifest.mn +++ b/nss/lib/freebl/manifest.mn @@ -94,6 +94,7 @@ PRIVATE_EXPORTS = \ ec.h \ ecl.h \ ecl-curve.h \ + eclt.h \ $(NULL) MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h @@ -102,7 +103,7 @@ MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c ECL_HDRS = ecl-exp.h ecl.h ecp.h ecl-priv.h ifndef NSS_DISABLE_ECC -ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \ +ECL_SRCS = ecl.c ecl_mult.c ecl_gf.c \ ecp_aff.c ecp_jac.c ecp_mont.c \ ec_naf.c ecp_jm.c ecp_256.c ecp_384.c ecp_521.c \ ecp_256_32.c ecp_25519.c @@ -131,6 +132,7 @@ CSRCS = \ chacha20poly1305.c \ cts.c \ ctr.c \ + blinit.c \ fipsfreebl.c \ gcm.c \ hmacct.c \ diff --git a/nss/lib/freebl/mpi/README b/nss/lib/freebl/mpi/README index 475549b..f1c66df 100644 --- a/nss/lib/freebl/mpi/README +++ b/nss/lib/freebl/mpi/README @@ -503,9 +503,6 @@ MP_MODARITH - Define true to include the modular arithmetic in your application, you can set this to zero to leave out all the modular routines. -MP_NUMTH - Define true to include number theoretic functions - such as mp_gcd(), mp_lcm(), and mp_invmod(). - MP_LOGTAB - If true, the file "logtab.h" is included, which is basically a static table of base 2 logarithms. These are used to compute how big the buffers for diff --git a/nss/lib/freebl/mpi/mpi-config.h b/nss/lib/freebl/mpi/mpi-config.h index f365592..c6f72b2 100644 --- a/nss/lib/freebl/mpi/mpi-config.h +++ b/nss/lib/freebl/mpi/mpi-config.h @@ -24,10 +24,6 @@ #define MP_MODARITH 1 /* include modular arithmetic ? */ #endif -#ifndef MP_NUMTH -#define MP_NUMTH 1 /* include number theoretic functions? */ -#endif - #ifndef MP_LOGTAB #define MP_LOGTAB 1 /* use table of logs instead of log()? */ #endif diff --git a/nss/lib/freebl/mpi/mpi.c b/nss/lib/freebl/mpi/mpi.c index f6f7543..f7784c8 100644 --- a/nss/lib/freebl/mpi/mpi.c +++ b/nss/lib/freebl/mpi/mpi.c @@ -1695,7 +1695,6 @@ mp_iseven(const mp_int *a) /*------------------------------------------------------------------------*/ /* {{{ Number theoretic functions */ -#if MP_NUMTH /* {{{ mp_gcd(a, b, c) */ /* @@ -2376,7 +2375,6 @@ mp_invmod(const mp_int *a, const mp_int *m, mp_int *c) } /* end mp_invmod() */ /* }}} */ -#endif /* if MP_NUMTH */ /* }}} */ @@ -2861,6 +2859,9 @@ void s_mp_exch(mp_int *a, mp_int *b) { mp_int tmp; + if (!a || !b) { + return; + } tmp = *a; *a = *b; @@ -4088,7 +4089,7 @@ s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps) } #endif -#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) && !defined(MP_ASSEMBLY_DIV_2DX1D) +#if !defined(MP_ASSEMBLY_DIV_2DX1D) /* ** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized ** so its high bit is 1. This code is from NSPR. @@ -4166,11 +4167,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ mp_int *quot) /* i: 0; o: quotient */ { mp_int part, t; -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - mp_word q_msd; -#else mp_digit q_msd; -#endif mp_err res; mp_digit d; mp_digit div_msd; @@ -4215,7 +4212,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ MP_USED(&part) = MP_USED(div); /* We have now truncated the part of the remainder to the same length as - * the divisor. If part is smaller than div, extend part by one digit. */ + * the divisor. If part is smaller than div, extend part by one digit. */ if (s_mp_cmp(&part, div) < 0) { --unusedRem; #if MP_ARGCHK == 2 @@ -4232,18 +4229,12 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ div_msd = MP_DIGIT(div, MP_USED(div) - 1); if (!partExtended) { /* In this case, q_msd /= div_msd is always 1. First, since div_msd is - * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since - * we didn't extend part, q_msd >= div_msd. Therefore we know that - * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we - * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ + * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since + * we didn't extend part, q_msd >= div_msd. Therefore we know that + * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we + * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ q_msd = 1; } else { -#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) - q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2); - q_msd /= div_msd; - if (q_msd == RADIX) - --q_msd; -#else if (q_msd == div_msd) { q_msd = MP_DIGIT_MAX; } else { @@ -4251,7 +4242,6 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ MP_CHECKOK(s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), div_msd, &q_msd, &r)); } -#endif } #if MP_ARGCHK == 2 assert(q_msd > 0); /* This case should never occur any more. */ @@ -4261,15 +4251,15 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ /* See what that multiplies out to */ mp_copy(div, &t); - MP_CHECKOK(s_mp_mul_d(&t, (mp_digit)q_msd)); + MP_CHECKOK(s_mp_mul_d(&t, q_msd)); /* - If it's too big, back it off. We should not have to do this - more than once, or, in rare cases, twice. Knuth describes a - method by which this could be reduced to a maximum of once, but - I didn't implement that here. - * When using s_mpv_div_2dx1d, we may have to do this 3 times. - */ + If it's too big, back it off. We should not have to do this + more than once, or, in rare cases, twice. Knuth describes a + method by which this could be reduced to a maximum of once, but + I didn't implement that here. + When using s_mpv_div_2dx1d, we may have to do this 3 times. + */ for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) { --q_msd; MP_CHECKOK(s_mp_sub(&t, div)); /* t -= div */ @@ -4284,11 +4274,11 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ s_mp_clamp(rem); /* - Include the digit in the quotient. We allocated enough memory - for any quotient we could ever possibly get, so we should not - have to check for failures here - */ - MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd; + Include the digit in the quotient. We allocated enough memory + for any quotient we could ever possibly get, so we should not + have to check for failures here + */ + MP_DIGIT(quot, unusedRem) = q_msd; } /* Denormalize remainder */ diff --git a/nss/lib/freebl/mpi/mpi.h b/nss/lib/freebl/mpi/mpi.h index 64ffe75..97af0f0 100644 --- a/nss/lib/freebl/mpi/mpi.h +++ b/nss/lib/freebl/mpi/mpi.h @@ -225,13 +225,11 @@ int mp_isodd(const mp_int *a); int mp_iseven(const mp_int *a); /* Number theoretic */ -#if MP_NUMTH mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c); mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c); mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y); mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c); mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c); -#endif /* end MP_NUMTH */ /* Input and output */ #if MP_IOFUNC diff --git a/nss/lib/freebl/mpi/mpprime.c b/nss/lib/freebl/mpi/mpprime.c index 5828719..9d6232c 100644 --- a/nss/lib/freebl/mpi/mpprime.c +++ b/nss/lib/freebl/mpi/mpprime.c @@ -402,8 +402,7 @@ mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, #define SIEVE_SIZE 32 * 1024 mp_err -mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, - unsigned long *nTries) +mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong) { mp_digit np; mp_err res; @@ -548,8 +547,6 @@ mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, CLEANUP: mp_clear(&trial); mp_clear(&q); - if (nTries) - *nTries += i; if (sieve != NULL) { memset(sieve, 0, SIEVE_SIZE); free(sieve); diff --git a/nss/lib/freebl/mpi/mpprime.h b/nss/lib/freebl/mpi/mpprime.h index c47c618..acd888d 100644 --- a/nss/lib/freebl/mpi/mpprime.h +++ b/nss/lib/freebl/mpi/mpprime.h @@ -13,6 +13,8 @@ #include "mpi.h" +SEC_BEGIN_PROTOS + extern const int prime_tab_size; /* number of primes available */ extern const mp_digit prime_tab[]; @@ -32,7 +34,8 @@ mp_err mpp_fermat_list(mp_int *a, const mp_digit *primes, mp_size nPrimes); mp_err mpp_pprime(mp_int *a, int nt); mp_err mpp_sieve(mp_int *trial, const mp_digit *primes, mp_size nPrimes, unsigned char *sieve, mp_size nSieve); -mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, - unsigned long *nTries); +mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong); + +SEC_END_PROTOS #endif /* end _H_MP_PRIME_ */ diff --git a/nss/lib/freebl/os2_rand.c b/nss/lib/freebl/os2_rand.c deleted file mode 100644 index 407b080..0000000 --- a/nss/lib/freebl/os2_rand.c +++ /dev/null @@ -1,334 +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/. */ - -#define INCL_DOS -#define INCL_DOSERRORS -#include <os2.h> -#include "secrng.h" -#include "prerror.h" -#include <stdlib.h> -#include <time.h> -#include <stdio.h> -#include <sys/stat.h> - -static BOOL -clockTickTime(unsigned long *phigh, unsigned long *plow) -{ - APIRET rc = NO_ERROR; - QWORD qword = { 0, 0 }; - - rc = DosTmrQueryTime(&qword); - if (rc != NO_ERROR) - return FALSE; - - *phigh = qword.ulHi; - *plow = qword.ulLo; - - return TRUE; -} - -size_t -RNG_GetNoise(void *buf, size_t maxbuf) -{ - unsigned long high = 0; - unsigned long low = 0; - clock_t val = 0; - int n = 0; - int nBytes = 0; - time_t sTime; - - if (maxbuf <= 0) - return 0; - - clockTickTime(&high, &low); - - /* get the maximally changing bits first */ - nBytes = sizeof(low) > maxbuf ? maxbuf : sizeof(low); - memcpy(buf, &low, nBytes); - n += nBytes; - maxbuf -= nBytes; - - if (maxbuf <= 0) - return n; - - nBytes = sizeof(high) > maxbuf ? maxbuf : sizeof(high); - memcpy(((char *)buf) + n, &high, nBytes); - n += nBytes; - maxbuf -= nBytes; - - if (maxbuf <= 0) - return n; - - /* get the number of milliseconds that have elapsed since application started */ - val = clock(); - - nBytes = sizeof(val) > maxbuf ? maxbuf : sizeof(val); - memcpy(((char *)buf) + n, &val, nBytes); - n += nBytes; - maxbuf -= nBytes; - - if (maxbuf <= 0) - return n; - - /* get the time in seconds since midnight Jan 1, 1970 */ - time(&sTime); - nBytes = sizeof(sTime) > maxbuf ? maxbuf : sizeof(sTime); - memcpy(((char *)buf) + n, &sTime, nBytes); - n += nBytes; - - return n; -} - -static BOOL -EnumSystemFiles(void (*func)(const char *)) -{ - APIRET rc; - ULONG sysInfo = 0; - char bootLetter[2]; - char sysDir[_MAX_PATH] = ""; - char filename[_MAX_PATH]; - HDIR hdir = HDIR_CREATE; - ULONG numFiles = 1; - FILEFINDBUF3 fileBuf = { 0 }; - ULONG buflen = sizeof(FILEFINDBUF3); - - if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PVOID)&sysInfo, - sizeof(ULONG)) == NO_ERROR) { - bootLetter[0] = sysInfo + 'A' - 1; - bootLetter[1] = '\0'; - strcpy(sysDir, bootLetter); - strcpy(sysDir + 1, ":\\OS2\\"); - - strcpy(filename, sysDir); - strcat(filename, "*.*"); - } - - rc = DosFindFirst(filename, &hdir, FILE_NORMAL, &fileBuf, buflen, - &numFiles, FIL_STANDARD); - if (rc == NO_ERROR) { - do { - // pass the full pathname to the callback - sprintf(filename, "%s%s", sysDir, fileBuf.achName); - (*func)(filename); - - numFiles = 1; - rc = DosFindNext(hdir, &fileBuf, buflen, &numFiles); - if (rc != NO_ERROR && rc != ERROR_NO_MORE_FILES) - printf("DosFindNext errod code = %d\n", rc); - } while (rc == NO_ERROR); - - rc = DosFindClose(hdir); - if (rc != NO_ERROR) - printf("DosFindClose error code = %d", rc); - } else - printf("DosFindFirst error code = %d", rc); - - return TRUE; -} - -static int dwNumFiles, dwReadEvery, dwFileToRead = 0; - -static void -CountFiles(const char *file) -{ - dwNumFiles++; -} - -static void -ReadFiles(const char *file) -{ - if ((dwNumFiles % dwReadEvery) == 0) - RNG_FileForRNG(file); - - dwNumFiles++; -} - -static void -ReadSingleFile(const char *filename) -{ - unsigned char buffer[1024]; - FILE *file; - - file = fopen((char *)filename, "rb"); - if (file != NULL) { - while (fread(buffer, 1, sizeof(buffer), file) > 0) - ; - fclose(file); - } -} - -static void -ReadOneFile(const char *file) -{ - if (dwNumFiles == dwFileToRead) { - ReadSingleFile(file); - } - - dwNumFiles++; -} - -static void -ReadSystemFiles(void) -{ - // first count the number of files - dwNumFiles = 0; - if (!EnumSystemFiles(CountFiles)) - return; - - RNG_RandomUpdate(&dwNumFiles, sizeof(dwNumFiles)); - - // now read 10 files - if (dwNumFiles == 0) - return; - - dwReadEvery = dwNumFiles / 10; - if (dwReadEvery == 0) - dwReadEvery = 1; // less than 10 files - - dwNumFiles = 0; - EnumSystemFiles(ReadFiles); -} - -void -RNG_SystemInfoForRNG(void) -{ - unsigned long *plong = 0; - PTIB ptib; - PPIB ppib; - APIRET rc = NO_ERROR; - DATETIME dt; - COUNTRYCODE cc = { 0 }; - COUNTRYINFO ci = { 0 }; - unsigned long actual = 0; - char path[_MAX_PATH] = ""; - char fullpath[_MAX_PATH] = ""; - unsigned long pathlength = sizeof(path); - FSALLOCATE fsallocate; - FILESTATUS3 fstatus; - unsigned long defaultdrive = 0; - unsigned long logicaldrives = 0; - unsigned long sysInfo[QSV_MAX] = { 0 }; - char buffer[20]; - int nBytes = 0; - - nBytes = RNG_GetNoise(buffer, sizeof(buffer)); - RNG_RandomUpdate(buffer, nBytes); - - /* allocate memory and use address and memory */ - plong = (unsigned long *)malloc(sizeof(*plong)); - RNG_RandomUpdate(&plong, sizeof(plong)); - RNG_RandomUpdate(plong, sizeof(*plong)); - free(plong); - - /* process info */ - rc = DosGetInfoBlocks(&ptib, &ppib); - if (rc == NO_ERROR) { - RNG_RandomUpdate(ptib, sizeof(*ptib)); - RNG_RandomUpdate(ppib, sizeof(*ppib)); - } - - /* time */ - rc = DosGetDateTime(&dt); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&dt, sizeof(dt)); - } - - /* country */ - rc = DosQueryCtryInfo(sizeof(ci), &cc, &ci, &actual); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&cc, sizeof(cc)); - RNG_RandomUpdate(&ci, sizeof(ci)); - RNG_RandomUpdate(&actual, sizeof(actual)); - } - - /* current directory */ - rc = DosQueryCurrentDir(0, path, &pathlength); - strcat(fullpath, "\\"); - strcat(fullpath, path); - if (rc == NO_ERROR) { - RNG_RandomUpdate(fullpath, strlen(fullpath)); - // path info - rc = DosQueryPathInfo(fullpath, FIL_STANDARD, &fstatus, sizeof(fstatus)); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&fstatus, sizeof(fstatus)); - } - } - - /* file system info */ - rc = DosQueryFSInfo(0, FSIL_ALLOC, &fsallocate, sizeof(fsallocate)); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&fsallocate, sizeof(fsallocate)); - } - - /* drive info */ - rc = DosQueryCurrentDisk(&defaultdrive, &logicaldrives); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&defaultdrive, sizeof(defaultdrive)); - RNG_RandomUpdate(&logicaldrives, sizeof(logicaldrives)); - } - - /* system info */ - rc = DosQuerySysInfo(1L, QSV_MAX, (PVOID)&sysInfo, sizeof(ULONG) * QSV_MAX); - if (rc == NO_ERROR) { - RNG_RandomUpdate(&sysInfo, sizeof(sysInfo)); - } - - // now let's do some files - ReadSystemFiles(); - - /* more noise */ - nBytes = RNG_GetNoise(buffer, sizeof(buffer)); - RNG_RandomUpdate(buffer, nBytes); -} - -void -RNG_FileForRNG(const char *filename) -{ - struct stat stat_buf; - unsigned char buffer[1024]; - FILE *file = 0; - int nBytes = 0; - static int totalFileBytes = 0; - - if (stat((char *)filename, &stat_buf) < 0) - return; - - RNG_RandomUpdate((unsigned char *)&stat_buf, sizeof(stat_buf)); - - file = fopen((char *)filename, "r"); - if (file != NULL) { - for (;;) { - size_t bytes = fread(buffer, 1, sizeof(buffer), file); - - if (bytes == 0) - break; - - RNG_RandomUpdate(buffer, bytes); - totalFileBytes += bytes; - if (totalFileBytes > 250000) - break; - } - fclose(file); - } - - nBytes = RNG_GetNoise(buffer, 20); - RNG_RandomUpdate(buffer, nBytes); -} - -static void -rng_systemJitter(void) -{ - dwNumFiles = 0; - EnumSystemFiles(ReadOneFile); - dwFileToRead++; - if (dwFileToRead >= dwNumFiles) { - dwFileToRead = 0; - } -} - -size_t -RNG_SystemRNG(void *dest, size_t maxLen) -{ - return rng_systemFromNoise(dest, maxLen); -} diff --git a/nss/lib/freebl/rijndael.c b/nss/lib/freebl/rijndael.c index 4bb1826..0c3ab58 100644 --- a/nss/lib/freebl/rijndael.c +++ b/nss/lib/freebl/rijndael.c @@ -26,17 +26,11 @@ #include "mpi.h" #ifdef USE_HW_AES -static int has_intel_aes = 0; static PRBool use_hw_aes = PR_FALSE; #ifdef INTEL_GCM #include "intel-gcm.h" -static int has_intel_avx = 0; -static int has_intel_clmul = 0; static PRBool use_hw_gcm = PR_FALSE; -#if defined(_MSC_VER) && !defined(_M_IX86) -#include <intrin.h> /* for _xgetbv() */ -#endif #endif #endif /* USE_HW_AES */ @@ -999,39 +993,6 @@ AES_AllocateContext(void) return PORT_ZNew(AESContext); } -#ifdef INTEL_GCM -/* - * Adapted from the example code in "How to detect New Instruction support in - * the 4th generation Intel Core processor family" by Max Locktyukhin. - * - * XGETBV: - * Reads an extended control register (XCR) specified by ECX into EDX:EAX. - */ -static PRBool -check_xcr0_ymm() -{ - PRUint32 xcr0; -#if defined(_MSC_VER) -#if defined(_M_IX86) - __asm { - mov ecx, 0 - xgetbv - mov xcr0, eax - } -#else - xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */ -#endif -#else - __asm__("xgetbv" - : "=a"(xcr0) - : "c"(0) - : "%edx"); -#endif - /* Check if xmm and ymm state are enabled in XCR0. */ - return (xcr0 & 6) == 6; -} -#endif - /* ** Initialize a new AES context suitable for AES encryption/decryption in ** the ECB or CBC mode. @@ -1070,33 +1031,9 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, return SECFailure; } #ifdef USE_HW_AES - if (has_intel_aes == 0) { - unsigned long eax, ebx, ecx, edx; - char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES"); - - if (disable_hw_aes == NULL) { - freebl_cpuid(1, &eax, &ebx, &ecx, &edx); - has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1; -#ifdef INTEL_GCM - has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1; - if ((ecx & (1 << 27)) != 0 && (ecx & (1 << 28)) != 0 && - check_xcr0_ymm()) { - has_intel_avx = 1; - } else { - has_intel_avx = -1; - } -#endif - } else { - has_intel_aes = -1; -#ifdef INTEL_GCM - has_intel_avx = -1; - has_intel_clmul = -1; -#endif - } - } - use_hw_aes = (PRBool)(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16); + use_hw_aes = aesni_support() && (keysize % 8) == 0 && blocksize == 16; #ifdef INTEL_GCM - use_hw_gcm = (PRBool)(use_hw_aes && has_intel_avx > 0 && has_intel_clmul > 0); + use_hw_gcm = use_hw_aes && avx_support() && clmul_support(); #endif #endif /* USE_HW_AES */ /* Nb = (block size in bits) / 32 */ diff --git a/nss/lib/freebl/rsa.c b/nss/lib/freebl/rsa.c index ff8c40e..17d1d87 100644 --- a/nss/lib/freebl/rsa.c +++ b/nss/lib/freebl/rsa.c @@ -190,12 +190,12 @@ cleanup: } return rv; } -static SECStatus + +SECStatus generate_prime(mp_int *prime, int primeLen) { mp_err err = MP_OKAY; SECStatus rv = SECSuccess; - unsigned long counter = 0; int piter; unsigned char *pb = NULL; pb = PORT_Alloc(primeLen); @@ -208,7 +208,7 @@ generate_prime(mp_int *prime, int primeLen) pb[0] |= 0xC0; /* set two high-order bits */ pb[primeLen - 1] |= 0x01; /* set low-order bit */ CHECK_MPI_OK(mp_read_unsigned_octets(prime, pb, primeLen)); - err = mpp_make_prime(prime, primeLen * 8, PR_FALSE, &counter); + err = mpp_make_prime(prime, primeLen * 8, PR_FALSE); if (err != MP_NO) goto cleanup; /* keep going while err == MP_NO */ @@ -1236,7 +1236,10 @@ get_blinding_params(RSAPrivateKey *key, mp_int *n, unsigned int modLen, * Now, search its list of ready blinding params for a usable one. */ while (0 != (bp = rsabp->bp)) { - if (--(bp->counter) > 0) { +#ifndef UNSAFE_FUZZER_MODE + if (--(bp->counter) > 0) +#endif + { /* Found a match and there are still remaining uses left */ /* Return the parameters */ CHECK_MPI_OK(mp_copy(&bp->f, f)); @@ -1548,7 +1551,7 @@ cleanup: return rv; } -static SECStatus +SECStatus RSA_Init(void) { if (PR_CallOnce(&coBPInit, init_blinding_params_list) != PR_SUCCESS) { @@ -1558,12 +1561,6 @@ RSA_Init(void) return SECSuccess; } -SECStatus -BL_Init(void) -{ - return RSA_Init(); -} - /* cleanup at shutdown */ void RSA_Cleanup(void) diff --git a/nss/lib/freebl/rsapkcs.c b/nss/lib/freebl/rsapkcs.c index 577fe1f..c8a15da 100644 --- a/nss/lib/freebl/rsapkcs.c +++ b/nss/lib/freebl/rsapkcs.c @@ -85,6 +85,25 @@ rsa_modulusLen(SECItem *modulus) return modLen; } +static unsigned int +rsa_modulusBits(SECItem *modulus) +{ + unsigned char byteZero = modulus->data[0]; + unsigned int numBits = (modulus->len - 1) * 8; + + if (byteZero == 0) { + numBits -= 8; + byteZero = modulus->data[1]; + } + + while (byteZero > 0) { + numBits++; + byteZero >>= 1; + } + + return numBits; +} + /* * Format one block of data for public/private key encryption using * the rules defined in PKCS #1. @@ -962,12 +981,11 @@ failure: * We use mHash instead of M as input. * emBits from the RFC is just modBits - 1, see section 8.1.1. * We only support MGF1 as the MGF. - * - * NOTE: this code assumes modBits is a multiple of 8. */ static SECStatus emsa_pss_encode(unsigned char *em, unsigned int emLen, + unsigned int emBits, const unsigned char *mHash, HASH_HashType hashAlg, HASH_HashType maskHashAlg, @@ -1032,7 +1050,7 @@ emsa_pss_encode(unsigned char *em, PORT_Free(dbMask); /* Step 11 */ - em[0] &= 0x7f; + em[0] &= 0xff >> (8 * emLen - emBits); /* Step 12 */ em[emLen - 1] = 0xbc; @@ -1046,13 +1064,12 @@ emsa_pss_encode(unsigned char *em, * We use mHash instead of M as input. * emBits from the RFC is just modBits - 1, see section 8.1.2. * We only support MGF1 as the MGF. - * - * NOTE: this code assumes modBits is a multiple of 8. */ static SECStatus emsa_pss_verify(const unsigned char *mHash, const unsigned char *em, unsigned int emLen, + unsigned int emBits, HASH_HashType hashAlg, HASH_HashType maskHashAlg, unsigned int saltLen) @@ -1063,15 +1080,22 @@ emsa_pss_verify(const unsigned char *mHash, unsigned char *H_; /* H' from the RFC */ unsigned int i; unsigned int dbMaskLen; + unsigned int zeroBits; SECStatus rv; hash = HASH_GetRawHashObject(hashAlg); dbMaskLen = emLen - hash->length - 1; - /* Step 3 + 4 + 6 */ + /* Step 3 + 4 */ if ((emLen < (hash->length + saltLen + 2)) || - (em[emLen - 1] != 0xbc) || - ((em[0] & 0x80) != 0)) { + (em[emLen - 1] != 0xbc)) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + return SECFailure; + } + + /* Step 6 */ + zeroBits = 8 * emLen - emBits; + if (em[0] >> (8 - zeroBits)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } @@ -1091,7 +1115,7 @@ emsa_pss_verify(const unsigned char *mHash, } /* Step 9 */ - db[0] &= 0x7f; + db[0] &= 0xff >> zeroBits; /* Step 10 */ for (i = 0; i < (dbMaskLen - saltLen - 1); i++) { @@ -1156,7 +1180,9 @@ RSA_SignPSS(RSAPrivateKey *key, { SECStatus rv = SECSuccess; unsigned int modulusLen = rsa_modulusLen(&key->modulus); - unsigned char *pssEncoded = NULL; + unsigned int modulusBits = rsa_modulusBits(&key->modulus); + unsigned int emLen = modulusLen; + unsigned char *pssEncoded, *em; if (maxOutputLen < modulusLen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); @@ -1168,16 +1194,24 @@ RSA_SignPSS(RSAPrivateKey *key, return SECFailure; } - pssEncoded = (unsigned char *)PORT_Alloc(modulusLen); + pssEncoded = em = (unsigned char *)PORT_Alloc(modulusLen); if (pssEncoded == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } - rv = emsa_pss_encode(pssEncoded, modulusLen, input, hashAlg, + + /* len(em) == ceil((modulusBits - 1) / 8). */ + if (modulusBits % 8 == 1) { + em[0] = 0; + emLen--; + em++; + } + rv = emsa_pss_encode(em, emLen, modulusBits - 1, input, hashAlg, maskHashAlg, salt, saltLength); if (rv != SECSuccess) goto done; + // This sets error codes upon failure. rv = RSA_PrivateKeyOpDoubleChecked(key, output, pssEncoded); *outputLen = modulusLen; @@ -1198,7 +1232,9 @@ RSA_CheckSignPSS(RSAPublicKey *key, { SECStatus rv; unsigned int modulusLen = rsa_modulusLen(&key->modulus); - unsigned char *buffer; + unsigned int modulusBits = rsa_modulusBits(&key->modulus); + unsigned int emLen = modulusLen; + unsigned char *buffer, *em; if (sigLen != modulusLen) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); @@ -1210,7 +1246,7 @@ RSA_CheckSignPSS(RSAPublicKey *key, return SECFailure; } - buffer = (unsigned char *)PORT_Alloc(modulusLen); + buffer = em = (unsigned char *)PORT_Alloc(modulusLen); if (!buffer) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; @@ -1223,14 +1259,18 @@ RSA_CheckSignPSS(RSAPublicKey *key, return SECFailure; } - rv = emsa_pss_verify(hash, buffer, modulusLen, hashAlg, + /* len(em) == ceil((modulusBits - 1) / 8). */ + if (modulusBits % 8 == 1) { + emLen--; + em++; + } + rv = emsa_pss_verify(hash, em, emLen, modulusBits - 1, hashAlg, maskHashAlg, saltLength); - PORT_Free(buffer); + PORT_Free(buffer); return rv; } -/* XXX Doesn't set error code */ SECStatus RSA_Sign(RSAPrivateKey *key, unsigned char *output, @@ -1239,34 +1279,34 @@ RSA_Sign(RSAPrivateKey *key, const unsigned char *input, unsigned int inputLen) { - SECStatus rv = SECSuccess; + SECStatus rv = SECFailure; unsigned int modulusLen = rsa_modulusLen(&key->modulus); - SECItem formatted; - SECItem unformatted; + SECItem formatted = { siBuffer, NULL, 0 }; + SECItem unformatted = { siBuffer, (unsigned char *)input, inputLen }; - if (maxOutputLen < modulusLen) - return SECFailure; + if (maxOutputLen < modulusLen) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + goto done; + } - unformatted.len = inputLen; - unformatted.data = (unsigned char *)input; - formatted.data = NULL; rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPrivate, &unformatted); - if (rv != SECSuccess) + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); goto done; + } + // This sets error codes upon failure. rv = RSA_PrivateKeyOpDoubleChecked(key, output, formatted.data); *outputLen = modulusLen; - goto done; - done: - if (formatted.data != NULL) + if (formatted.data != NULL) { PORT_ZFree(formatted.data, modulusLen); + } return rv; } -/* XXX Doesn't set error code */ SECStatus RSA_CheckSign(RSAPublicKey *key, const unsigned char *sig, @@ -1274,60 +1314,71 @@ RSA_CheckSign(RSAPublicKey *key, const unsigned char *data, unsigned int dataLen) { - SECStatus rv; + SECStatus rv = SECFailure; unsigned int modulusLen = rsa_modulusLen(&key->modulus); unsigned int i; - unsigned char *buffer; + unsigned char *buffer = NULL; + + if (sigLen != modulusLen) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } - if (sigLen != modulusLen) - goto failure; /* * 0x00 || BT || Pad || 0x00 || ActualData * * The "3" below is the first octet + the second octet + the 0x00 * octet that always comes just before the ActualData. */ - if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)) - goto failure; + if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)) { + PORT_SetError(SEC_ERROR_BAD_DATA); + goto done; + } buffer = (unsigned char *)PORT_Alloc(modulusLen + 1); - if (!buffer) - goto failure; + if (!buffer) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + goto done; + } - rv = RSA_PublicKeyOp(key, buffer, sig); - if (rv != SECSuccess) - goto loser; + if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } /* * check the padding that was used */ if (buffer[0] != RSA_BLOCK_FIRST_OCTET || buffer[1] != (unsigned char)RSA_BlockPrivate) { - goto loser; + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; } for (i = 2; i < modulusLen - dataLen - 1; i++) { - if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) - goto loser; + if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } + } + if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; } - if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET) - goto loser; /* * make sure we get the same results */ - if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) != 0) - goto loser; - - PORT_Free(buffer); - return SECSuccess; + if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) == 0) { + rv = SECSuccess; + } -loser: - PORT_Free(buffer); -failure: - return SECFailure; +done: + if (buffer) { + PORT_Free(buffer); + } + return rv; } -/* XXX Doesn't set error code */ SECStatus RSA_CheckSignRecover(RSAPublicKey *key, unsigned char *output, @@ -1336,21 +1387,27 @@ RSA_CheckSignRecover(RSAPublicKey *key, const unsigned char *sig, unsigned int sigLen) { - SECStatus rv; + SECStatus rv = SECFailure; unsigned int modulusLen = rsa_modulusLen(&key->modulus); unsigned int i; - unsigned char *buffer; + unsigned char *buffer = NULL; - if (sigLen != modulusLen) - goto failure; + if (sigLen != modulusLen) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } buffer = (unsigned char *)PORT_Alloc(modulusLen + 1); - if (!buffer) - goto failure; + if (!buffer) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + goto done; + } + + if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } - rv = RSA_PublicKeyOp(key, buffer, sig); - if (rv != SECSuccess) - goto loser; *outputLen = 0; /* @@ -1358,28 +1415,34 @@ RSA_CheckSignRecover(RSAPublicKey *key, */ if (buffer[0] != RSA_BLOCK_FIRST_OCTET || buffer[1] != (unsigned char)RSA_BlockPrivate) { - goto loser; + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; } for (i = 2; i < modulusLen; i++) { if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) { *outputLen = modulusLen - i - 1; break; } - if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) - goto loser; + if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } + } + if (*outputLen == 0) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + goto done; + } + if (*outputLen > maxOutputLen) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + goto done; } - if (*outputLen == 0) - goto loser; - if (*outputLen > maxOutputLen) - goto loser; PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen); + rv = SECSuccess; - PORT_Free(buffer); - return SECSuccess; - -loser: - PORT_Free(buffer); -failure: - return SECFailure; +done: + if (buffer) { + PORT_Free(buffer); + } + return rv; } diff --git a/nss/lib/freebl/sysrand.c b/nss/lib/freebl/sysrand.c index 0128fa0..763f6af 100644 --- a/nss/lib/freebl/sysrand.c +++ b/nss/lib/freebl/sysrand.c @@ -8,42 +8,11 @@ #include "seccomon.h" -#ifndef XP_WIN -static size_t rng_systemFromNoise(unsigned char *dest, size_t maxLen); -#endif - -#if defined(XP_UNIX) || defined(XP_BEOS) +#if (defined(XP_UNIX) || defined(XP_BEOS)) && defined(SEED_ONLY_DEV_URANDOM) +#include "unix_urandom.c" +#elif defined(XP_UNIX) || defined(XP_BEOS) #include "unix_rand.c" #endif #ifdef XP_WIN #include "win_rand.c" #endif -#ifdef XP_OS2 -#include "os2_rand.c" -#endif - -#ifndef XP_WIN -/* - * Normal RNG_SystemRNG() isn't available, use the system noise to collect - * the required amount of entropy. - */ -static size_t -rng_systemFromNoise(unsigned char *dest, size_t maxLen) -{ - size_t retBytes = maxLen; - - while (maxLen) { - size_t nbytes = RNG_GetNoise(dest, maxLen); - - PORT_Assert(nbytes != 0); - - dest += nbytes; - maxLen -= nbytes; - - /* some hw op to try to introduce more entropy into the next - * RNG_GetNoise call */ - rng_systemJitter(); - } - return retBytes; -} -#endif diff --git a/nss/lib/freebl/unix_rand.c b/nss/lib/freebl/unix_rand.c index ea3b6af..20c76ec 100644 --- a/nss/lib/freebl/unix_rand.c +++ b/nss/lib/freebl/unix_rand.c @@ -160,7 +160,7 @@ RNG_kstat(PRUint32 *fed) #endif -#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) || defined(NTO) || defined(__riscos__) +#if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(DARWIN) || defined(OPENBSD) || defined(NTO) || defined(__riscos__) || defined(__GNU__) || defined(__FreeBSD_kernel__) || defined(__NetBSD_kernel__) #include <sys/times.h> #define getdtablesize() sysconf(_SC_OPEN_MAX) @@ -682,134 +682,6 @@ RNG_GetNoise(void *buf, size_t maxbytes) return n; } -#define SAFE_POPEN_MAXARGS 10 /* must be at least 2 */ - -/* - * safe_popen is static to this module and we know what arguments it is - * called with. Note that this version only supports a single open child - * process at any time. - */ -static pid_t safe_popen_pid; -static struct sigaction oldact; - -static FILE * -safe_popen(char *cmd) -{ - int p[2], fd, argc; - pid_t pid; - char *argv[SAFE_POPEN_MAXARGS + 1]; - FILE *fp; - static char blank[] = " \t"; - static struct sigaction newact; - - if (pipe(p) < 0) - return 0; - - fp = fdopen(p[0], "r"); - if (fp == 0) { - close(p[0]); - close(p[1]); - return 0; - } - - /* Setup signals so that SIGCHLD is ignored as we want to do waitpid */ - newact.sa_handler = SIG_DFL; - newact.sa_flags = 0; - sigfillset(&newact.sa_mask); - sigaction(SIGCHLD, &newact, &oldact); - - pid = fork(); - switch (pid) { - int ndesc; - - case -1: - fclose(fp); /* this closes p[0], the fd associated with fp */ - close(p[1]); - sigaction(SIGCHLD, &oldact, NULL); - return 0; - - case 0: - /* dup write-side of pipe to stderr and stdout */ - if (p[1] != 1) - dup2(p[1], 1); - if (p[1] != 2) - dup2(p[1], 2); - - /* - * close the other file descriptors, except stdin which we - * try reassociating with /dev/null, first (bug 174993) - */ - if (!freopen("/dev/null", "r", stdin)) - close(0); - ndesc = getdtablesize(); - for (fd = PR_MIN(65536, ndesc); --fd > 2; close(fd)) - ; - - /* clean up environment in the child process */ - putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc"); - putenv("SHELL=/bin/sh"); - putenv("IFS= \t"); - - /* - * The caller may have passed us a string that is in text - * space. It may be illegal to modify the string - */ - cmd = strdup(cmd); - /* format argv */ - argv[0] = strtok(cmd, blank); - argc = 1; - while ((argv[argc] = strtok(0, blank)) != 0) { - if (++argc == SAFE_POPEN_MAXARGS) { - argv[argc] = 0; - break; - } - } - - /* and away we go */ - execvp(argv[0], argv); - exit(127); - break; - - default: - close(p[1]); - break; - } - - /* non-zero means there's a cmd running */ - safe_popen_pid = pid; - return fp; -} - -static int -safe_pclose(FILE *fp) -{ - pid_t pid; - int status = -1, rv; - - if ((pid = safe_popen_pid) == 0) - return -1; - safe_popen_pid = 0; - - fclose(fp); - - /* yield the processor so the child gets some time to exit normally */ - PR_Sleep(PR_INTERVAL_NO_WAIT); - - /* if the child hasn't exited, kill it -- we're done with its output */ - while ((rv = waitpid(pid, &status, WNOHANG)) == -1 && errno == EINTR) - ; - if (rv == 0) { - kill(pid, SIGKILL); - while ((rv = waitpid(pid, &status, 0)) == -1 && errno == EINTR) - ; - } - - /* Reset SIGCHLD signal hander before returning */ - sigaction(SIGCHLD, &oldact, NULL); - - return status; -} - #ifdef DARWIN #include <TargetConditionals.h> #if !TARGET_OS_IPHONE @@ -817,15 +689,9 @@ safe_pclose(FILE *fp) #endif #endif -/* Fork netstat to collect its output by default. Do not unset this unless - * another source of entropy is available - */ -#define DO_NETSTAT 1 - void RNG_SystemInfoForRNG(void) { - FILE *fp; char buf[BUFSIZ]; size_t bytes; const char *const *cp; @@ -860,12 +726,6 @@ RNG_SystemInfoForRNG(void) }; #endif -#if defined(BSDI) - static char netstat_ni_cmd[] = "netstat -nis"; -#else - static char netstat_ni_cmd[] = "netstat -ni"; -#endif - GiveSystemInfo(); bytes = RNG_GetNoise(buf, sizeof(buf)); @@ -890,10 +750,12 @@ RNG_SystemInfoForRNG(void) if (gethostname(buf, sizeof(buf)) == 0) { RNG_RandomUpdate(buf, strlen(buf)); } - GiveSystemInfo(); /* grab some data from system's PRNG before any other files. */ bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT); + if (!bytes) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + } /* If the user points us to a random file, pass it through the rng */ randfile = PR_GetEnvSecure("NSRANDFILE"); @@ -911,33 +773,12 @@ RNG_SystemInfoForRNG(void) for (cp = files; *cp; cp++) RNG_FileForRNG(*cp); -/* - * Bug 100447: On BSD/OS 4.2 and 4.3, we have problem calling safe_popen - * in a pthreads environment. Therefore, we call safe_popen last and on - * BSD/OS we do not call safe_popen when we succeeded in getting data - * from /dev/urandom. - * - * Bug 174993: On platforms providing /dev/urandom, don't fork netstat - * either, if data has been gathered successfully. - */ - #if defined(BSDI) || defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(DARWIN) || defined(LINUX) || defined(HPUX) if (bytes) return; #endif #ifdef SOLARIS - -/* - * On Solaris, NSS may be initialized automatically from libldap in - * applications that are unaware of the use of NSS. safe_popen forks, and - * sometimes creates issues with some applications' pthread_atfork handlers. - * We always have /dev/urandom on Solaris 9 and above as an entropy source, - * and for Solaris 8 we have the libkstat interface, so we don't need to - * fork netstat. - */ - -#undef DO_NETSTAT if (!bytes) { /* On Solaris 8, /dev/urandom isn't available, so we use libkstat. */ PRUint32 kstat_bytes = 0; @@ -948,15 +789,6 @@ RNG_SystemInfoForRNG(void) PORT_Assert(bytes); } #endif - -#ifdef DO_NETSTAT - fp = safe_popen(netstat_ni_cmd); - if (fp != NULL) { - while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0) - RNG_RandomUpdate(buf, bytes); - safe_pclose(fp); - } -#endif } #define TOTAL_FILE_LIMIT 1000000 /* one million */ @@ -1022,20 +854,6 @@ RNG_FileForRNG(const char *fileName) RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); } -void -ReadSingleFile(const char *fileName) -{ - FILE *file; - unsigned char buffer[BUFSIZ]; - - file = fopen(fileName, "rb"); - if (file != NULL) { - while (fread(buffer, 1, sizeof(buffer), file) > 0) - ; - fclose(file); - } -} - #define _POSIX_PTHREAD_SEMANTICS #include <dirent.h> @@ -1055,89 +873,6 @@ ReadFileOK(char *dir, char *file) return S_ISREG(stat_buf.st_mode) ? PR_TRUE : PR_FALSE; } -/* - * read one file out of either /etc or the user's home directory. - * fileToRead tells which file to read. - * - * return 1 if it's time to reset the fileToRead (no more files to read). - */ -static int -ReadOneFile(int fileToRead) -{ - char *dir = "/etc"; - DIR *fd = opendir(dir); - int resetCount = 0; - struct dirent *entry; -#if defined(__sun) - char firstName[256]; -#else - char firstName[NAME_MAX + 1]; -#endif - const char *name = NULL; - int i; - - if (fd == NULL) { - dir = PR_GetEnvSecure("HOME"); - if (dir) { - fd = opendir(dir); - } - } - if (fd == NULL) { - return 1; - } - - firstName[0] = '\0'; - for (i = 0; i <= fileToRead; i++) { - do { - /* readdir() isn't guaranteed to be thread safe on every platform; - * this code assumes the same directory isn't read concurrently. - * This usage is confirmed safe on Linux, see bug 1254334. */ - entry = readdir(fd); - } while (entry != NULL && !ReadFileOK(dir, &entry->d_name[0])); - if (entry == NULL) { - resetCount = 1; /* read to the end, start again at the beginning */ - if (firstName[0]) { - /* ran out of entries in the directory, use the first one */ - name = firstName; - } - break; - } - name = entry->d_name; - if (i == 0) { - /* copy the name of the first in case we run out of entries */ - PORT_Assert(PORT_Strlen(name) < sizeof(firstName)); - PORT_Strncpy(firstName, name, sizeof(firstName) - 1); - firstName[sizeof(firstName) - 1] = '\0'; - } - } - - if (name) { - char filename[PATH_MAX]; - int count = snprintf(filename, sizeof(filename), "%s/%s", dir, name); - if (count >= 1) { - ReadSingleFile(filename); - } - } - - closedir(fd); - return resetCount; -} - -/* - * do something to try to introduce more noise into the 'GetNoise' call - */ -static void -rng_systemJitter(void) -{ - static int fileToRead = 1; - - if (ReadOneFile(fileToRead)) { - fileToRead = 1; - } else { - fileToRead++; - } -} - size_t RNG_SystemRNG(void *dest, size_t maxLen) { @@ -1149,7 +884,8 @@ RNG_SystemRNG(void *dest, size_t maxLen) file = fopen("/dev/urandom", "r"); if (file == NULL) { - return rng_systemFromNoise(dest, maxLen); + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; } /* Read from the underlying file descriptor directly to bypass stdio * buffering and avoid reading more bytes than we need from /dev/urandom. diff --git a/nss/lib/freebl/unix_urandom.c b/nss/lib/freebl/unix_urandom.c new file mode 100644 index 0000000..25e6ad9 --- /dev/null +++ b/nss/lib/freebl/unix_urandom.c @@ -0,0 +1,50 @@ +/* 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 <fcntl.h> +#include <unistd.h> +#include "secerr.h" +#include "secrng.h" +#include "prprf.h" + +void +RNG_SystemInfoForRNG(void) +{ + PRUint8 bytes[SYSTEM_RNG_SEED_COUNT]; + size_t numBytes = RNG_SystemRNG(bytes, SYSTEM_RNG_SEED_COUNT); + if (!numBytes) { + /* error is set */ + return; + } + RNG_RandomUpdate(bytes, numBytes); +} + +size_t +RNG_SystemRNG(void *dest, size_t maxLen) +{ + int fd; + int bytes; + size_t fileBytes = 0; + unsigned char *buffer = dest; + + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; + } + while (fileBytes < maxLen) { + bytes = read(fd, buffer, maxLen - fileBytes); + if (bytes <= 0) { + break; + } + fileBytes += bytes; + buffer += bytes; + } + (void)close(fd); + if (fileBytes != maxLen) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); + return 0; + } + return fileBytes; +} diff --git a/nss/lib/jar/jar.gyp b/nss/lib/jar/jar.gyp index e38b4ab..ee8734a 100644 --- a/nss/lib/jar/jar.gyp +++ b/nss/lib/jar/jar.gyp @@ -26,49 +26,6 @@ 'defines': [ 'MOZILLA_CLIENT=1', ], - 'conditions': [ - [ 'OS=="win"', { - 'configurations': { - 'x86_Base': { - 'msvs_settings': { - 'VCCLCompilerTool': { - 'PreprocessorDefinitions': [ - 'NSS_X86_OR_X64', - 'NSS_X86', - ], - }, - }, - }, - 'x64_Base': { - 'msvs_settings': { - 'VCCLCompilerTool': { - 'PreprocessorDefinitions': [ - 'NSS_USE_64', - 'NSS_X86_OR_X64', - 'NSS_X64', - ], - }, - }, - }, - }, - }, { - 'conditions': [ - [ 'target_arch=="x64"', { - 'defines': [ - 'NSS_USE_64', - 'NSS_X86_OR_X64', - 'NSS_X64', - ], - }], - [ 'target_arch=="ia32"', { - 'defines': [ - 'NSS_X86_OR_X64', - 'NSS_X86', - ], - }], - ], - }], - ], }, 'variables': { 'module': 'nss' diff --git a/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c b/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c index 171a3d2..28b6953 100644 --- a/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c +++ b/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c @@ -89,8 +89,8 @@ pkix_pl_OcspRequest_Hashcode( PKIX_HASHCODE(ocspRq->signerCert, &signerHash, plContext, PKIX_CERTHASHCODEFAILED); - *pHashcode = (((((extensionHash << 8) || certHash) << 8) || - dateHash) << 8) || signerHash; + *pHashcode = (((((extensionHash << 8) | certHash) << 8) | + dateHash) << 8) | signerHash; cleanup: diff --git a/nss/lib/nss/nss.def b/nss/lib/nss/nss.def index 1760b96..e1453cc 100644 --- a/nss/lib/nss/nss.def +++ b/nss/lib/nss/nss.def @@ -1097,3 +1097,21 @@ PK11_VerifyWithMechanism; ;+ local: ;+ *; ;+}; +;+NSS_3.30 { # NSS 3.30 release +;+ global: +CERT_CompareAVA; +PK11_HasAttributeSet; +;+ local: +;+ *; +;+}; +;+NSS_3.31 { # NSS 3.31 release +;+ global: +CERT_GetCertIsPerm; +CERT_GetCertIsTemp; +PK11_FindCertFromURI; +PK11_FindCertsFromURI; +PK11_GetModuleURI; +PK11_GetTokenURI; +;+ local: +;+ *; +;+}; diff --git a/nss/lib/nss/nss.h b/nss/lib/nss/nss.h index e1c67ec..a35789e 100644 --- a/nss/lib/nss/nss.h +++ b/nss/lib/nss/nss.h @@ -22,10 +22,10 @@ * The format of the version string should be * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" */ -#define NSS_VERSION "3.28.1" _NSS_CUSTOMIZED +#define NSS_VERSION "3.31" _NSS_CUSTOMIZED #define NSS_VMAJOR 3 -#define NSS_VMINOR 28 -#define NSS_VPATCH 1 +#define NSS_VMINOR 31 +#define NSS_VPATCH 0 #define NSS_VBUILD 0 #define NSS_BETA PR_FALSE diff --git a/nss/lib/pk11wrap/dev3hack.c b/nss/lib/pk11wrap/dev3hack.c index 27325a5..39afd67 100644 --- a/nss/lib/pk11wrap/dev3hack.c +++ b/nss/lib/pk11wrap/dev3hack.c @@ -114,7 +114,7 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) rvSlot->base.refCount = 1; rvSlot->base.lock = PZ_NewLock(nssILockOther); rvSlot->base.arena = arena; - rvSlot->pk11slot = nss3slot; + rvSlot->pk11slot = PK11_ReferenceSlot(nss3slot); rvSlot->epv = nss3slot->functionList; rvSlot->slotID = nss3slot->slotID; /* Grab the slot name from the PKCS#11 fixed-length buffer */ @@ -150,7 +150,7 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) return NULL; } rvToken->base.arena = arena; - rvToken->pk11slot = nss3slot; + rvToken->pk11slot = PK11_ReferenceSlot(nss3slot); rvToken->epv = nss3slot->functionList; rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena, nss3slot->session, diff --git a/nss/lib/pk11wrap/pk11akey.c b/nss/lib/pk11wrap/pk11akey.c index d086ed4..c45901e 100644 --- a/nss/lib/pk11wrap/pk11akey.c +++ b/nss/lib/pk11wrap/pk11akey.c @@ -765,12 +765,10 @@ PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, CK_OBJECT_HANDLE id) &pubKey->u.ec.DEREncodedParams); if (crv != CKR_OK) break; + pubKey->u.ec.encoding = ECPoint_Undefined; crv = pk11_get_Decoded_ECPoint(arena, &pubKey->u.ec.DEREncodedParams, value, &pubKey->u.ec.publicValue); - if (seckey_SetPointEncoding(arena, pubKey) != SECSuccess) { - crv |= CKR_GENERAL_ERROR; - } break; case fortezzaKey: case nullKey: @@ -888,6 +886,10 @@ PK11_GetPrivateModulusLen(SECKEYPrivateKey *key) PORT_SetError(PK11_MapError(crv)); return -1; } + if (theTemplate.pValue == NULL) { + PORT_SetError(PK11_MapError(CKR_ATTRIBUTE_VALUE_INVALID)); + return -1; + } length = theTemplate.ulValueLen; if (*(unsigned char *)theTemplate.pValue == 0) { length--; diff --git a/nss/lib/pk11wrap/pk11cert.c b/nss/lib/pk11wrap/pk11cert.c index 6968ae7..c1caf5e 100644 --- a/nss/lib/pk11wrap/pk11cert.c +++ b/nss/lib/pk11wrap/pk11cert.c @@ -34,6 +34,8 @@ #include "pkitm.h" #include "pkistore.h" /* to remove temp cert */ #include "devt.h" +#include "ckhelper.h" +#include "pkcs11uri.h" extern const NSSError NSS_ERROR_NOT_FOUND; extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; @@ -507,15 +509,231 @@ transfer_token_certs_to_collection(nssList *certList, NSSToken *token, nss_ZFreeIf(certs); } -CERTCertificate * -PK11_FindCertFromNickname(const char *nickname, void *wincx) +static void +transfer_uri_certs_to_collection(nssList *certList, PK11URI *uri, + nssPKIObjectCollection *collection) +{ + + NSSCertificate **certs; + PRUint32 i, count; + NSSToken **tokens, **tp; + PK11SlotInfo *slot; + const char *id; + + id = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_ID); + count = nssList_Count(certList); + if (count == 0) { + return; + } + certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count); + if (!certs) { + return; + } + nssList_GetArray(certList, (void **)certs, count); + for (i = 0; i < count; i++) { + /* + * Filter the subject matched certs based on the + * CKA_ID from the URI + */ + if (id && (strlen(id) != certs[i]->id.size || + memcmp(id, certs[i]->id.data, certs[i]->id.size))) + continue; + tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL); + if (tokens) { + for (tp = tokens; *tp; tp++) { + const char *value; + slot = (*tp)->pk11slot; + + value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_TOKEN); + if (value && + !pk11_MatchString(value, + (char *)slot->tokenInfo.label, + sizeof(slot->tokenInfo.label))) { + continue; + } + + value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MANUFACTURER); + if (value && + !pk11_MatchString(value, + (char *)slot->tokenInfo.manufacturerID, + sizeof(slot->tokenInfo.manufacturerID))) { + continue; + } + + value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MODEL); + if (value && + !pk11_MatchString(value, + (char *)slot->tokenInfo.model, + sizeof(slot->tokenInfo.model))) { + continue; + } + + nssPKIObjectCollection_AddObject(collection, + (nssPKIObject *)certs[i]); + break; + } + nssTokenArray_Destroy(tokens); + } + CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(certs[i])); + } + nss_ZFreeIf(certs); +} + +static NSSCertificate ** +find_certs_from_uri(const char *uriString, void *wincx) { + PK11URI *uri = NULL; + CK_ATTRIBUTE attributes[10]; + CK_ULONG nattributes = 0; + const char *label; + PK11SlotInfo *slotinfo; + nssCryptokiObject **instances; PRStatus status; - CERTCertificate *rvCert = NULL; - NSSCertificate *cert = NULL; + nssPKIObjectCollection *collection = NULL; + NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); NSSCertificate **certs = NULL; + nssList *certList = NULL; + SECStatus rv; + CK_OBJECT_CLASS s_class = CKO_CERTIFICATE; + static const CK_BBOOL s_true = CK_TRUE; + NSSToken **tokens, **tok; + + uri = PK11URI_ParseURI(uriString); + if (uri == NULL) { + goto loser; + } + + collection = nssCertificateCollection_Create(defaultTD, NULL); + if (!collection) { + goto loser; + } + certList = nssList_Create(NULL, PR_FALSE); + if (!certList) { + goto loser; + } + + label = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_OBJECT); + if (label) { + (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, + (const char *)label, + certList); + } else { + (void)nssTrustDomain_GetCertsFromCache(defaultTD, certList); + } + + transfer_uri_certs_to_collection(certList, uri, collection); + + /* add the CKA_CLASS and CKA_TOKEN attributes manually */ + attributes[nattributes].type = CKA_CLASS; + attributes[nattributes].pValue = (void *)&s_class; + attributes[nattributes].ulValueLen = sizeof(s_class); + nattributes++; + + attributes[nattributes].type = CKA_TOKEN; + attributes[nattributes].pValue = (void *)&s_true; + attributes[nattributes].ulValueLen = sizeof(s_true); + nattributes++; + + if (label) { + attributes[nattributes].type = CKA_LABEL; + attributes[nattributes].pValue = (void *)label; + attributes[nattributes].ulValueLen = strlen(label); + nattributes++; + } + + tokens = NSSTrustDomain_FindTokensByURI(defaultTD, uri); + for (tok = tokens; tok && *tok; tok++) { + if (nssToken_IsPresent(*tok)) { + slotinfo = (*tok)->pk11slot; + + rv = pk11_AuthenticateUnfriendly(slotinfo, PR_TRUE, wincx); + if (rv != SECSuccess) { + continue; + } + instances = nssToken_FindObjectsByTemplate(*tok, NULL, + attributes, + nattributes, + 0, &status); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); + } + nssToken_Destroy(*tok); + } + nss_ZFreeIf(tokens); + nssList_Destroy(certList); + certs = nssPKIObjectCollection_GetCertificates(collection, NULL, 0, NULL); + +loser: + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + if (uri) { + PK11URI_DestroyURI(uri); + } + return certs; +} + +CERTCertificate * +PK11_FindCertFromURI(const char *uri, void *wincx) +{ static const NSSUsage usage = { PR_TRUE /* ... */ }; - NSSToken *token; + NSSCertificate *cert = NULL; + NSSCertificate **certs = NULL; + CERTCertificate *rvCert = NULL; + + certs = find_certs_from_uri(uri, wincx); + if (certs) { + cert = nssCertificateArray_FindBestCertificate(certs, NULL, + &usage, NULL); + if (cert) { + rvCert = STAN_GetCERTCertificateOrRelease(cert); + } + nssCertificateArray_Destroy(certs); + } + return rvCert; +} + +CERTCertList * +PK11_FindCertsFromURI(const char *uri, void *wincx) +{ + int i; + CERTCertList *certList = NULL; + NSSCertificate **foundCerts; + NSSCertificate *c; + + foundCerts = find_certs_from_uri(uri, wincx); + if (foundCerts) { + PRTime now = PR_Now(); + certList = CERT_NewCertList(); + for (i = 0, c = *foundCerts; c; c = foundCerts[++i]) { + if (certList) { + CERTCertificate *certCert = STAN_GetCERTCertificateOrRelease(c); + /* c may be invalid after this, don't reference it */ + if (certCert) { + /* CERT_AddCertToListSorted adopts certCert */ + CERT_AddCertToListSorted(certList, certCert, + CERT_SortCBValidity, &now); + } + } else { + nssCertificate_Destroy(c); + } + } + if (certList && CERT_LIST_HEAD(certList) == NULL) { + CERT_DestroyCertList(certList); + certList = NULL; + } + /* all the certs have been adopted or freed, free the raw array */ + nss_ZFreeIf(foundCerts); + } + return certList; +} + +static NSSCertificate ** +find_certs_from_nickname(const char *nickname, void *wincx) +{ + PRStatus status; + NSSCertificate **certs = NULL; + NSSToken *token = NULL; NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); PK11SlotInfo *slot = NULL; SECStatus rv; @@ -523,6 +741,11 @@ PK11_FindCertFromNickname(const char *nickname, void *wincx) char *delimit = NULL; char *tokenName; + if (!strncmp(nickname, "pkcs11:", strlen("pkcs11:"))) { + certs = find_certs_from_uri(nickname, wincx); + if (certs) + return certs; + } nickCopy = PORT_Strdup(nickname); if (!nickCopy) { /* error code is set */ @@ -543,6 +766,11 @@ PK11_FindCertFromNickname(const char *nickname, void *wincx) } else { slot = PK11_GetInternalKeySlot(); token = PK11Slot_GetNSSToken(slot); + if (token) { + nssToken_AddRef(token); + } else { + PORT_SetError(SEC_ERROR_NO_TOKEN); + } } if (token) { nssList *certList; @@ -600,29 +828,38 @@ PK11_FindCertFromNickname(const char *nickname, void *wincx) certs = nssPKIObjectCollection_GetCertificates(collection, NULL, 0, NULL); nssPKIObjectCollection_Destroy(collection); - if (certs) { - cert = nssCertificateArray_FindBestCertificate(certs, NULL, - &usage, NULL); - if (cert) { - rvCert = STAN_GetCERTCertificateOrRelease(cert); - } - nssCertificateArray_Destroy(certs); - } nssList_Destroy(certList); } - if (slot) { - PK11_FreeSlot(slot); - } - if (nickCopy) - PORT_Free(nickCopy); - return rvCert; loser: + if (token) { + nssToken_Destroy(token); + } if (slot) { PK11_FreeSlot(slot); } if (nickCopy) PORT_Free(nickCopy); - return NULL; + return certs; +} + +CERTCertificate * +PK11_FindCertFromNickname(const char *nickname, void *wincx) +{ + CERTCertificate *rvCert = NULL; + NSSCertificate *cert = NULL; + NSSCertificate **certs = NULL; + static const NSSUsage usage = { PR_TRUE /* ... */ }; + + certs = find_certs_from_nickname(nickname, wincx); + if (certs) { + cert = nssCertificateArray_FindBestCertificate(certs, NULL, + &usage, NULL); + if (cert) { + rvCert = STAN_GetCERTCertificateOrRelease(cert); + } + nssCertificateArray_Destroy(certs); + } + return rvCert; } /* Traverse slots callback */ @@ -690,8 +927,7 @@ PK11_FindCertsFromEmailAddress(const char *email, void *wincx) } /* empty list? */ - if (CERT_LIST_HEAD(cbparam.certList) == NULL || - CERT_LIST_END(CERT_LIST_HEAD(cbparam.certList), cbparam.certList)) { + if (CERT_LIST_EMPTY(cbparam.certList)) { CERT_DestroyCertList(cbparam.certList); cbparam.certList = NULL; } @@ -703,111 +939,12 @@ PK11_FindCertsFromEmailAddress(const char *email, void *wincx) CERTCertList * PK11_FindCertsFromNickname(const char *nickname, void *wincx) { - char *nickCopy; - char *delimit = NULL; - char *tokenName; int i; CERTCertList *certList = NULL; - nssPKIObjectCollection *collection = NULL; NSSCertificate **foundCerts = NULL; - NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); NSSCertificate *c; - NSSToken *token; - PK11SlotInfo *slot; - SECStatus rv; - - nickCopy = PORT_Strdup(nickname); - if (!nickCopy) { - /* error code is set */ - return NULL; - } - if ((delimit = PORT_Strchr(nickCopy, ':')) != NULL) { - tokenName = nickCopy; - nickname = delimit + 1; - *delimit = '\0'; - /* find token by name */ - token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName); - if (token) { - slot = PK11_ReferenceSlot(token->pk11slot); - } else { - PORT_SetError(SEC_ERROR_NO_TOKEN); - slot = NULL; - } - *delimit = ':'; - } else { - slot = PK11_GetInternalKeySlot(); - token = PK11Slot_GetNSSToken(slot); - } - if (token) { - PRStatus status; - nssList *nameList; - nssCryptokiObject **instances; - nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; - rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx); - if (rv != SECSuccess) { - PK11_FreeSlot(slot); - if (nickCopy) - PORT_Free(nickCopy); - return NULL; - } - collection = nssCertificateCollection_Create(defaultTD, NULL); - if (!collection) { - PK11_FreeSlot(slot); - if (nickCopy) - PORT_Free(nickCopy); - return NULL; - } - nameList = nssList_Create(NULL, PR_FALSE); - if (!nameList) { - PK11_FreeSlot(slot); - if (nickCopy) - PORT_Free(nickCopy); - return NULL; - } - (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, - nickname, - nameList); - transfer_token_certs_to_collection(nameList, token, collection); - instances = nssToken_FindCertificatesByNickname(token, - NULL, - nickname, - tokenOnly, - 0, - &status); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - - /* if it wasn't found, repeat the process for email address */ - if (nssPKIObjectCollection_Count(collection) == 0 && - PORT_Strchr(nickname, '@') != NULL) { - char *lowercaseName = CERT_FixupEmailAddr(nickname); - if (lowercaseName) { - (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD, - lowercaseName, - nameList); - transfer_token_certs_to_collection(nameList, token, collection); - instances = nssToken_FindCertificatesByEmail(token, - NULL, - lowercaseName, - tokenOnly, - 0, - &status); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - PORT_Free(lowercaseName); - } - } - nssList_Destroy(nameList); - foundCerts = nssPKIObjectCollection_GetCertificates(collection, - NULL, 0, NULL); - nssPKIObjectCollection_Destroy(collection); - } - if (slot) { - PK11_FreeSlot(slot); - } - if (nickCopy) - PORT_Free(nickCopy); + foundCerts = find_certs_from_nickname(nickname, wincx); if (foundCerts) { PRTime now = PR_Now(); certList = CERT_NewCertList(); @@ -824,10 +961,6 @@ PK11_FindCertsFromNickname(const char *nickname, void *wincx) nssCertificate_Destroy(c); } } - if (certList && CERT_LIST_HEAD(certList) == NULL) { - CERT_DestroyCertList(certList); - certList = NULL; - } /* all the certs have been adopted or freed, free the raw array */ nss_ZFreeIf(foundCerts); } @@ -979,8 +1112,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); c->object.cryptoContext = NULL; + CERT_LockCertTempPerm(cert); cert->istemp = PR_FALSE; cert->isperm = PR_TRUE; + CERT_UnlockCertTempPerm(cert); } /* add the new instance to the cert, force an update of the diff --git a/nss/lib/pk11wrap/pk11load.c b/nss/lib/pk11wrap/pk11load.c index f12d0fd..91339fa 100644 --- a/nss/lib/pk11wrap/pk11load.c +++ b/nss/lib/pk11wrap/pk11load.c @@ -17,6 +17,10 @@ #include "secerr.h" #include "prenv.h" #include "utilparst.h" +#include "prio.h" +#include "prprf.h" +#include <stdio.h> +#include "prsystem.h" #define DEBUG_MODULE 1 @@ -350,6 +354,7 @@ SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod) } } +#ifndef NSS_TEST_BUILD static const char *my_shlib_name = SHLIB_PREFIX "nss" SHLIB_VERSION "." SHLIB_SUFFIX; static const char *softoken_shlib_name = @@ -359,11 +364,6 @@ static PRCallOnceType loadSoftokenOnce; static PRLibrary *softokenLib; static PRInt32 softokenLoadCount; -#include "prio.h" -#include "prprf.h" -#include <stdio.h> -#include "prsystem.h" - /* This function must be run only once. */ /* determine if hybrid platform, then actually load the DSO. */ static PRStatus @@ -380,6 +380,10 @@ softoken_LoadDSO(void) } return PR_FAILURE; } +#else +CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList); +char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args); +#endif /* * load a new module into our address space and initialize it. @@ -398,8 +402,11 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) if (mod->loaded) return SECSuccess; - /* intenal modules get loaded from their internal list */ + /* internal modules get loaded from their internal list */ if (mod->internal && (mod->dllName == NULL)) { +#ifdef NSS_TEST_BUILD + entry = (CK_C_GetFunctionList)NSC_GetFunctionList; +#else /* * Loads softoken as a dynamic library, * even though the rest of NSS assumes this as the "internal" module. @@ -420,10 +427,15 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) if (!entry) return SECFailure; +#endif if (mod->isModuleDB) { mod->moduleDBFunc = (CK_C_GetFunctionList) +#ifdef NSS_TEST_BUILD + NSC_ModuleDBFunc; +#else PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc"); +#endif } if (mod->moduleDBOnly) { @@ -601,6 +613,7 @@ SECMOD_UnloadModule(SECMODModule *mod) * if not, we should change this to SECFailure and move it above the * mod->loaded = PR_FALSE; */ if (mod->internal && (mod->dllName == NULL)) { +#ifndef NSS_TEST_BUILD if (0 == PR_ATOMIC_DECREMENT(&softokenLoadCount)) { if (softokenLib) { disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD"); @@ -616,6 +629,7 @@ SECMOD_UnloadModule(SECMODModule *mod) } loadSoftokenOnce = pristineCallOnce; } +#endif return SECSuccess; } diff --git a/nss/lib/pk11wrap/pk11mech.c b/nss/lib/pk11wrap/pk11mech.c index 4db05ff..48e50df 100644 --- a/nss/lib/pk11wrap/pk11mech.c +++ b/nss/lib/pk11wrap/pk11mech.c @@ -612,6 +612,10 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size) case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN: case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN: case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: case CKM_NETSCAPE_PBE_SHA1_DES_CBC: case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: diff --git a/nss/lib/pk11wrap/pk11obj.c b/nss/lib/pk11wrap/pk11obj.c index 18850b2..4046c1f 100644 --- a/nss/lib/pk11wrap/pk11obj.c +++ b/nss/lib/pk11wrap/pk11obj.c @@ -156,8 +156,8 @@ PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, * check to see if a bool has been set. */ CK_BBOOL -PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type, PRBool haslock) +pk11_HasAttributeSet_Lock(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, + CK_ATTRIBUTE_TYPE type, PRBool haslock) { CK_BBOOL ckvalue = CK_FALSE; CK_ATTRIBUTE theTemplate; @@ -181,6 +181,14 @@ PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, return ckvalue; } +CK_BBOOL +PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, + CK_ATTRIBUTE_TYPE type, PRBool haslock) +{ + PR_ASSERT(haslock == PR_FALSE); + return pk11_HasAttributeSet_Lock(slot, id, type, PR_FALSE); +} + /* * returns a full list of attributes. Allocate space for them. If an arena is * provided, allocate space out of the arena. diff --git a/nss/lib/pk11wrap/pk11pbe.c b/nss/lib/pk11wrap/pk11pbe.c index 7837bfe..bea9333 100644 --- a/nss/lib/pk11wrap/pk11pbe.c +++ b/nss/lib/pk11wrap/pk11pbe.c @@ -4,6 +4,7 @@ #include "plarena.h" +#include "blapit.h" #include "seccomon.h" #include "secitem.h" #include "secport.h" @@ -301,17 +302,49 @@ SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen) return SEC_OID_UNKNOWN; } +static PRBool +sec_pkcs5_is_algorithm_v2_aes_algorithm(SECOidTag algorithm) +{ + switch (algorithm) { + case SEC_OID_AES_128_CBC: + case SEC_OID_AES_192_CBC: + case SEC_OID_AES_256_CBC: + return PR_TRUE; + default: + return PR_FALSE; + } +} + +static int +sec_pkcs5v2_aes_key_length(SECOidTag algorithm) +{ + switch (algorithm) { + /* The key length for the AES-CBC-Pad algorithms are + * determined from the undelying cipher algorithm. */ + case SEC_OID_AES_128_CBC: + return AES_128_KEY_LENGTH; + case SEC_OID_AES_192_CBC: + return AES_192_KEY_LENGTH; + case SEC_OID_AES_256_CBC: + return AES_256_KEY_LENGTH; + default: + break; + } + return 0; +} + /* * get the key length in bytes from a PKCS5 PBE */ -int -sec_pkcs5v2_key_length(SECAlgorithmID *algid) +static int +sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId) { SECOidTag algorithm; PLArenaPool *arena = NULL; SEC_PKCS5PBEParameter p5_param; SECStatus rv; int length = -1; + SECOidTag cipherAlg = SEC_OID_UNKNOWN; algorithm = SECOID_GetAlgorithmTag(algid); /* sanity check, they should all be PBKDF2 here */ @@ -330,8 +363,20 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid) goto loser; } - if (p5_param.keyLength.data != NULL) { + if (cipherAlgId) + cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId); + + if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlg)) { + length = sec_pkcs5v2_aes_key_length(cipherAlg); + } else if (p5_param.keyLength.data != NULL) { length = DER_GetInteger(&p5_param.keyLength); + } else { + CK_MECHANISM_TYPE cipherMech; + cipherMech = PK11_AlgtagToMechanism(cipherAlg); + if (cipherMech == CKM_INVALID_MECHANISM) { + goto loser; + } + length = PK11_GetMaxKeyLength(cipherMech); } loser: @@ -375,14 +420,15 @@ SEC_PKCS5GetKeyLength(SECAlgorithmID *algid) case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: return 16; case SEC_OID_PKCS5_PBKDF2: - return sec_pkcs5v2_key_length(algid); + return sec_pkcs5v2_key_length(algid, NULL); case SEC_OID_PKCS5_PBES2: case SEC_OID_PKCS5_PBMAC1: { sec_pkcs5V2Parameter *pbeV2_param; int length = -1; pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); if (pbeV2_param != NULL) { - length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId); + length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId, + &pbeV2_param->cipherAlgId); sec_pkcs5_v2_destroy_v2_param(pbeV2_param); } return length; @@ -614,6 +660,8 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm, SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm); if (hashAlg != SEC_OID_UNKNOWN) { keyLength = HASH_ResultLenByOidTag(hashAlg); + } else if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlgorithm)) { + keyLength = sec_pkcs5v2_aes_key_length(cipherAlgorithm); } else { CK_MECHANISM_TYPE cryptoMech; cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm); diff --git a/nss/lib/pk11wrap/pk11pk12.c b/nss/lib/pk11wrap/pk11pk12.c index 1683cc5..d753b87 100644 --- a/nss/lib/pk11wrap/pk11pk12.c +++ b/nss/lib/pk11wrap/pk11pk12.c @@ -65,6 +65,19 @@ struct SECKEYDHPrivateKeyStr { typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey; /* +** Elliptic Curve Private Key structures +** <https://tools.ietf.org/html/rfc5915#section-3> +*/ +struct SECKEYECPrivateKeyStr { + PLArenaPool *arena; + SECItem version; + SECItem curveOID; /* optional/ignored */ + SECItem publicValue; /* required (for now) */ + SECItem privateValue; +}; +typedef struct SECKEYECPrivateKeyStr SECKEYECPrivateKey; + +/* ** raw private key object */ struct SECKEYRawPrivateKeyStr { @@ -74,6 +87,7 @@ struct SECKEYRawPrivateKeyStr { SECKEYRSAPrivateKey rsa; SECKEYDSAPrivateKey dsa; SECKEYDHPrivateKey dh; + SECKEYECPrivateKey ec; } u; }; typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey; @@ -139,6 +153,33 @@ const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = { { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) }, }; +#ifndef NSS_DISABLE_ECC +SEC_ASN1_MKSUB(SEC_BitStringTemplate) +SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) + +const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, + { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.ec.version) }, + { SEC_ASN1_OCTET_STRING, + offsetof(SECKEYRawPrivateKey, u.ec.privateValue) }, + /* This value will always be ignored. u.ec.curveOID will always be + * overriden with the outer AlgorithmID.parameters. */ + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | + SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_XTRN | 0, + offsetof(SECKEYRawPrivateKey, u.ec.curveOID), + SEC_ASN1_SUB(SEC_ObjectIDTemplate) }, + /* The public value is optional per RFC, but required in NSS. We + * can't do scalar mult on ECs to get a raw point with PK11 APIs. */ + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | + SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_XTRN | 1, + offsetof(SECKEYRawPrivateKey, u.ec.publicValue), + SEC_ASN1_SUB(SEC_BitStringTemplate) }, + { 0 } +}; +#endif /* NSS_DISABLE_ECC */ + const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) }, @@ -198,6 +239,15 @@ prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) key->u.dh.base.type = siUnsignedInteger; } +static void +prepare_ec_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) +{ + key->u.ec.version.type = siUnsignedInteger; + key->u.ec.curveOID.type = siUnsignedInteger; + key->u.ec.privateValue.type = siUnsignedInteger; + key->u.ec.publicValue.type = siUnsignedInteger; +} + SECStatus PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI, SECItem *nickname, SECItem *publicValue, PRBool isPerm, @@ -432,7 +482,50 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, lpk->u.dh.privateValue.len); attrs++; break; - /* what about fortezza??? */ +#ifndef NSS_DISABLE_ECC + case ecKey: + keyType = CKK_EC; + if (lpk->u.ec.publicValue.len == 0) { + goto loser; + } + if (PK11_IsInternal(slot)) { + PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, + lpk->u.ec.publicValue.data, + lpk->u.ec.publicValue.len); + attrs++; + } + PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue + : &ckfalse, + sizeof(CK_BBOOL)); + attrs++; + PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, + (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue + : &ckfalse, + sizeof(CK_BBOOL)); + attrs++; + PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue + : &ckfalse, + sizeof(CK_BBOOL)); + attrs++; + ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue); + if (ck_id == NULL) { + goto loser; + } + PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); + attrs++; + signedattr = attrs; + /* curveOID always is a copy of AlgorithmID.parameters. */ + PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data, + lpk->u.ec.curveOID.len); + attrs++; + PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data, + lpk->u.ec.privateValue.len); + attrs++; + PK11_SETATTRS(attrs, CKA_EC_POINT, lpk->u.ec.publicValue.data, + lpk->u.ec.publicValue.len); + attrs++; + break; +#endif /* NSS_DISABLE_ECC */ default: PORT_SetError(SEC_ERROR_BAD_KEY); goto loser; @@ -513,6 +606,15 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, paramDest = NULL; lpk->keyType = dhKey; break; +#ifndef NSS_DISABLE_ECC + case SEC_OID_ANSIX962_EC_PUBLIC_KEY: + prepare_ec_priv_key_export_for_asn1(lpk); + keyTemplate = SECKEY_ECPrivateKeyExportTemplate; + paramTemplate = NULL; + paramDest = NULL; + lpk->keyType = ecKey; + break; +#endif /* NSS_DISABLE_ECC */ default: keyTemplate = NULL; @@ -526,10 +628,25 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, } /* decode the private key and any algorithm parameters */ - rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey); + rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey); if (rv != SECSuccess) { goto loser; } + +#ifndef NSS_DISABLE_ECC + if (lpk->keyType == ecKey) { + /* Convert length in bits to length in bytes. */ + lpk->u.ec.publicValue.len >>= 3; + + /* Always override curveOID, we're ignoring any given value. */ + rv = SECITEM_CopyItem(arena, &lpk->u.ec.curveOID, + &pki->algorithm.parameters); + if (rv != SECSuccess) { + goto loser; + } + } +#endif /* NSS_DISABLE_ECC */ + if (paramDest && paramTemplate) { rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate, &(pki->algorithm.parameters)); diff --git a/nss/lib/pk11wrap/pk11priv.h b/nss/lib/pk11wrap/pk11priv.h index 45a60b4..9281923 100644 --- a/nss/lib/pk11wrap/pk11priv.h +++ b/nss/lib/pk11wrap/pk11priv.h @@ -14,6 +14,7 @@ #include "seccomon.h" #include "pkcs7t.h" #include "cmsreclist.h" +#include "pkcs11uri.h" /* * These are the private NSS functions. They are not exported by nss.def, and @@ -39,12 +40,15 @@ int PK11_GetMaxKeyLength(CK_MECHANISM_TYPE type); * Generic Slot Management ************************************************************/ CK_OBJECT_HANDLE PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject); +PRBool pk11_MatchUriTokenInfo(PK11SlotInfo *slot, PK11URI *uri); SECStatus PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result); CK_ULONG PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type); char *PK11_MakeString(PLArenaPool *arena, char *space, char *staticSring, int stringLen); +PRBool pk11_MatchString(const char *string, + const char *staticString, int staticStringLen); int PK11_MapError(CK_RV error); CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot); void PK11_RestoreROSession(PK11SlotInfo *slot, CK_SESSION_HANDLE rwsession); @@ -106,6 +110,7 @@ CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot); PK11SymKey *pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey); +unsigned int pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType); /********************************************************************** * Certs @@ -118,10 +123,10 @@ CK_OBJECT_HANDLE *PK11_FindObjectsFromNickname(char *nickname, void *wincx); CK_OBJECT_HANDLE PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE peer, CK_OBJECT_CLASS o_class); -CK_BBOOL PK11_HasAttributeSet(PK11SlotInfo *slot, - CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type, - PRBool haslock); +CK_BBOOL pk11_HasAttributeSet_Lock(PK11SlotInfo *slot, + CK_OBJECT_HANDLE id, + CK_ATTRIBUTE_TYPE type, + PRBool haslock); CK_RV PK11_GetAttributes(PLArenaPool *arena, PK11SlotInfo *slot, CK_OBJECT_HANDLE obj, CK_ATTRIBUTE *attr, int count); int PK11_NumberCertsForCertSubject(CERTCertificate *cert); diff --git a/nss/lib/pk11wrap/pk11pub.h b/nss/lib/pk11wrap/pk11pub.h index e11af86..edfe82f 100644 --- a/nss/lib/pk11wrap/pk11pub.h +++ b/nss/lib/pk11wrap/pk11pub.h @@ -76,6 +76,7 @@ PRBool PK11_IsReadOnly(PK11SlotInfo *slot); PRBool PK11_IsInternal(PK11SlotInfo *slot); PRBool PK11_IsInternalKeySlot(PK11SlotInfo *slot); char *PK11_GetTokenName(PK11SlotInfo *slot); +char *PK11_GetTokenURI(PK11SlotInfo *slot); char *PK11_GetSlotName(PK11SlotInfo *slot); PRBool PK11_NeedLogin(PK11SlotInfo *slot); PRBool PK11_IsFriendly(PK11SlotInfo *slot); @@ -135,6 +136,7 @@ PK11TokenStatus PK11_WaitForTokenEvent(PK11SlotInfo *slot, PK11TokenEvent event, PRBool PK11_NeedPWInit(void); PRBool PK11_TokenExists(CK_MECHANISM_TYPE); SECStatus PK11_GetModInfo(SECMODModule *mod, CK_INFO *info); +char *PK11_GetModuleURI(SECMODModule *mod); PRBool PK11_IsFIPS(void); SECMODModule *PK11_GetModule(PK11SlotInfo *slot); @@ -642,6 +644,8 @@ SECStatus PK11_TraverseSlotCerts( SECStatus (*callback)(CERTCertificate *, SECItem *, void *), void *arg, void *wincx); CERTCertificate *PK11_FindCertFromNickname(const char *nickname, void *wincx); +CERTCertificate *PK11_FindCertFromURI(const char *uri, void *wincx); +CERTCertList *PK11_FindCertsFromURI(const char *uri, void *wincx); CERTCertList *PK11_FindCertsFromEmailAddress(const char *email, void *wincx); CERTCertList *PK11_FindCertsFromNickname(const char *nickname, void *wincx); CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey); @@ -686,6 +690,10 @@ CERTCertList *PK11_ListCerts(PK11CertListType type, void *pwarg); CERTCertList *PK11_ListCertsInSlot(PK11SlotInfo *slot); CERTSignedCrl *PK11_ImportCRL(PK11SlotInfo *slot, SECItem *derCRL, char *url, int type, void *wincx, PRInt32 importOptions, PLArenaPool *arena, PRInt32 decodeOptions); +CK_BBOOL PK11_HasAttributeSet(PK11SlotInfo *slot, + CK_OBJECT_HANDLE id, + CK_ATTRIBUTE_TYPE type, + PRBool haslock /* must be set to PR_FALSE */); /********************************************************************** * Sign/Verify diff --git a/nss/lib/pk11wrap/pk11skey.c b/nss/lib/pk11wrap/pk11skey.c index 850ec02..1ef53e1 100644 --- a/nss/lib/pk11wrap/pk11skey.c +++ b/nss/lib/pk11wrap/pk11skey.c @@ -18,6 +18,8 @@ #include "secerr.h" #include "hasht.h" +static ECPointEncoding pk11_ECGetPubkeyEncoding(const SECKEYPublicKey *pubKey); + static void pk11_EnterKeyMonitor(PK11SymKey *symKey) { @@ -2005,7 +2007,7 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, /* old PKCS #11 spec was ambiguous on what needed to be passed, * try this again with and encoded public key */ - if (crv != CKR_OK) { + if (crv != CKR_OK && pk11_ECGetPubkeyEncoding(pubKey) != ECPoint_XOnly) { SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, &pubKey->u.ec.publicValue, SEC_ASN1_GET(SEC_OctetStringTemplate)); @@ -2037,6 +2039,40 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, return NULL; } +/* Test for curves that are known to use a special encoding. + * Extend this function when additional curves are added. */ +static ECPointEncoding +pk11_ECGetPubkeyEncoding(const SECKEYPublicKey *pubKey) +{ + SECItem oid; + SECStatus rv; + PORTCheapArenaPool tmpArena; + ECPointEncoding encoding = ECPoint_Undefined; + + PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE); + + /* decode the OID tag */ + rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &oid, + SEC_ASN1_GET(SEC_ObjectIDTemplate), + &pubKey->u.ec.DEREncodedParams); + if (rv == SECSuccess) { + SECOidTag tag = SECOID_FindOIDTag(&oid); + switch (tag) { + case SEC_OID_CURVE25519: + encoding = ECPoint_XOnly; + break; + case SEC_OID_SECG_EC_SECP256R1: + case SEC_OID_SECG_EC_SECP384R1: + case SEC_OID_SECG_EC_SECP521R1: + default: + /* unknown curve, default to uncompressed */ + encoding = ECPoint_Uncompressed; + } + } + PORT_DestroyCheapArena(&tmpArena); + return encoding; +} + /* Returns the size of the public key, or 0 if there * is an error. */ static CK_ULONG @@ -2044,10 +2080,11 @@ pk11_ECPubKeySize(SECKEYPublicKey *pubKey) { SECItem *publicValue = &pubKey->u.ec.publicValue; - if (pubKey->u.ec.encoding == ECPoint_XOnly) { + ECPointEncoding encoding = pk11_ECGetPubkeyEncoding(pubKey); + if (encoding == ECPoint_XOnly) { return publicValue->len; } - if (publicValue->data[0] == 0x04) { + if (encoding == ECPoint_Uncompressed) { /* key encoded in uncompressed form */ return ((publicValue->len - 1) / 2); } @@ -2176,6 +2213,11 @@ pk11_PubDeriveECKeyWithKDF( /* old PKCS #11 spec was ambiguous on what needed to be passed, * try this again with an encoded public key */ if (crv != CKR_OK) { + /* For curves that only use X as public value and no encoding we don't + * have to try again. (Currently only Curve25519) */ + if (pk11_ECGetPubkeyEncoding(pubKey) == ECPoint_XOnly) { + goto loser; + } SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, &pubKey->u.ec.publicValue, SEC_ASN1_GET(SEC_OctetStringTemplate)); diff --git a/nss/lib/pk11wrap/pk11slot.c b/nss/lib/pk11wrap/pk11slot.c index c66ae27..db805c1 100644 --- a/nss/lib/pk11wrap/pk11slot.c +++ b/nss/lib/pk11wrap/pk11slot.c @@ -18,6 +18,7 @@ #include "dev3hack.h" #include "pkim.h" #include "utilpars.h" +#include "pkcs11uri.h" /************************************************************* * local static and global data @@ -409,6 +410,7 @@ PK11_NewSlotInfo(SECMODModule *mod) slot->slot_name[0] = 0; slot->token_name[0] = 0; PORT_Memset(slot->serial, ' ', sizeof(slot->serial)); + PORT_Memset(&slot->tokenInfo, 0, sizeof(slot->tokenInfo)); slot->module = NULL; slot->authTransact = 0; slot->authTime = LL_ZERO; @@ -1077,6 +1079,29 @@ PK11_MakeString(PLArenaPool *arena, char *space, } /* + * check if a null-terminated string matches with a PKCS11 Static Label + */ +PRBool +pk11_MatchString(const char *string, + const char *staticString, int staticStringLen) +{ + int i; + + for (i = (staticStringLen - 1); i >= 0; i--) { + if (staticString[i] != ' ') + break; + } + /* move i to point to the last space */ + i++; + + if (strlen(string) == i && memcmp(string, staticString, i) == 0) { + return PR_TRUE; + } + + return PR_FALSE; +} + +/* * Reads in the slots mechanism list for later use */ SECStatus @@ -1140,7 +1165,6 @@ PK11_ReadMechanismList(PK11SlotInfo *slot) SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) { - CK_TOKEN_INFO tokenInfo; CK_RV crv; SECStatus rv; PRStatus status; @@ -1148,7 +1172,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) /* set the slot flags to the current token values */ if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &tokenInfo); + crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &slot->tokenInfo); if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); if (crv != CKR_OK) { @@ -1159,13 +1183,13 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) /* set the slot flags to the current token values */ slot->series++; /* allow other objects to detect that the * slot is different */ - slot->flags = tokenInfo.flags; - slot->needLogin = ((tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE); - slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE); + slot->flags = slot->tokenInfo.flags; + slot->needLogin = ((slot->tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE); + slot->readOnly = ((slot->tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE); - slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); + slot->hasRandom = ((slot->tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); slot->protectedAuthPath = - ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + ((slot->tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? PR_TRUE : PR_FALSE); slot->lastLoginCheck = 0; @@ -1176,15 +1200,15 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) slot->protectedAuthPath = PR_FALSE; } (void)PK11_MakeString(NULL, slot->token_name, - (char *)tokenInfo.label, sizeof(tokenInfo.label)); - slot->minPassword = tokenInfo.ulMinPinLen; - slot->maxPassword = tokenInfo.ulMaxPinLen; - PORT_Memcpy(slot->serial, tokenInfo.serialNumber, sizeof(slot->serial)); + (char *)slot->tokenInfo.label, sizeof(slot->tokenInfo.label)); + slot->minPassword = slot->tokenInfo.ulMinPinLen; + slot->maxPassword = slot->tokenInfo.ulMaxPinLen; + PORT_Memcpy(slot->serial, slot->tokenInfo.serialNumber, sizeof(slot->serial)); nssToken_UpdateName(slot->nssToken); slot->defRWSession = (PRBool)((!slot->readOnly) && - (tokenInfo.ulMaxSessionCount == 1)); + (slot->tokenInfo.ulMaxSessionCount == 1)); rv = PK11_ReadMechanismList(slot); if (rv != SECSuccess) return rv; @@ -1193,13 +1217,13 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) slot->RSAInfoFlags = 0; /* initialize the maxKeyCount value */ - if (tokenInfo.ulMaxSessionCount == 0) { + if (slot->tokenInfo.ulMaxSessionCount == 0) { slot->maxKeyCount = 800; /* should be #define or a config param */ - } else if (tokenInfo.ulMaxSessionCount < 20) { + } else if (slot->tokenInfo.ulMaxSessionCount < 20) { /* don't have enough sessions to keep that many keys around */ slot->maxKeyCount = 0; } else { - slot->maxKeyCount = tokenInfo.ulMaxSessionCount / 2; + slot->maxKeyCount = slot->tokenInfo.ulMaxSessionCount / 2; } /* Make sure our session handle is valid */ @@ -1331,13 +1355,12 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) SECStatus PK11_TokenRefresh(PK11SlotInfo *slot) { - CK_TOKEN_INFO tokenInfo; CK_RV crv; /* set the slot flags to the current token values */ if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &tokenInfo); + crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &slot->tokenInfo); if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); if (crv != CKR_OK) { @@ -1345,12 +1368,12 @@ PK11_TokenRefresh(PK11SlotInfo *slot) return SECFailure; } - slot->flags = tokenInfo.flags; - slot->needLogin = ((tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE); - slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE); - slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); + slot->flags = slot->tokenInfo.flags; + slot->needLogin = ((slot->tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE); + slot->readOnly = ((slot->tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE); + slot->hasRandom = ((slot->tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); slot->protectedAuthPath = - ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + ((slot->tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) ? PR_TRUE : PR_FALSE); /* on some platforms Active Card incorrectly sets the @@ -1666,6 +1689,63 @@ PK11_GetTokenName(PK11SlotInfo *slot) } char * +PK11_GetTokenURI(PK11SlotInfo *slot) +{ + PK11URI *uri; + char *ret = NULL; + char label[32 + 1], manufacturer[32 + 1], serial[16 + 1], model[16 + 1]; + PK11URIAttribute attrs[4]; + size_t nattrs = 0; + + PK11_MakeString(NULL, label, (char *)slot->tokenInfo.label, + sizeof(slot->tokenInfo.label)); + if (*label != '\0') { + attrs[nattrs].name = PK11URI_PATTR_TOKEN; + attrs[nattrs].value = label; + nattrs++; + } + + PK11_MakeString(NULL, manufacturer, (char *)slot->tokenInfo.manufacturerID, + sizeof(slot->tokenInfo.manufacturerID)); + if (*manufacturer != '\0') { + attrs[nattrs].name = PK11URI_PATTR_MANUFACTURER; + attrs[nattrs].value = manufacturer; + nattrs++; + } + + PK11_MakeString(NULL, serial, (char *)slot->tokenInfo.serialNumber, + sizeof(slot->tokenInfo.serialNumber)); + if (*serial != '\0') { + attrs[nattrs].name = PK11URI_PATTR_SERIAL; + attrs[nattrs].value = serial; + nattrs++; + } + + PK11_MakeString(NULL, model, (char *)slot->tokenInfo.model, + sizeof(slot->tokenInfo.model)); + if (*model != '\0') { + attrs[nattrs].name = PK11URI_PATTR_MODEL; + attrs[nattrs].value = model; + nattrs++; + } + + uri = PK11URI_CreateURI(attrs, nattrs, NULL, 0); + if (uri == NULL) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return NULL; + } + + ret = PK11URI_FormatURI(NULL, uri); + PK11URI_DestroyURI(uri); + + if (ret == NULL) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + } + + return ret; +} + +char * PK11_GetSlotName(PK11SlotInfo *slot) { return slot->slot_name; @@ -1771,6 +1851,46 @@ PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info) return SECSuccess; } +PRBool +pk11_MatchUriTokenInfo(PK11SlotInfo *slot, PK11URI *uri) +{ + const char *value; + + value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_TOKEN); + if (value) { + if (!pk11_MatchString(value, (char *)slot->tokenInfo.label, + sizeof(slot->tokenInfo.label))) { + return PR_FALSE; + } + } + + value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MANUFACTURER); + if (value) { + if (!pk11_MatchString(value, (char *)slot->tokenInfo.manufacturerID, + sizeof(slot->tokenInfo.manufacturerID))) { + return PR_FALSE; + } + } + + value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_SERIAL); + if (value) { + if (!pk11_MatchString(value, (char *)slot->tokenInfo.serialNumber, + sizeof(slot->tokenInfo.serialNumber))) { + return PR_FALSE; + } + } + + value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MODEL); + if (value) { + if (!pk11_MatchString(value, (char *)slot->tokenInfo.model, + sizeof(slot->tokenInfo.model))) { + return PR_FALSE; + } + } + + return PR_TRUE; +} + /* Find out if we need to initialize the user's pin */ PRBool PK11_NeedUserInit(PK11SlotInfo *slot) @@ -2291,6 +2411,14 @@ PK11_GetMaxKeyLength(CK_MECHANISM_TYPE mechanism) } } } + + /* fallback to pk11_GetPredefinedKeyLength for fixed key size algorithms */ + if (keyLength == 0) { + CK_KEY_TYPE keyType; + keyType = PK11_GetKeyType(mechanism, 0); + keyLength = pk11_GetPredefinedKeyLength(keyType); + } + if (le) PK11_FreeSlotListElement(list, le); if (freeit) diff --git a/nss/lib/pk11wrap/pk11util.c b/nss/lib/pk11wrap/pk11util.c index 9636b07..a962e9b 100644 --- a/nss/lib/pk11wrap/pk11util.c +++ b/nss/lib/pk11wrap/pk11util.c @@ -14,6 +14,7 @@ #include "secerr.h" #include "dev.h" #include "utilpars.h" +#include "pkcs11uri.h" /* these are for displaying error messages */ @@ -590,6 +591,58 @@ PK11_GetModInfo(SECMODModule *mod, CK_INFO *info) return (crv == CKR_OK) ? SECSuccess : SECFailure; } +char * +PK11_GetModuleURI(SECMODModule *mod) +{ + CK_INFO info; + PK11URI *uri; + char *ret = NULL; + PK11URIAttribute attrs[3]; + size_t nattrs = 0; + char libraryManufacturer[32 + 1], libraryDescription[32 + 1], libraryVersion[8]; + + if (PK11_GetModInfo(mod, &info) == SECFailure) { + return NULL; + } + + PK11_MakeString(NULL, libraryManufacturer, (char *)info.manufacturerID, + sizeof(info.manufacturerID)); + if (*libraryManufacturer != '\0') { + attrs[nattrs].name = PK11URI_PATTR_LIBRARY_MANUFACTURER; + attrs[nattrs].value = libraryManufacturer; + nattrs++; + } + + PK11_MakeString(NULL, libraryDescription, (char *)info.libraryDescription, + sizeof(info.libraryDescription)); + if (*libraryDescription != '\0') { + attrs[nattrs].name = PK11URI_PATTR_LIBRARY_DESCRIPTION; + attrs[nattrs].value = libraryDescription; + nattrs++; + } + + PR_snprintf(libraryVersion, sizeof(libraryVersion), "%d.%d", + info.libraryVersion.major, info.libraryVersion.minor); + attrs[nattrs].name = PK11URI_PATTR_LIBRARY_VERSION; + attrs[nattrs].value = libraryVersion; + nattrs++; + + uri = PK11URI_CreateURI(attrs, nattrs, NULL, 0); + if (uri == NULL) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return NULL; + } + + ret = PK11URI_FormatURI(NULL, uri); + PK11URI_DestroyURI(uri); + if (ret == NULL) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return NULL; + } + + return ret; +} + /* Determine if we have the FIP's module loaded as the default * module to trigger other bogus FIPS requirements in PKCS #12 and * SSL diff --git a/nss/lib/pk11wrap/pk11wrap.gyp b/nss/lib/pk11wrap/pk11wrap.gyp index 2af27a0..35fdace 100644 --- a/nss/lib/pk11wrap/pk11wrap.gyp +++ b/nss/lib/pk11wrap/pk11wrap.gyp @@ -7,35 +7,54 @@ ], 'targets': [ { - 'target_name': 'pk11wrap', + 'target_name': 'pk11wrap_static', 'type': 'static_library', - 'sources': [ - 'dev3hack.c', - 'pk11akey.c', - 'pk11auth.c', - 'pk11cert.c', - 'pk11cxt.c', - 'pk11err.c', - 'pk11kea.c', - 'pk11list.c', - 'pk11load.c', - 'pk11mech.c', - 'pk11merge.c', - 'pk11nobj.c', - 'pk11obj.c', - 'pk11pars.c', - 'pk11pbe.c', - 'pk11pk12.c', - 'pk11pqg.c', - 'pk11sdr.c', - 'pk11skey.c', - 'pk11slot.c', - 'pk11util.c' + 'defines': [ + 'NSS_TEST_BUILD', + ], + 'dependencies': [ + 'pk11wrap_base', + '<(DEPTH)/exports.gyp:nss_exports', + '<(DEPTH)/lib/softoken/softoken.gyp:softokn_static', ], + }, + { + 'target_name': 'pk11wrap', + 'type': 'static_library', 'dependencies': [ - '<(DEPTH)/exports.gyp:nss_exports' - ] - } + 'pk11wrap_base', + '<(DEPTH)/exports.gyp:nss_exports', + ], + }, + { + 'target_name': 'pk11wrap_base', + 'type': 'none', + 'direct_dependent_settings': { + 'sources': [ + 'dev3hack.c', + 'pk11akey.c', + 'pk11auth.c', + 'pk11cert.c', + 'pk11cxt.c', + 'pk11err.c', + 'pk11kea.c', + 'pk11list.c', + 'pk11load.c', + 'pk11mech.c', + 'pk11merge.c', + 'pk11nobj.c', + 'pk11obj.c', + 'pk11pars.c', + 'pk11pbe.c', + 'pk11pk12.c', + 'pk11pqg.c', + 'pk11sdr.c', + 'pk11skey.c', + 'pk11slot.c', + 'pk11util.c' + ], + }, + }, ], 'target_defaults': { 'defines': [ @@ -48,4 +67,4 @@ 'variables': { 'module': 'nss' } -}
\ No newline at end of file +} diff --git a/nss/lib/pk11wrap/secmodti.h b/nss/lib/pk11wrap/secmodti.h index 5201655..63c2079 100644 --- a/nss/lib/pk11wrap/secmodti.h +++ b/nss/lib/pk11wrap/secmodti.h @@ -107,6 +107,8 @@ struct PK11SlotInfoStr { unsigned int lastState; /* for Stan */ NSSToken *nssToken; + /* the tokeninfo struct */ + CK_TOKEN_INFO tokenInfo; /* fast mechanism lookup */ char mechanismBits[256]; }; diff --git a/nss/lib/pkcs12/p12d.c b/nss/lib/pkcs12/p12d.c index d0b6476..57333ac 100644 --- a/nss/lib/pkcs12/p12d.c +++ b/nss/lib/pkcs12/p12d.c @@ -177,6 +177,8 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid) SEC_PKCS12DecoderContext *p12dcx = (SEC_PKCS12DecoderContext *)arg; PK11SlotInfo *slot; PK11SymKey *bulkKey; + SECItem pwitem = { 0 }; + SECOidTag algorithm; if (!p12dcx) { return NULL; @@ -189,8 +191,11 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid) slot = PK11_GetInternalKeySlot(); } - bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem, - PR_FALSE, p12dcx->wincx); + algorithm = SECOID_GetAlgorithmTag(algid); + if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm, p12dcx->pwitem)) + return NULL; + + bulkKey = PK11_PBEKeyGen(slot, algid, &pwitem, PR_FALSE, p12dcx->wincx); /* some tokens can't generate PBE keys on their own, generate the * key in the internal slot, and let the Import code deal with it, * (if the slot can't generate PBEs, then we need to use the internal @@ -198,8 +203,7 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid) if (!bulkKey && !PK11_IsInternal(slot)) { PK11_FreeSlot(slot); slot = PK11_GetInternalKeySlot(); - bulkKey = PK11_PBEKeyGen(slot, algid, p12dcx->pwitem, - PR_FALSE, p12dcx->wincx); + bulkKey = PK11_PBEKeyGen(slot, algid, &pwitem, PR_FALSE, p12dcx->wincx); } PK11_FreeSlot(slot); @@ -208,6 +212,10 @@ sec_pkcs12_decoder_get_decrypt_key(void *arg, SECAlgorithmID *algid) PK11_SetSymKeyUserData(bulkKey, p12dcx->pwitem, NULL); } + if (pwitem.data) { + SECITEM_ZfreeItem(&pwitem, PR_FALSE); + } + return bulkKey; } @@ -1335,11 +1343,23 @@ sec_pkcs12_decoder_verify_mac(SEC_PKCS12DecoderContext *p12dcx) case SEC_OID_MD2: integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; break; + case SEC_OID_SHA224: + integrityMech = CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN; + break; + case SEC_OID_SHA256: + integrityMech = CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN; + break; + case SEC_OID_SHA384: + integrityMech = CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN; + break; + case SEC_OID_SHA512: + integrityMech = CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN; + break; default: goto loser; } - symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL); + symKey = PK11_KeyGen(NULL, integrityMech, params, 0, NULL); PK11_DestroyPBEParams(params); params = NULL; if (!symKey) @@ -2440,13 +2460,25 @@ sec_pkcs12_add_key(sec_PKCS12SafeBag *key, SECKEYPublicKey *pubKey, nickName, publicValue, PR_TRUE, PR_TRUE, keyUsage, wincx); break; - case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID: + case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID: { + SECItem pwitem = { 0 }; + SECAlgorithmID *algid = + &key->safeBagContent.pkcs8ShroudedKeyBag->algorithm; + SECOidTag algorithm = SECOID_GetAlgorithmTag(algid); + + if (!sec_pkcs12_decode_password(NULL, &pwitem, algorithm, + key->pwitem)) + return SECFailure; rv = PK11_ImportEncryptedPrivateKeyInfo(key->slot, key->safeBagContent.pkcs8ShroudedKeyBag, - key->pwitem, nickName, publicValue, + &pwitem, nickName, publicValue, PR_TRUE, PR_TRUE, keyType, keyUsage, wincx); + if (pwitem.data) { + SECITEM_ZfreeItem(&pwitem, PR_FALSE); + } break; + } default: key->error = SEC_ERROR_PKCS12_UNSUPPORTED_VERSION; key->problem = PR_TRUE; diff --git a/nss/lib/pkcs12/p12e.c b/nss/lib/pkcs12/p12e.c index cce1ff7..4a21d89 100644 --- a/nss/lib/pkcs12/p12e.c +++ b/nss/lib/pkcs12/p12e.c @@ -10,6 +10,7 @@ #include "seccomon.h" #include "secport.h" #include "cert.h" +#include "secpkcs5.h" #include "secpkcs7.h" #include "secasn1.h" #include "secerr.h" @@ -378,17 +379,25 @@ SEC_PKCS12CreatePasswordPrivSafe(SEC_PKCS12ExportContext *p12ctxt, safeInfo->itemCount = 0; /* create the encrypted safe */ - safeInfo->cinfo = SEC_PKCS7CreateEncryptedData(privAlg, 0, p12ctxt->pwfn, - p12ctxt->pwfnarg); + if (!SEC_PKCS5IsAlgorithmPBEAlgTag(privAlg) && + PK11_AlgtagToMechanism(privAlg) == CKM_AES_CBC) { + safeInfo->cinfo = SEC_PKCS7CreateEncryptedDataWithPBEV2(SEC_OID_PKCS5_PBES2, + privAlg, + SEC_OID_UNKNOWN, + 0, + p12ctxt->pwfn, + p12ctxt->pwfnarg); + } else { + safeInfo->cinfo = SEC_PKCS7CreateEncryptedData(privAlg, 0, p12ctxt->pwfn, + p12ctxt->pwfnarg); + } if (!safeInfo->cinfo) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } safeInfo->arena = p12ctxt->arena; - /* convert the password to unicode */ - if (!sec_pkcs12_convert_item_to_unicode(NULL, &uniPwitem, pwitem, - PR_TRUE, PR_TRUE, PR_TRUE)) { + if (!sec_pkcs12_encode_password(NULL, &uniPwitem, privAlg, pwitem)) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } @@ -1203,8 +1212,8 @@ SEC_PKCS12AddKeyForCert(SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *sa SECKEYEncryptedPrivateKeyInfo *epki = NULL; PK11SlotInfo *slot = NULL; - if (!sec_pkcs12_convert_item_to_unicode(p12ctxt->arena, &uniPwitem, - pwitem, PR_TRUE, PR_TRUE, PR_TRUE)) { + if (!sec_pkcs12_encode_password(p12ctxt->arena, &uniPwitem, algorithm, + pwitem)) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } diff --git a/nss/lib/pkcs12/p12local.c b/nss/lib/pkcs12/p12local.c index d7f0d9e..a94c08b 100644 --- a/nss/lib/pkcs12/p12local.c +++ b/nss/lib/pkcs12/p12local.c @@ -949,6 +949,73 @@ sec_pkcs12_convert_item_to_unicode(PLArenaPool *arena, SECItem *dest, return PR_TRUE; } +PRBool +sec_pkcs12_is_pkcs12_pbe_algorithm(SECOidTag algorithm) +{ + switch (algorithm) { + case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: + case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: + case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: + case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: + case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: + case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: + case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: + case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: + case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: + case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: + case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: + /* those are actually PKCS #5 v1.5 PBEs, but we + * historically treat them in the same way as PKCS #12 + * PBEs */ + case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: + case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: + case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: + return PR_TRUE; + default: + return PR_FALSE; + } +} + +/* this function decodes a password from Unicode if necessary, + * according to the PBE algorithm. + * + * we assume that the pwitem is already encoded in Unicode by the + * caller. if the encryption scheme is not the one defined in PKCS + * #12, decode the pwitem back into UTF-8. */ +PRBool +sec_pkcs12_decode_password(PLArenaPool *arena, + SECItem *result, + SECOidTag algorithm, + const SECItem *pwitem) +{ + if (!sec_pkcs12_is_pkcs12_pbe_algorithm(algorithm)) + return sec_pkcs12_convert_item_to_unicode(arena, result, + (SECItem *)pwitem, + PR_TRUE, PR_FALSE, PR_FALSE); + + return SECITEM_CopyItem(arena, result, pwitem) == SECSuccess; +} + +/* this function encodes a password into Unicode if necessary, + * according to the PBE algorithm. + * + * we assume that the pwitem holds a raw password. if the encryption + * scheme is the one defined in PKCS #12, encode the password into + * BMPString. */ +PRBool +sec_pkcs12_encode_password(PLArenaPool *arena, + SECItem *result, + SECOidTag algorithm, + const SECItem *pwitem) +{ + if (sec_pkcs12_is_pkcs12_pbe_algorithm(algorithm)) + return sec_pkcs12_convert_item_to_unicode(arena, result, + (SECItem *)pwitem, + PR_TRUE, PR_TRUE, PR_TRUE); + + return SECITEM_CopyItem(arena, result, pwitem) == SECSuccess; +} + /* pkcs 12 templates */ static const SEC_ASN1TemplateChooserPtr sec_pkcs12_shroud_chooser = sec_pkcs12_choose_shroud_type; diff --git a/nss/lib/pkcs12/p12local.h b/nss/lib/pkcs12/p12local.h index f07122a..06a56d1 100644 --- a/nss/lib/pkcs12/p12local.h +++ b/nss/lib/pkcs12/p12local.h @@ -55,4 +55,15 @@ sec_PKCS12ConvertOldSafeToNew(PLArenaPool *arena, PK11SlotInfo *slot, void *wincx, SEC_PKCS12SafeContents *safe, SEC_PKCS12Baggage *baggage); +extern PRBool sec_pkcs12_is_pkcs12_pbe_algorithm(SECOidTag algorithm); + +extern PRBool sec_pkcs12_decode_password(PLArenaPool *arena, + SECItem *result, + SECOidTag algorithm, + const SECItem *pwitem); +extern PRBool sec_pkcs12_encode_password(PLArenaPool *arena, + SECItem *result, + SECOidTag algorithm, + const SECItem *pwitem); + #endif diff --git a/nss/lib/pkcs12/p12plcy.c b/nss/lib/pkcs12/p12plcy.c index fef288c..97970ab 100644 --- a/nss/lib/pkcs12/p12plcy.c +++ b/nss/lib/pkcs12/p12plcy.c @@ -24,6 +24,9 @@ static pkcs12SuiteMap pkcs12SuiteMaps[] = { { SEC_OID_RC2_CBC, 128, PKCS12_RC2_CBC_128, PR_FALSE, PR_FALSE }, { SEC_OID_DES_CBC, 64, PKCS12_DES_56, PR_FALSE, PR_FALSE }, { SEC_OID_DES_EDE3_CBC, 192, PKCS12_DES_EDE3_168, PR_FALSE, PR_FALSE }, + { SEC_OID_AES_128_CBC, 128, PKCS12_AES_CBC_128, PR_FALSE, PR_FALSE }, + { SEC_OID_AES_192_CBC, 192, PKCS12_AES_CBC_192, PR_FALSE, PR_FALSE }, + { SEC_OID_AES_256_CBC, 256, PKCS12_AES_CBC_256, PR_FALSE, PR_FALSE }, { SEC_OID_UNKNOWN, 0, PKCS12_NULL, PR_FALSE, PR_FALSE }, { SEC_OID_UNKNOWN, 0, 0L, PR_FALSE, PR_FALSE } }; diff --git a/nss/lib/pkcs7/p7create.c b/nss/lib/pkcs7/p7create.c index fcf0cad..96ada5c 100644 --- a/nss/lib/pkcs7/p7create.c +++ b/nss/lib/pkcs7/p7create.c @@ -1245,3 +1245,56 @@ SEC_PKCS7CreateEncryptedData(SECOidTag algorithm, int keysize, return cinfo; } + +SEC_PKCS7ContentInfo * +SEC_PKCS7CreateEncryptedDataWithPBEV2(SECOidTag pbe_algorithm, + SECOidTag cipher_algorithm, + SECOidTag prf_algorithm, + int keysize, + SECKEYGetPasswordKey pwfn, void *pwfn_arg) +{ + SEC_PKCS7ContentInfo *cinfo; + SECAlgorithmID *algid; + SEC_PKCS7EncryptedData *enc_data; + SECStatus rv; + + PORT_Assert(SEC_PKCS5IsAlgorithmPBEAlgTag(pbe_algorithm)); + + cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_ENCRYPTED_DATA, + PR_FALSE, pwfn, pwfn_arg); + if (cinfo == NULL) + return NULL; + + enc_data = cinfo->content.encryptedData; + algid = &(enc_data->encContentInfo.contentEncAlg); + + SECAlgorithmID *pbe_algid; + pbe_algid = PK11_CreatePBEV2AlgorithmID(pbe_algorithm, + cipher_algorithm, + prf_algorithm, + keysize, + NSS_PBE_DEFAULT_ITERATION_COUNT, + NULL); + if (pbe_algid == NULL) { + rv = SECFailure; + } else { + rv = SECOID_CopyAlgorithmID(cinfo->poolp, algid, pbe_algid); + SECOID_DestroyAlgorithmID(pbe_algid, PR_TRUE); + } + + if (rv != SECSuccess) { + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; + } + + rv = sec_pkcs7_init_encrypted_content_info(&(enc_data->encContentInfo), + cinfo->poolp, + SEC_OID_PKCS7_DATA, PR_FALSE, + cipher_algorithm, keysize); + if (rv != SECSuccess) { + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; + } + + return cinfo; +} diff --git a/nss/lib/pkcs7/p7encode.c b/nss/lib/pkcs7/p7encode.c index bdbc343..af3da59 100644 --- a/nss/lib/pkcs7/p7encode.c +++ b/nss/lib/pkcs7/p7encode.c @@ -510,7 +510,7 @@ sec_pkcs7_encoder_work_data(SEC_PKCS7EncoderContext *p7ecx, SECItem *dest, * No output is expected, but the input data may be buffered * so we still have to call Encrypt. */ - rv = sec_PKCS7Encrypt(p7ecx->encryptobj, NULL, NULL, 0, + rv = sec_PKCS7Encrypt(p7ecx->encryptobj, NULL, &outlen, 0, data, inlen, final); if (final) { len = 0; diff --git a/nss/lib/pkcs7/secpkcs7.h b/nss/lib/pkcs7/secpkcs7.h index d95c7d8..78270bd 100644 --- a/nss/lib/pkcs7/secpkcs7.h +++ b/nss/lib/pkcs7/secpkcs7.h @@ -287,6 +287,26 @@ SEC_PKCS7CreateEncryptedData(SECOidTag algorithm, int keysize, SECKEYGetPasswordKey pwfn, void *pwfn_arg); /* + * Create an empty PKCS7 encrypted content info. + * + * Similar to SEC_PKCS7CreateEncryptedData(), but this is capable of + * creating encrypted content for PKCS #5 v2 algorithms. + * + * "pbe_algorithm" specifies the PBE algorithm to use. + * "cipher_algorithm" specifies the bulk encryption algorithm to use. + * "prf_algorithm" specifies the PRF algorithm which pbe_algorithm uses. + * + * An error results in a return value of NULL and an error set. + * (Retrieve specific errors via PORT_GetError()/XP_GetError().) + */ +extern SEC_PKCS7ContentInfo * +SEC_PKCS7CreateEncryptedDataWithPBEV2(SECOidTag pbe_algorithm, + SECOidTag cipher_algorithm, + SECOidTag prf_algorithm, + int keysize, + SECKEYGetPasswordKey pwfn, void *pwfn_arg); + +/* * All of the following things return SECStatus to signal success or failure. * Failure should have a more specific error status available via * PORT_GetError()/XP_GetError(). diff --git a/nss/lib/pki/cryptocontext.c b/nss/lib/pki/cryptocontext.c index 074eb74..0ec4f2f 100644 --- a/nss/lib/pki/cryptocontext.c +++ b/nss/lib/pki/cryptocontext.c @@ -47,7 +47,10 @@ NSS_IMPLEMENT PRStatus NSSCryptoContext_Destroy(NSSCryptoContext *cc) { PRStatus status = PR_SUCCESS; - PORT_Assert(cc->certStore); + PORT_Assert(cc && cc->certStore); + if (!cc) { + return PR_FAILURE; + } if (cc->certStore) { status = nssCertificateStore_Destroy(cc->certStore); if (status == PR_FAILURE) { @@ -93,8 +96,8 @@ NSSCryptoContext_FindOrImportCertificate( { NSSCertificate *rvCert = NULL; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return rvCert; } @@ -146,8 +149,8 @@ nssCryptoContext_ImportTrust( NSSTrust *trust) { PRStatus nssrv; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return PR_FAILURE; } nssrv = nssCertificateStore_AddTrust(cc->certStore, trust); @@ -165,8 +168,8 @@ nssCryptoContext_ImportSMIMEProfile( nssSMIMEProfile *profile) { PRStatus nssrv; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return PR_FAILURE; } nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile); @@ -189,8 +192,8 @@ NSSCryptoContext_FindBestCertificateByNickname( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore, @@ -215,8 +218,8 @@ NSSCryptoContext_FindCertificatesByNickname( NSSArena *arenaOpt) { NSSCertificate **rvCerts; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } rvCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore, @@ -233,8 +236,8 @@ NSSCryptoContext_FindCertificateByIssuerAndSerialNumber( NSSDER *issuer, NSSDER *serialNumber) { - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } return nssCertificateStore_FindCertificateByIssuerAndSerialNumber( @@ -253,8 +256,8 @@ NSSCryptoContext_FindBestCertificateBySubject( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore, @@ -279,8 +282,8 @@ nssCryptoContext_FindCertificatesBySubject( NSSArena *arenaOpt) { NSSCertificate **rvCerts; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } rvCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore, @@ -333,8 +336,8 @@ NSSCryptoContext_FindCertificateByEncodedCertificate( NSSCryptoContext *cc, NSSBER *encodedCertificate) { - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } return nssCertificateStore_FindCertificateByEncodedCertificate( @@ -353,8 +356,8 @@ NSSCryptoContext_FindBestCertificateByEmail( NSSCertificate **certs; NSSCertificate *rvCert = NULL; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore, @@ -379,8 +382,8 @@ NSSCryptoContext_FindCertificatesByEmail( NSSArena *arenaOpt) { NSSCertificate **rvCerts; - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } rvCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore, @@ -488,8 +491,8 @@ nssCryptoContext_FindTrustForCertificate( NSSCryptoContext *cc, NSSCertificate *cert) { - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } return nssCertificateStore_FindTrustForCertificate(cc->certStore, cert); @@ -500,8 +503,8 @@ nssCryptoContext_FindSMIMEProfileForCertificate( NSSCryptoContext *cc, NSSCertificate *cert) { - PORT_Assert(cc->certStore); - if (!cc->certStore) { + PORT_Assert(cc && cc->certStore); + if (!cc || !cc->certStore) { return NULL; } return nssCertificateStore_FindSMIMEProfileForCertificate(cc->certStore, diff --git a/nss/lib/pki/nsspki.h b/nss/lib/pki/nsspki.h index 28780c3..0ecec08 100644 --- a/nss/lib/pki/nsspki.h +++ b/nss/lib/pki/nsspki.h @@ -23,6 +23,8 @@ #include "base.h" #endif /* BASE_H */ +#include "pkcs11uri.h" + PR_BEGIN_EXTERN_C /* @@ -1302,6 +1304,16 @@ NSSTrustDomain_IsTokenEnabled( NSSError *whyOpt); /* + * NSSTrustDomain_FindTokensByURI + * + */ + +NSS_EXTERN NSSToken ** +NSSTrustDomain_FindTokensByURI( + NSSTrustDomain *td, + PK11URI *uri); + +/* * NSSTrustDomain_FindSlotByName * */ diff --git a/nss/lib/pki/pki3hack.c b/nss/lib/pki/pki3hack.c index 0826b7f..5488539 100644 --- a/nss/lib/pki/pki3hack.c +++ b/nss/lib/pki/pki3hack.c @@ -831,8 +831,10 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced cc->dbhandle = c->object.trustDomain; /* subjectList ? */ /* istemp and isperm are supported in NSS 3.4 */ + CERT_LockCertTempPerm(cc); cc->istemp = PR_FALSE; /* CERT_NewTemp will override this */ cc->isperm = PR_TRUE; /* by default */ + CERT_UnlockCertTempPerm(cc); /* pointer back */ cc->nssCertificate = c; if (trust) { diff --git a/nss/lib/pki/trustdomain.c b/nss/lib/pki/trustdomain.c index 49f7dc5..151b888 100644 --- a/nss/lib/pki/trustdomain.c +++ b/nss/lib/pki/trustdomain.c @@ -14,6 +14,7 @@ #include "pki3hack.h" #include "pk11pub.h" #include "nssrwlk.h" +#include "pk11priv.h" #define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32 @@ -234,6 +235,37 @@ NSSTrustDomain_FindSlotByName( return NULL; } +NSS_IMPLEMENT NSSToken ** +NSSTrustDomain_FindTokensByURI( + NSSTrustDomain *td, + PK11URI *uri) +{ + NSSToken *tok = NULL; + PK11SlotInfo *slotinfo; + NSSToken **tokens; + int count, i = 0; + + NSSRWLock_LockRead(td->tokensLock); + count = nssList_Count(td->tokenList); + tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1); + if (!tokens) { + return NULL; + } + for (tok = (NSSToken *)nssListIterator_Start(td->tokens); + tok != (NSSToken *)NULL; + tok = (NSSToken *)nssListIterator_Next(td->tokens)) { + if (nssToken_IsPresent(tok)) { + slotinfo = tok->pk11slot; + if (pk11_MatchUriTokenInfo(slotinfo, uri)) + tokens[i++] = nssToken_AddRef(tok); + } + } + tokens[i] = NULL; + nssListIterator_Finish(td->tokens); + NSSRWLock_UnlockRead(td->tokensLock); + return tokens; +} + NSS_IMPLEMENT NSSToken * NSSTrustDomain_FindTokenByName( NSSTrustDomain *td, @@ -248,8 +280,10 @@ NSSTrustDomain_FindTokenByName( tok = (NSSToken *)nssListIterator_Next(td->tokens)) { if (nssToken_IsPresent(tok)) { myName = nssToken_GetName(tok); - if (nssUTF8_Equal(tokenName, myName, &nssrv)) + if (nssUTF8_Equal(tokenName, myName, &nssrv)) { + tok = nssToken_AddRef(tok); break; + } } } nssListIterator_Finish(td->tokens); diff --git a/nss/lib/softoken/legacydb/dbmshim.c b/nss/lib/softoken/legacydb/dbmshim.c index 40728d5..cca24bc 100644 --- a/nss/lib/softoken/legacydb/dbmshim.c +++ b/nss/lib/softoken/legacydb/dbmshim.c @@ -47,9 +47,6 @@ struct DBSStr { char *blobdir; int mode; PRBool readOnly; - PRFileMap *dbs_mapfile; - unsigned char *dbs_addr; - PRUint32 dbs_len; char staticBlobArea[BLOB_BUF_LEN]; }; @@ -244,43 +241,6 @@ loser: } /* - * we need to keep a address map in memory between calls to DBM. - * remember what we have mapped can close it when we get another dbm - * call. - * - * NOTE: Not all platforms support mapped files. This code is designed to - * detect this at runtime. If map files aren't supported the OS will indicate - * this by failing the PR_Memmap call. In this case we emulate mapped files - * by just reading in the file into regular memory. We signal this state by - * making dbs_mapfile NULL and dbs_addr non-NULL. - */ - -static void -dbs_freemap(DBS *dbsp) -{ - if (dbsp->dbs_mapfile) { - PR_MemUnmap(dbsp->dbs_addr, dbsp->dbs_len); - PR_CloseFileMap(dbsp->dbs_mapfile); - dbsp->dbs_mapfile = NULL; - dbsp->dbs_addr = NULL; - dbsp->dbs_len = 0; - } else if (dbsp->dbs_addr) { - PORT_Free(dbsp->dbs_addr); - dbsp->dbs_addr = NULL; - dbsp->dbs_len = 0; - } - return; -} - -static void -dbs_setmap(DBS *dbsp, PRFileMap *mapfile, unsigned char *addr, PRUint32 len) -{ - dbsp->dbs_mapfile = mapfile; - dbsp->dbs_addr = addr; - dbsp->dbs_len = len; -} - -/* * platforms that cannot map the file need to read it into a temp buffer. */ static unsigned char * @@ -317,7 +277,6 @@ dbs_readBlob(DBS *dbsp, DBT *data) { char *file = NULL; PRFileDesc *filed = NULL; - PRFileMap *mapfile = NULL; unsigned char *addr = NULL; int error; int len = -1; @@ -334,23 +293,16 @@ dbs_readBlob(DBS *dbsp, DBT *data) } len = dbs_getBlobSize(data); - mapfile = PR_CreateFileMap(filed, len, PR_PROT_READONLY); - if (mapfile == NULL) { - /* USE PR_GetError instead of PORT_GetError here - * because we are getting the error from PR_xxx - * function */ - if (PR_GetError() != PR_NOT_IMPLEMENTED_ERROR) { - goto loser; - } - addr = dbs_EmulateMap(filed, len); - } else { - addr = PR_MemMap(mapfile, 0, len); - } + /* Bug 1323150 + * PR_MemMap fails on Windows for larger certificates. + * https://msdn.microsoft.com/en-us/library/windows/desktop/aa366761(v=vs.85).aspx + * Let's always use the emulated map, i.e. read the file. + */ + addr = dbs_EmulateMap(filed, len); if (addr == NULL) { goto loser; } PR_Close(filed); - dbs_setmap(dbsp, mapfile, addr, len); data->data = addr; data->size = len; @@ -359,9 +311,6 @@ dbs_readBlob(DBS *dbsp, DBT *data) loser: /* preserve the error code */ error = PR_GetError(); - if (mapfile) { - PR_CloseFileMap(mapfile); - } if (filed) { PR_Close(filed); } @@ -379,8 +328,6 @@ dbs_get(const DB *dbs, const DBT *key, DBT *data, unsigned int flags) DBS *dbsp = (DBS *)dbs; DB *db = (DB *)dbs->internal; - dbs_freemap(dbsp); - ret = (*db->get)(db, key, data, flags); if ((ret == 0) && dbs_IsBlob(data)) { ret = dbs_readBlob(dbsp, data); @@ -397,8 +344,6 @@ dbs_put(const DB *dbs, DBT *key, const DBT *data, unsigned int flags) DBS *dbsp = (DBS *)dbs; DB *db = (DB *)dbs->internal; - dbs_freemap(dbsp); - /* If the db is readonly, just pass the data down to rdb and let it fail */ if (!dbsp->readOnly) { DBT oldData; @@ -431,10 +376,6 @@ static int dbs_sync(const DB *dbs, unsigned int flags) { DB *db = (DB *)dbs->internal; - DBS *dbsp = (DBS *)dbs; - - dbs_freemap(dbsp); - return (*db->sync)(db, flags); } @@ -445,8 +386,6 @@ dbs_del(const DB *dbs, const DBT *key, unsigned int flags) DBS *dbsp = (DBS *)dbs; DB *db = (DB *)dbs->internal; - dbs_freemap(dbsp); - if (!dbsp->readOnly) { DBT oldData; ret = (*db->get)(db, key, &oldData, 0); @@ -465,8 +404,6 @@ dbs_seq(const DB *dbs, DBT *key, DBT *data, unsigned int flags) DBS *dbsp = (DBS *)dbs; DB *db = (DB *)dbs->internal; - dbs_freemap(dbsp); - ret = (*db->seq)(db, key, data, flags); if ((ret == 0) && dbs_IsBlob(data)) { /* don't return a blob read as an error so traversals keep going */ @@ -483,7 +420,6 @@ dbs_close(DB *dbs) DB *db = (DB *)dbs->internal; int ret; - dbs_freemap(dbsp); ret = (*db->close)(db); PORT_Free(dbsp->blobdir); PORT_Free(dbsp); @@ -574,9 +510,6 @@ dbsopen(const char *dbname, int flags, int mode, DBTYPE type, } dbsp->mode = mode; dbsp->readOnly = (PRBool)(flags == NO_RDONLY); - dbsp->dbs_mapfile = NULL; - dbsp->dbs_addr = NULL; - dbsp->dbs_len = 0; /* the real dbm call */ db = dbopen(dbname, flags, mode, type, &dbs_hashInfo); diff --git a/nss/lib/softoken/legacydb/legacydb.gyp b/nss/lib/softoken/legacydb/legacydb.gyp index 6431fb5..34c0235 100644 --- a/nss/lib/softoken/legacydb/legacydb.gyp +++ b/nss/lib/softoken/legacydb/legacydb.gyp @@ -57,7 +57,7 @@ 'defines': [ 'SHLIB_SUFFIX=\"<(dll_suffix)\"', 'SHLIB_PREFIX=\"<(dll_prefix)\"', - 'LG_LIB_NAME=\"libnssdbm3.so\"' + 'LG_LIB_NAME=\"<(dll_prefix)nssdbm3.<(dll_suffix)\"' ] }, 'variables': { diff --git a/nss/lib/softoken/legacydb/pcertdb.c b/nss/lib/softoken/legacydb/pcertdb.c index 65da516..f1444bf 100644 --- a/nss/lib/softoken/legacydb/pcertdb.c +++ b/nss/lib/softoken/legacydb/pcertdb.c @@ -733,6 +733,12 @@ DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry) entry->derCert.len += lenoff; } + /* Is data long enough? */ + if (dbentry->len < headerlen + entry->derCert.len) { + PORT_SetError(SEC_ERROR_BAD_DATABASE); + goto loser; + } + /* copy the dercert */ entry->derCert.data = pkcs11_copyStaticData(&dbentry->data[headerlen], entry->derCert.len, entry->derCertSpace, sizeof(entry->derCertSpace)); @@ -743,6 +749,11 @@ DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry) /* copy the nickname */ if (nnlen > 1) { + /* Is data long enough? */ + if (dbentry->len < headerlen + entry->derCert.len + nnlen) { + PORT_SetError(SEC_ERROR_BAD_DATABASE); + goto loser; + } entry->nickname = (char *)pkcs11_copyStaticData( &dbentry->data[headerlen + entry->derCert.len], nnlen, (unsigned char *)entry->nicknameSpace, diff --git a/nss/lib/softoken/lowpbe.c b/nss/lib/softoken/lowpbe.c index b78302e..0a47804 100644 --- a/nss/lib/softoken/lowpbe.c +++ b/nss/lib/softoken/lowpbe.c @@ -408,7 +408,6 @@ loser: return result; } -#define HMAC_BUFFER 64 #define NSSPBE_ROUNDUP(x, y) ((((x) + ((y)-1)) / (y)) * (y)) #define NSSPBE_MIN(x, y) ((x) < (y) ? (x) : (y)) /* @@ -430,6 +429,7 @@ nsspkcs5_PKCS12PBE(const SECHashObject *hashObject, int iter; unsigned char *iterBuf; void *hash = NULL; + unsigned int bufferLength; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { @@ -439,8 +439,11 @@ nsspkcs5_PKCS12PBE(const SECHashObject *hashObject, /* how many hash object lengths are needed */ c = (bytesNeeded + (hashLength - 1)) / hashLength; + /* 64 if 0 < hashLength <= 32, 128 if 32 < hashLength <= 64 */ + bufferLength = NSSPBE_ROUNDUP(hashLength * 2, 64); + /* initialize our buffers */ - D.len = HMAC_BUFFER; + D.len = bufferLength; /* B and D are the same length, use one alloc go get both */ D.data = (unsigned char *)PORT_ArenaZAlloc(arena, D.len * 2); B.len = D.len; @@ -452,8 +455,8 @@ nsspkcs5_PKCS12PBE(const SECHashObject *hashObject, goto loser; } - SLen = NSSPBE_ROUNDUP(salt->len, HMAC_BUFFER); - PLen = NSSPBE_ROUNDUP(pwitem->len, HMAC_BUFFER); + SLen = NSSPBE_ROUNDUP(salt->len, bufferLength); + PLen = NSSPBE_ROUNDUP(pwitem->len, bufferLength); I.len = SLen + PLen; I.data = (unsigned char *)PORT_ArenaZAlloc(arena, I.len); if (I.data == NULL) { diff --git a/nss/lib/softoken/pkcs11.c b/nss/lib/softoken/pkcs11.c index 77212f7..a594fd5 100644 --- a/nss/lib/softoken/pkcs11.c +++ b/nss/lib/softoken/pkcs11.c @@ -480,6 +480,10 @@ static const struct mechanismList mechanisms[] = { { CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, { 20, 20, CKF_GENERATE }, PR_TRUE }, { CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE }, { CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, { 16, 16, CKF_GENERATE }, PR_TRUE }, + { CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN, { 28, 28, CKF_GENERATE }, PR_TRUE }, + { CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN, { 32, 32, CKF_GENERATE }, PR_TRUE }, + { CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN, { 48, 48, CKF_GENERATE }, PR_TRUE }, + { CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN, { 64, 64, CKF_GENERATE }, PR_TRUE }, /* ------------------ AES Key Wrap (also encrypt) ------------------- */ { CKM_NETSCAPE_AES_KEY_WRAP, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, { CKM_NETSCAPE_AES_KEY_WRAP_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, @@ -1795,7 +1799,7 @@ sftk_GetPubKey(SFTKObject *object, CK_KEY_TYPE key_type, crv = sftk_Attribute2SSecItem(arena, &pubKey->u.ec.publicValue, object, CKA_EC_POINT); if (crv == CKR_OK) { - unsigned int keyLen = pubKey->u.ec.ecParams.pointSize; + unsigned int keyLen = EC_GetPointSize(&pubKey->u.ec.ecParams); /* special note: We can't just use the first byte to distinguish * between EC_POINT_FORM_UNCOMPRESSED and SEC_ASN1_OCTET_STRING. @@ -3145,9 +3149,11 @@ nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS) * this call doesn't force freebl to be reloaded. */ BL_SetForkState(PR_FALSE); +#ifndef NSS_TEST_BUILD /* unload freeBL shared library from memory. This may only decrement the * OS refcount if it's been loaded multiple times, eg. by libssl */ BL_Unload(); +#endif /* clean up the default OID table */ SECOID_Shutdown(); @@ -4757,7 +4763,7 @@ sftk_pruneSearch(CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, static CK_RV sftk_searchTokenList(SFTKSlot *slot, SFTKSearchResults *search, CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount, - PRBool *tokenOnly, PRBool isLoggedIn) + PRBool isLoggedIn) { CK_RV crv = CKR_OK; CK_RV crv2; @@ -4792,7 +4798,6 @@ NSC_FindObjectsInit(CK_SESSION_HANDLE hSession, SFTKSearchResults *search = NULL, *freeSearch = NULL; SFTKSession *session = NULL; SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - PRBool tokenOnly = PR_FALSE; CK_RV crv = CKR_OK; PRBool isLoggedIn; @@ -4823,18 +4828,15 @@ NSC_FindObjectsInit(CK_SESSION_HANDLE hSession, search->array_size = NSC_SEARCH_BLOCK_SIZE; isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn); - crv = sftk_searchTokenList(slot, search, pTemplate, ulCount, &tokenOnly, - isLoggedIn); + crv = sftk_searchTokenList(slot, search, pTemplate, ulCount, isLoggedIn); if (crv != CKR_OK) { goto loser; } /* build list of found objects in the session */ - if (!tokenOnly) { - crv = sftk_searchObjectList(search, slot->sessObjHashTable, - slot->sessObjHashSize, slot->objectLock, - pTemplate, ulCount, isLoggedIn); - } + crv = sftk_searchObjectList(search, slot->sessObjHashTable, + slot->sessObjHashSize, slot->objectLock, + pTemplate, ulCount, isLoggedIn); if (crv != CKR_OK) { goto loser; } diff --git a/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c index d7b4bb9..e290495 100644 --- a/nss/lib/softoken/pkcs11c.c +++ b/nss/lib/softoken/pkcs11c.c @@ -3971,6 +3971,22 @@ nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe) params->hashType = HASH_AlgMD2; params->keyLen = 16; break; + case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: + params->hashType = HASH_AlgSHA224; + params->keyLen = 28; + break; + case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: + params->hashType = HASH_AlgSHA256; + params->keyLen = 32; + break; + case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: + params->hashType = HASH_AlgSHA384; + params->keyLen = 48; + break; + case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: + params->hashType = HASH_AlgSHA512; + params->keyLen = 64; + break; default: PORT_FreeArena(arena, PR_TRUE); return CKR_MECHANISM_INVALID; @@ -4189,6 +4205,10 @@ NSC_GenerateKey(CK_SESSION_HANDLE hSession, case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN: case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN: case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: + case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: key_gen_type = nsc_pbe; key_type = CKK_GENERIC_SECRET; crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param); @@ -5571,6 +5591,7 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) switch (SECOID_GetAlgorithmTag(&pki->algorithm)) { case SEC_OID_PKCS1_RSA_ENCRYPTION: + case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: keyTemplate = nsslowkey_RSAPrivateKeyTemplate; paramTemplate = NULL; paramDest = NULL; @@ -7220,14 +7241,9 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, ecPoint.data = mechParams->pPublicData; ecPoint.len = mechParams->ulPublicDataLen; - pubKeyLen = privKey->u.ec.ecParams.pointSize; + pubKeyLen = EC_GetPointSize(&privKey->u.ec.ecParams); - /* if the len is too small, can't be a valid point */ - if (ecPoint.len < pubKeyLen) { - goto ec_loser; - } - /* if the len is too large, must be an encoded point (length is - * equal case just falls through */ + /* if the len is too large, might be an encoded point */ if (ecPoint.len > pubKeyLen) { SECItem newPoint; @@ -7247,14 +7263,6 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession, if (mechanism == CKM_ECDH1_COFACTOR_DERIVE) { withCofactor = PR_TRUE; - } else { - /* When not using cofactor derivation, one should - * validate the public key to avoid small subgroup - * attacks. - */ - if (EC_ValidatePublicKey(&privKey->u.ec.ecParams, &ecPoint) != SECSuccess) { - goto ec_loser; - } } rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar, diff --git a/nss/lib/softoken/pkcs11u.c b/nss/lib/softoken/pkcs11u.c index a5694ee..c51211b 100644 --- a/nss/lib/softoken/pkcs11u.c +++ b/nss/lib/softoken/pkcs11u.c @@ -1649,10 +1649,8 @@ sftk_searchObjectList(SFTKSearchResults *search, SFTKObject **head, SFTKObject *object; CK_RV crv = CKR_OK; + PZ_Lock(lock); for (i = 0; i < size; i++) { - /* We need to hold the lock to copy a consistant version of - * the linked list. */ - PZ_Lock(lock); for (object = head[i]; object != NULL; object = object->next) { if (sftk_objectMatch(object, theTemplate, count)) { /* don't return objects that aren't yet visible */ @@ -1661,8 +1659,8 @@ sftk_searchObjectList(SFTKSearchResults *search, SFTKObject **head, sftk_addHandle(search, object->handle); } } - PZ_Unlock(lock); } + PZ_Unlock(lock); return crv; } diff --git a/nss/lib/softoken/sdb.c b/nss/lib/softoken/sdb.c index 0e321dd..8690df3 100644 --- a/nss/lib/softoken/sdb.c +++ b/nss/lib/softoken/sdb.c @@ -674,8 +674,8 @@ struct SDBFindStr { sqlite3_stmt *findstmt; }; -static const char FIND_OBJECTS_CMD[] = "SELECT ALL * FROM %s WHERE %s;"; -static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL * FROM %s;"; +static const char FIND_OBJECTS_CMD[] = "SELECT ALL id FROM %s WHERE %s;"; +static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL id FROM %s;"; CK_RV sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count, SDBFind **find) diff --git a/nss/lib/softoken/softkver.h b/nss/lib/softoken/softkver.h index cbdd29b..709a03c 100644 --- a/nss/lib/softoken/softkver.h +++ b/nss/lib/softoken/softkver.h @@ -21,10 +21,10 @@ * The format of the version string should be * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" */ -#define SOFTOKEN_VERSION "3.28.1" SOFTOKEN_ECC_STRING +#define SOFTOKEN_VERSION "3.31" SOFTOKEN_ECC_STRING #define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 28 -#define SOFTOKEN_VPATCH 1 +#define SOFTOKEN_VMINOR 31 +#define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VBUILD 0 #define SOFTOKEN_BETA PR_FALSE diff --git a/nss/lib/softoken/softoken.gyp b/nss/lib/softoken/softoken.gyp index 8d72e60..ba917cf 100644 --- a/nss/lib/softoken/softoken.gyp +++ b/nss/lib/softoken/softoken.gyp @@ -7,35 +7,65 @@ ], 'targets': [ { - 'target_name': 'softokn', + 'target_name': 'softokn_static', 'type': 'static_library', - 'sources': [ - 'fipsaudt.c', - 'fipstest.c', - 'fipstokn.c', - 'jpakesftk.c', - 'lgglue.c', - 'lowkey.c', - 'lowpbe.c', - 'padbuf.c', - 'pkcs11.c', - 'pkcs11c.c', - 'pkcs11u.c', - 'sdb.c', - 'sftkdb.c', - 'sftkhmac.c', - 'sftkpars.c', - 'sftkpwd.c', - 'softkver.c', - 'tlsprf.c' + 'defines': [ + 'NSS_TEST_BUILD', + ], + 'dependencies': [ + 'softokn_base', + '<(DEPTH)/exports.gyp:nss_exports', + '<(DEPTH)/lib/freebl/freebl.gyp:freebl_static', + ], + 'conditions': [ + [ 'use_system_sqlite==1', { + 'dependencies': [ + '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3', + ], + }, { + 'dependencies': [ + '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite', + ], + }], ], + }, + { + 'target_name': 'softokn', + 'type': 'static_library', 'dependencies': [ + 'softokn_base', '<(DEPTH)/exports.gyp:nss_exports', '<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3', '<(DEPTH)/lib/freebl/freebl.gyp:freebl', ] }, { + 'target_name': 'softokn_base', + 'type': 'none', + 'direct_dependent_settings': { + 'sources': [ + 'fipsaudt.c', + 'fipstest.c', + 'fipstokn.c', + 'jpakesftk.c', + 'lgglue.c', + 'lowkey.c', + 'lowpbe.c', + 'padbuf.c', + 'pkcs11.c', + 'pkcs11c.c', + 'pkcs11u.c', + 'sdb.c', + 'sftkdb.c', + 'sftkhmac.c', + 'sftkpars.c', + 'sftkpwd.c', + 'softkver.c', + 'tlsprf.c' + ], + }, + }, + { 'target_name': 'softokn3', 'type': 'shared_library', 'dependencies': [ @@ -61,7 +91,7 @@ 'defines': [ 'SHLIB_SUFFIX=\"<(dll_suffix)\"', 'SHLIB_PREFIX=\"<(dll_prefix)\"', - 'SOFTOKEN_LIB_NAME=\"libsoftokn3.so\"', + 'SOFTOKEN_LIB_NAME=\"<(dll_prefix)softokn3.<(dll_suffix)\"', 'SHLIB_VERSION=\"3\"' ] }, diff --git a/nss/lib/softoken/softoken.h b/nss/lib/softoken/softoken.h index 0e943d3..4626e78 100644 --- a/nss/lib/softoken/softoken.h +++ b/nss/lib/softoken/softoken.h @@ -183,7 +183,7 @@ extern PRBool sftk_fatalError; #define CHECK_FORK_MIXED -#elif defined(LINUX) +#elif defined(LINUX) || defined(__GLIBC__) || defined(FREEBSD) || defined(OPENBSD) #define CHECK_FORK_PTHREAD diff --git a/nss/lib/ssl/SSLerrs.h b/nss/lib/ssl/SSLerrs.h index b0319b8..b73fb6b 100644 --- a/nss/lib/ssl/SSLerrs.h +++ b/nss/lib/ssl/SSLerrs.h @@ -504,4 +504,10 @@ ER3(SSL_ERROR_MALFORMED_PSK_KEY_EXCHANGE_MODES, (SSL_ERROR_BASE + 158), "SSL received a malformed PSK key exchange modes extension.") ER3(SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES, (SSL_ERROR_BASE + 159), - "SSL expected a missing PSK key exchange modes extension.") + "SSL expected a PSK key exchange modes extension.") + +ER3(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA, (SSL_ERROR_BASE + 160), + "SSL got a pre-TLS 1.3 version even though we sent early data.") + +ER3(SSL_ERROR_TOO_MUCH_EARLY_DATA, (SSL_ERROR_BASE + 161), + "SSL received more early data than permitted.") diff --git a/nss/lib/ssl/config.mk b/nss/lib/ssl/config.mk index 339cc80..c8b053c 100644 --- a/nss/lib/ssl/config.mk +++ b/nss/lib/ssl/config.mk @@ -62,10 +62,6 @@ DEFINES += -DNSS_SSL_ENABLE_ZLIB include $(CORE_DEPTH)/coreconf/zlib.mk endif -ifndef NSS_ENABLE_TLS_1_3 -NSS_DISABLE_TLS_1_3=1 -endif - ifdef NSS_DISABLE_TLS_1_3 DEFINES += -DNSS_DISABLE_TLS_1_3 endif diff --git a/nss/lib/ssl/dtlscon.c b/nss/lib/ssl/dtlscon.c index 09ceeac..b33dc2a 100644 --- a/nss/lib/ssl/dtlscon.c +++ b/nss/lib/ssl/dtlscon.c @@ -235,6 +235,26 @@ dtls_RetransmitDetected(sslSocket *ss) return rv; } +static SECStatus +dtls_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *data, PRBool last) +{ + + /* At this point we are advancing our state machine, so we can free our last + * flight of messages. */ + dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); + ss->ssl3.hs.recvdHighWater = -1; + + /* Reset the timer to the initial value if the retry counter + * is 0, per Sec. 4.2.4.1 */ + dtls_CancelTimer(ss); + if (ss->ssl3.hs.rtRetries == 0) { + ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_MS; + } + + return ssl3_HandleHandshakeMessage(ss, data, ss->ssl3.hs.msg_len, + last); +} + /* Called only from ssl3_HandleRecord, for each (deciphered) DTLS record. * origBuf is the decrypted ssl record content and is expected to contain * complete handshake records @@ -329,23 +349,10 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) ss->ssl3.hs.msg_type = (SSL3HandshakeType)type; ss->ssl3.hs.msg_len = message_length; - /* At this point we are advancing our state machine, so - * we can free our last flight of messages */ - dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); - ss->ssl3.hs.recvdHighWater = -1; - dtls_CancelTimer(ss); - - /* Reset the timer to the initial value if the retry counter - * is 0, per Sec. 4.2.4.1 */ - if (ss->ssl3.hs.rtRetries == 0) { - ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_MS; - } - - rv = ssl3_HandleHandshakeMessage(ss, buf.buf, ss->ssl3.hs.msg_len, + rv = dtls_HandleHandshakeMessage(ss, buf.buf, buf.len == fragment_length); if (rv == SECFailure) { - /* Do not attempt to process rest of messages in this record */ - break; + break; /* Discard the remainder of the record. */ } } else { if (message_seq < ss->ssl3.hs.recvMessageSeq) { @@ -446,24 +453,11 @@ dtls_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) /* If we have all the bytes, then we are good to go */ if (ss->ssl3.hs.recvdHighWater == ss->ssl3.hs.msg_len) { - ss->ssl3.hs.recvdHighWater = -1; + rv = dtls_HandleHandshakeMessage(ss, ss->ssl3.hs.msg_body.buf, + buf.len == fragment_length); - rv = ssl3_HandleHandshakeMessage( - ss, - ss->ssl3.hs.msg_body.buf, ss->ssl3.hs.msg_len, - buf.len == fragment_length); - if (rv == SECFailure) - break; /* Skip rest of record */ - - /* At this point we are advancing our state machine, so - * we can free our last flight of messages */ - dtls_FreeHandshakeMessages(&ss->ssl3.hs.lastMessageFlight); - dtls_CancelTimer(ss); - - /* If there have been no retries this time, reset the - * timer value to the default per Section 4.2.4.1 */ - if (ss->ssl3.hs.rtRetries == 0) { - ss->ssl3.hs.rtTimeoutMs = DTLS_RETRANSMIT_INITIAL_MS; + if (rv == SECFailure) { + break; /* Discard the rest of the record. */ } } } diff --git a/nss/lib/ssl/ssl.def b/nss/lib/ssl/ssl.def index 6aa8b64..94d3042 100644 --- a/nss/lib/ssl/ssl.def +++ b/nss/lib/ssl/ssl.def @@ -221,3 +221,16 @@ SSL_SignatureSchemePrefGet; ;+ local: ;+*; ;+}; +;+NSS_3.30 { # NSS 3.30 release +;+ global: +SSL_SetSessionTicketKeyPair; +;+ local: +;+*; +;+}; +;+NSS_3.30.0.1 { # Additional symbols for NSS 3.30 release +;+ global: +SSL_AlertReceivedCallback; +SSL_AlertSentCallback; +;+ local: +;+*; +;+}; diff --git a/nss/lib/ssl/ssl.gyp b/nss/lib/ssl/ssl.gyp index 0306ab6..175d1ce 100644 --- a/nss/lib/ssl/ssl.gyp +++ b/nss/lib/ssl/ssl.gyp @@ -63,7 +63,7 @@ 'NSS_SSL_ENABLE_ZLIB', ], }], - [ 'fuzz==1', { + [ 'fuzz_tls==1', { 'defines': [ 'UNSAFE_FUZZER_MODE', ], @@ -71,7 +71,6 @@ ], 'dependencies': [ '<(DEPTH)/exports.gyp:nss_exports', - '<(DEPTH)/lib/freebl/freebl.gyp:freebl', ], }, { @@ -81,6 +80,7 @@ 'ssl', '<(DEPTH)/lib/nss/nss.gyp:nss3', '<(DEPTH)/lib/util/util.gyp:nssutil3', + '<(DEPTH)/lib/freebl/freebl.gyp:freebl', ], 'variables': { 'mapfile': 'ssl.def' diff --git a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h index b4af0e1..f19c2de 100644 --- a/nss/lib/ssl/ssl.h +++ b/nss/lib/ssl/ssl.h @@ -228,7 +228,7 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd); * on the server to read that data. Calls to * SSL_GetPreliminaryChannelInfo() and SSL_GetNextProto() * can be made used during this period to learn about the channel - * parameters [TODO(ekr@rtfm.com): This hasn't landed yet]. + * parameters. * * The transition between the 0-RTT and 1-RTT modes is marked by the * handshake callback. @@ -356,10 +356,11 @@ SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy); ** that is compatible with both its certificate and its peer's supported ** values. ** -** NSS uses the strict signature schemes from TLS 1.3 in TLS 1.2. That means -** that if a peer indicates support for SHA-384 and ECDSA, NSS will not -** generate a signature if it has a P-256 key, even though that is permitted in -** TLS 1.2. +** This configuration affects TLS 1.2, but the combination of EC group and hash +** algorithm is interpreted loosely to be compatible with other implementations. +** For TLS 1.2, NSS will ignore the curve group when generating or verifying +** ECDSA signatures. For example, a P-384 ECDSA certificate is used with +** SHA-256 if ssl_sig_ecdsa_secp256r1_sha256 is enabled. ** ** Omitting SHA-256 schemes from this list might be foolish. Support is ** mandatory in TLS 1.2 and 1.3 and there might be interoperability issues. @@ -819,6 +820,25 @@ SSL_IMPORT PRFileDesc *SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd); SSL_IMPORT SECStatus SSL_SetPKCS11PinArg(PRFileDesc *fd, void *a); /* +** These are callbacks for dealing with SSL alerts. + */ + +typedef PRUint8 SSLAlertLevel; +typedef PRUint8 SSLAlertDescription; + +typedef struct { + SSLAlertLevel level; + SSLAlertDescription description; +} SSLAlert; + +typedef void(PR_CALLBACK *SSLAlertCallback)(const PRFileDesc *fd, void *arg, + const SSLAlert *alert); + +SSL_IMPORT SECStatus SSL_AlertReceivedCallback(PRFileDesc *fd, SSLAlertCallback cb, + void *arg); +SSL_IMPORT SECStatus SSL_AlertSentCallback(PRFileDesc *fd, SSLAlertCallback cb, + void *arg); +/* ** This is a callback for dealing with server certs that are not authenticated ** by the client. The client app can decide that it actually likes the ** cert by some external means and restart the connection. @@ -914,6 +934,19 @@ SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, SECKEYPrivateKey *key, SSLKEAType kea); /* +** SSL_SetSessionTicketKeyPair configures an asymmetric key pair for use in +** wrapping session ticket keys, used by the server. This function currently +** only accepts an RSA public/private key pair. +** +** Prior to the existence of this function, NSS used an RSA private key +** associated with a configured certificate to perform session ticket +** encryption. If this function isn't used, the keys provided with a configured +** RSA certificate are used for wrapping session ticket keys. +*/ +SSL_IMPORT SECStatus +SSL_SetSessionTicketKeyPair(SECKEYPublicKey *pubKey, SECKEYPrivateKey *privKey); + +/* ** Configure a secure server's session-id cache. Define the maximum number ** of entries in the cache, the longevity of the entires, and the directory ** where the cache files will be placed. These values can be zero, and diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c index 154d22a..5d3bd07 100644 --- a/nss/lib/ssl/ssl3con.c +++ b/nss/lib/ssl/ssl3con.c @@ -38,13 +38,6 @@ #include "zlib.h" #endif -#ifndef PK11_SETATTRS -#define PK11_SETATTRS(x, id, v, l) \ - (x)->type = (id); \ - (x)->pValue = (v); \ - (x)->ulValueLen = (l); -#endif - static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, PK11SlotInfo *serverKeySlot); static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); @@ -273,10 +266,6 @@ static const /*SSL3ClientCertificateType */ PRUint8 certificate_types[] = { ct_DSS_sign, }; -/* This global item is used only in servers. It is is initialized by -** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest(). -*/ -CERTDistNames *ssl3_server_ca_list = NULL; static SSL3Statistics ssl3stats; /* Record protection algorithms, indexed by SSL3BulkCipher. @@ -863,12 +852,10 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType) cursor != &ss->serverCerts; cursor = PR_NEXT_LINK(cursor)) { sslServerCert *cert = (sslServerCert *)cursor; - if (cert->certType.authType != authType) { - continue; - } if (!cert->serverKeyPair || !cert->serverKeyPair->privKey || - !cert->serverCertChain) { + !cert->serverCertChain || + !SSL_CERT_IS(cert, authType)) { continue; } /* When called from ssl3_config_match_init(), all the EC curves will be @@ -879,7 +866,7 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType) if ((authType == ssl_auth_ecdsa || authType == ssl_auth_ecdh_ecdsa || authType == ssl_auth_ecdh_rsa) && - !ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) { + !ssl_NamedGroupEnabled(ss, cert->namedCurve)) { continue; } return PR_TRUE; @@ -1044,8 +1031,9 @@ Null_Cipher(void *ctx, unsigned char *output, int *outputLen, int maxOutputLen, return SECFailure; } *outputLen = inputLen; - if (input != output) + if (inputLen > 0 && input != output) { PORT_Memcpy(output, input, inputLen); + } return SECSuccess; } @@ -1088,10 +1076,11 @@ ssl_ClientReadVersion(sslSocket *ss, SSL3Opaque **b, unsigned int *len, SSL3ProtocolVersion *version) { SSL3ProtocolVersion v; - PRInt32 temp; + PRUint32 temp; + SECStatus rv; - temp = ssl3_ConsumeHandshakeNumber(ss, 2, b, len); - if (temp < 0) { + rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, b, len); + if (rv != SECSuccess) { return SECFailure; /* alert has been sent */ } @@ -1624,10 +1613,6 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss) pwSpec->compressContext = NULL; pwSpec->decompressContext = NULL; - if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) { - PORT_Assert(ss->ssl3.hs.kea_def->ephemeral); - PORT_Assert(pwSpec->cipher_def->type == type_aead); - } ssl_ReleaseSpecWriteLock(ss); /*******************************/ return SECSuccess; } @@ -1777,29 +1762,6 @@ ssl3_InitCompressionContext(ssl3CipherSpec *pwSpec) return SECSuccess; } -/* This function should probably be moved to pk11wrap and be named - * PK11_ParamFromIVAndEffectiveKeyBits - */ -static SECItem * -ssl3_ParamFromIV(CK_MECHANISM_TYPE mtype, SECItem *iv, CK_ULONG ulEffectiveBits) -{ - SECItem *param = PK11_ParamFromIV(mtype, iv); - if (param && param->data && param->len >= sizeof(CK_RC2_PARAMS)) { - switch (mtype) { - case CKM_RC2_KEY_GEN: - case CKM_RC2_ECB: - case CKM_RC2_CBC: - case CKM_RC2_MAC: - case CKM_RC2_MAC_GENERAL: - case CKM_RC2_CBC_PAD: - *(CK_RC2_PARAMS *)param->data = ulEffectiveBits; - default: - break; - } - } - return param; -} - /* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data * which is included in the MAC or AEAD additional data) to |out| and returns * its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the @@ -1981,7 +1943,6 @@ ssl3_InitPendingContexts(sslSocket *ss) CK_MECHANISM_TYPE mechanism; CK_MECHANISM_TYPE mac_mech; CK_ULONG macLength; - CK_ULONG effKeyBits; SECItem iv; SECItem mac_param; SSLCipherAlgorithm calg; @@ -2051,14 +2012,13 @@ ssl3_InitPendingContexts(sslSocket *ss) return SECSuccess; } mechanism = ssl3_Alg2Mech(calg); - effKeyBits = cipher_def->key_size * BPB; /* * build the server context */ iv.data = pwSpec->server.write_iv; iv.len = cipher_def->iv_size; - param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits); + param = PK11_ParamFromIV(mechanism, &iv); if (param == NULL) { ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); goto fail; @@ -2082,7 +2042,7 @@ ssl3_InitPendingContexts(sslSocket *ss) iv.data = pwSpec->client.write_iv; iv.len = cipher_def->iv_size; - param = ssl3_ParamFromIV(mechanism, &iv, effKeyBits); + param = PK11_ParamFromIV(mechanism, &iv); if (param == NULL) { ssl_MapLowLevelError(SSL_ERROR_IV_PARAM_FAILURE); goto fail; @@ -2702,6 +2662,7 @@ ssl3_SendRecord(sslSocket *ss, SECStatus rv; PRInt32 totalSent = 0; PRBool capRecordVersion; + ssl3CipherSpec *spec; SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), @@ -2733,10 +2694,7 @@ ssl3_SendRecord(sslSocket *ss, ** trying to send an alert. */ PR_ASSERT(type == content_alert); - rv = ssl3_InitState(ss); - if (rv != SECSuccess) { - return SECFailure; /* ssl3_InitState has set the error code. */ - } + ssl3_InitState(ss); } /* check for Token Presence */ @@ -2806,11 +2764,12 @@ ssl3_SendRecord(sslSocket *ss, PORT_Assert(IS_DTLS(ss) && (type == content_handshake || type == content_change_cipher_spec)); + spec = cwSpec; } else { - cwSpec = ss->ssl3.cwSpec; + spec = ss->ssl3.cwSpec; } - rv = ssl_ProtectRecord(ss, cwSpec, !IS_DTLS(ss) && capRecordVersion, + rv = ssl_ProtectRecord(ss, spec, !IS_DTLS(ss) && capRecordVersion, type, pIn, contentLen, wrBuf); if (rv == SECSuccess) { PRINT_BUF(50, (ss, "send (encrypted) record data:", @@ -2941,6 +2900,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, ssl_GetXmitBufLock(ss); } toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH); + /* * Note that the 0 epoch is OK because flags will never require * its use, as guaranteed by the PORT_Assert above. @@ -3077,7 +3037,9 @@ ssl3_HandleNoCertificate(sslSocket *ss) (ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE))) { PRFileDesc *lower; - ss->sec.uncache(ss->sec.ci.sid); + if (!ss->opt.noCache) { + ss->sec.uncache(ss->sec.ci.sid); + } SSL3_SendAlert(ss, alert_fatal, bad_certificate); lower = ss->fd->lower; @@ -3124,6 +3086,10 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc) { PRUint8 bytes[2]; SECStatus rv; + PRBool needHsLock = !ssl_HaveSSL3HandshakeLock(ss); + + /* Check that if I need the HS lock I also need the Xmit lock */ + PORT_Assert(!needHsLock || !ssl_HaveXmitBufLock(ss)); SSL_TRC(3, ("%d: SSL3[%d]: send alert record, level=%d desc=%d", SSL_GETPID(), ss->fd, level, desc)); @@ -3131,7 +3097,9 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc) bytes[0] = level; bytes[1] = desc; - ssl_GetSSL3HandshakeLock(ss); + if (needHsLock) { + ssl_GetSSL3HandshakeLock(ss); + } if (level == alert_fatal) { if (!ss->opt.noCache && ss->sec.ci.sid) { ss->sec.uncache(ss->sec.ci.sid); @@ -3149,7 +3117,13 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc) ss->ssl3.fatalAlertSent = PR_TRUE; } ssl_ReleaseXmitBufLock(ss); - ssl_ReleaseSSL3HandshakeLock(ss); + if (needHsLock) { + ssl_ReleaseSSL3HandshakeLock(ss); + } + if (rv == SECSuccess && ss->alertSentCallback) { + SSLAlert alert = { level, desc }; + ss->alertSentCallback(ss->fd, ss->alertSentCallbackArg, &alert); + } return rv; /* error set by ssl3_FlushHandshake or ssl3_SendRecord */ } @@ -3262,6 +3236,11 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) SSL_TRC(5, ("%d: SSL3[%d] received alert, level = %d, description = %d", SSL_GETPID(), ss->fd, level, desc)); + if (ss->alertReceivedCallback) { + SSLAlert alert = { level, desc }; + ss->alertReceivedCallback(ss->fd, ss->alertReceivedCallbackArg, &alert); + } + switch (desc) { case close_notify: ss->recvdCloseNotify = 1; @@ -4088,11 +4067,9 @@ ssl3_InitHandshakeHashes(sslSocket *ss) return SECSuccess; } -SECStatus +void ssl3_RestartHandshakeHashes(sslSocket *ss) { - SECStatus rv = SECSuccess; - SSL_TRC(30, ("%d: SSL3[%d]: reset handshake hashes", SSL_GETPID(), ss->fd)); ss->ssl3.hs.hashType = handshake_hash_unknown; @@ -4105,7 +4082,6 @@ ssl3_RestartHandshakeHashes(sslSocket *ss) PK11_DestroyContext(ss->ssl3.hs.sha, PR_TRUE); ss->ssl3.hs.sha = NULL; } - return rv; } /* @@ -4330,7 +4306,7 @@ ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length) * override the generic error code by setting another. */ SECStatus -ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b, +ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, SSL3Opaque **b, PRUint32 *length) { PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); @@ -4348,37 +4324,33 @@ ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b, /* Read up the next "bytes" number of bytes from the (decrypted) input * stream "b" (which is *length bytes long), and interpret them as an - * integer in network byte order. Returns the received value. + * integer in network byte order. Sets *num to the received value. * Reduces *length by bytes. Advances *b by bytes. * - * Returns SECFailure (-1) on failure. - * This value is indistinguishable from the equivalent received value. - * Only positive numbers are to be received this way. - * Thus, the largest value that may be sent this way is 0x7fffffff. * On error, an alert has been sent, and a generic error code has been set. */ -PRInt32 -ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b, - PRUint32 *length) +SECStatus +ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, PRUint32 bytes, + SSL3Opaque **b, PRUint32 *length) { PRUint8 *buf = *b; int i; - PRInt32 num = 0; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - PORT_Assert(bytes <= sizeof num); - if ((PRUint32)bytes > *length) { + *num = 0; + if (bytes > *length || bytes > sizeof(*num)) { return ssl3_DecodeError(ss); } PRINT_BUF(60, (ss, "consume bytes:", *b, bytes)); - for (i = 0; i < bytes; i++) - num = (num << 8) + buf[i]; + for (i = 0; i < bytes; i++) { + *num = (*num << 8) + buf[i]; + } *b += bytes; *length -= bytes; - return num; + return SECSuccess; } /* Read in two values from the incoming decrypted byte stream "b", which is @@ -4396,21 +4368,22 @@ ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b, * point to the values in the buffer **b. */ SECStatus -ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes, +ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRUint32 bytes, SSL3Opaque **b, PRUint32 *length) { - PRInt32 count; + PRUint32 count; + SECStatus rv; PORT_Assert(bytes <= 3); i->len = 0; i->data = NULL; i->type = siBuffer; - count = ssl3_ConsumeHandshakeNumber(ss, bytes, b, length); - if (count < 0) { /* Can't test for SECSuccess here. */ + rv = ssl3_ConsumeHandshakeNumber(ss, &count, bytes, b, length); + if (rv != SECSuccess) { return SECFailure; } if (count > 0) { - if ((PRUint32)count > *length) { + if (count > *length) { return ssl3_DecodeError(ss); } i->data = *b; @@ -4681,10 +4654,11 @@ SECStatus ssl_ConsumeSignatureScheme(sslSocket *ss, SSL3Opaque **b, PRUint32 *length, SSLSignatureScheme *out) { - PRInt32 tmp; + PRUint32 tmp; + SECStatus rv; - tmp = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); - if (tmp < 0) { + rv = ssl3_ConsumeHandshakeNumber(ss, &tmp, 2, b, length); + if (rv != SECSuccess) { return SECFailure; /* Error code set already. */ } if (!ssl_IsSupportedSignatureScheme((SSLSignatureScheme)tmp)) { @@ -4990,7 +4964,6 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) PRBool isTLS = PR_FALSE; PRBool requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE; PRInt32 total_exten_len = 0; - unsigned paddingExtensionLen; unsigned numCompressionMethods; PRUint16 version; PRInt32 flags; @@ -5013,15 +4986,8 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) if (ss->ssl3.hs.helloRetry) { PORT_Assert(type == client_hello_retry); } else { - rv = ssl3_InitState(ss); - if (rv != SECSuccess) { - return rv; /* ssl3_InitState has set the error code. */ - } - - rv = ssl3_RestartHandshakeHashes(ss); - if (rv != SECSuccess) { - return rv; - } + ssl3_InitState(ss); + ssl3_RestartHandshakeHashes(ss); } /* These must be reset every handshake. */ @@ -5293,19 +5259,12 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) length += 1 + ss->ssl3.hs.cookie.len; } - /* A padding extension may be included to ensure that the record containing - * the ClientHello doesn't have a length between 256 and 511 bytes - * (inclusive). Initial, ClientHello records with such lengths trigger bugs - * in F5 devices. - * - * This is not done for DTLS, for renegotiation, or when there are no - * extensions. */ - if (!IS_DTLS(ss) && isTLS && !ss->firstHsDone && total_exten_len) { - paddingExtensionLen = ssl3_CalculatePaddingExtensionLength(length); - total_exten_len += paddingExtensionLen; - length += paddingExtensionLen; - } else { - paddingExtensionLen = 0; + if (total_exten_len > 0) { + ssl3_CalculatePaddingExtLen(ss, length); + if (ss->xtnData.paddingLen) { + total_exten_len += 4 + ss->xtnData.paddingLen; + length += 4 + ss->xtnData.paddingLen; + } } rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); @@ -5476,15 +5435,6 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type) return rv; /* err set by AppendHandshake. */ } - extLen = ssl3_AppendPaddingExtension(ss, paddingExtensionLen, maxBytes); - if (extLen < 0) { - if (sid->u.ssl3.lock) { - PR_RWLock_Unlock(sid->u.ssl3.lock); - } - return SECFailure; - } - maxBytes -= extLen; - extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL); if (extLen < 0) { if (sid->u.ssl3.lock) { @@ -5579,8 +5529,6 @@ ssl3_HandleHelloRequest(sslSocket *ss) return rv; } -#define UNKNOWN_WRAP_MECHANISM 0x7fffffff - static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = { CKM_DES3_ECB, CKM_CAST5_ECB, @@ -5596,27 +5544,58 @@ static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = { CKM_SKIPJACK_CBC64, CKM_AES_ECB, CKM_CAMELLIA_ECB, - CKM_SEED_ECB, - UNKNOWN_WRAP_MECHANISM + CKM_SEED_ECB }; -static int -ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech) +static SECStatus +ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech, unsigned int *wrapMechIndex) { - const CK_MECHANISM_TYPE *pMech = wrapMechanismList; + unsigned int i; + for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) { + if (wrapMechanismList[i] == mech) { + *wrapMechIndex = i; + return SECSuccess; + } + } + PORT_Assert(0); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +} + +/* Each process sharing the server session ID cache has its own array of SymKey + * pointers for the symmetric wrapping keys that are used to wrap the master + * secrets. There is one key for each authentication type. These Symkeys + * correspond to the wrapped SymKeys kept in the server session cache. + */ +const SSLAuthType ssl_wrap_key_auth_type[SSL_NUM_WRAP_KEYS] = { + ssl_auth_rsa_decrypt, + ssl_auth_rsa_sign, + ssl_auth_rsa_pss, + ssl_auth_ecdsa, + ssl_auth_ecdh_rsa, + ssl_auth_ecdh_ecdsa +}; - while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) { - ++pMech; +static SECStatus +ssl_FindIndexByWrapKey(const sslServerCert *serverCert, unsigned int *wrapKeyIndex) +{ + unsigned int i; + for (i = 0; i < SSL_NUM_WRAP_KEYS; ++i) { + if (SSL_CERT_IS(serverCert, ssl_wrap_key_auth_type[i])) { + *wrapKeyIndex = i; + return SECSuccess; + } } - return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1 - : (pMech - wrapMechanismList); + /* Can't assert here because we still get people using DSA certificates. */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } static PK11SymKey * ssl_UnwrapSymWrappingKey( SSLWrappedSymWrappingKey *pWswk, SECKEYPrivateKey *svrPrivKey, - SSLAuthType authType, + unsigned int wrapKeyIndex, CK_MECHANISM_TYPE masterWrapMech, void *pwArg) { @@ -5628,9 +5607,9 @@ ssl_UnwrapSymWrappingKey( /* found the wrapping key on disk. */ PORT_Assert(pWswk->symWrapMechanism == masterWrapMech); - PORT_Assert(pWswk->authType == authType); + PORT_Assert(pWswk->wrapKeyIndex == wrapKeyIndex); if (pWswk->symWrapMechanism != masterWrapMech || - pWswk->authType != authType) { + pWswk->wrapKeyIndex != wrapKeyIndex) { goto loser; } wrappedKey.type = siBuffer; @@ -5638,7 +5617,7 @@ ssl_UnwrapSymWrappingKey( wrappedKey.len = pWswk->wrappedSymKeyLen; PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey); - switch (authType) { + switch (ssl_wrap_key_auth_type[wrapKeyIndex]) { case ssl_auth_rsa_decrypt: case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */ @@ -5711,14 +5690,8 @@ loser: return unwrappedWrappingKey; } -/* Each process sharing the server session ID cache has its own array of SymKey - * pointers for the symmetric wrapping keys that are used to wrap the master - * secrets. There is one key for each authentication type. These Symkeys - * correspond to the wrapped SymKeys kept in the server session cache. - */ - typedef struct { - PK11SymKey *symWrapKey[ssl_auth_size]; + PK11SymKey *symWrapKey[SSL_NUM_WRAP_KEYS]; } ssl3SymWrapKey; static PZLock *symWrapKeysLock = NULL; @@ -5746,7 +5719,7 @@ SSL3_ShutdownServerCache(void) PZ_Lock(symWrapKeysLock); /* get rid of all symWrapKeys */ for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) { - for (j = 0; j < ssl_auth_size; ++j) { + for (j = 0; j < SSL_NUM_WRAP_KEYS; ++j) { PK11SymKey **pSymWrapKey; pSymWrapKey = &symWrapKeys[i].symWrapKey[j]; if (*pSymWrapKey) { @@ -5780,7 +5753,6 @@ ssl_InitSymWrapKeysLock(void) PK11SymKey * ssl3_GetWrappingKey(sslSocket *ss, PK11SlotInfo *masterSecretSlot, - const sslServerCert *serverCert, CK_MECHANISM_TYPE masterWrapMech, void *pwArg) { @@ -5791,7 +5763,8 @@ ssl3_GetWrappingKey(sslSocket *ss, PK11SymKey **pSymWrapKey; CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM; int length; - int symWrapMechIndex; + unsigned int wrapMechIndex; + unsigned int wrapKeyIndex; SECStatus rv; SECItem wrappedKey; SSLWrappedSymWrappingKey wswk; @@ -5799,6 +5772,7 @@ ssl3_GetWrappingKey(sslSocket *ss, SECKEYPublicKey *pubWrapKey = NULL; SECKEYPrivateKey *privWrapKey = NULL; ECCWrappedKeyInfo *ecWrapped; + const sslServerCert *serverCert = ss->sec.serverCert; PORT_Assert(serverCert); PORT_Assert(serverCert->serverKeyPair); @@ -5810,15 +5784,18 @@ ssl3_GetWrappingKey(sslSocket *ss, PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return NULL; /* hmm */ } - authType = serverCert->certType.authType; - svrPrivKey = serverCert->serverKeyPair->privKey; - symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech); - PORT_Assert(symWrapMechIndex >= 0); - if (symWrapMechIndex < 0) + rv = ssl_FindIndexByWrapKey(serverCert, &wrapKeyIndex); + if (rv != SECSuccess) + return NULL; /* unusable wrapping key. */ + + rv = ssl_FindIndexByWrapMechanism(masterWrapMech, &wrapMechIndex); + if (rv != SECSuccess) return NULL; /* invalid masterWrapMech. */ - pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[authType]; + authType = ssl_wrap_key_auth_type[wrapKeyIndex]; + svrPrivKey = serverCert->serverKeyPair->privKey; + pSymWrapKey = &symWrapKeys[wrapMechIndex].symWrapKey[wrapKeyIndex]; ssl_InitSessionCacheLocks(PR_TRUE); @@ -5837,10 +5814,11 @@ ssl3_GetWrappingKey(sslSocket *ss, /* Try to get wrapped SymWrapping key out of the (disk) cache. */ /* Following call fills in wswk on success. */ - if (ssl_GetWrappingKey(symWrapMechIndex, authType, &wswk)) { + rv = ssl_GetWrappingKey(wrapMechIndex, wrapKeyIndex, &wswk); + if (rv == SECSuccess) { /* found the wrapped sym wrapping key on disk. */ unwrappedWrappingKey = - ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, authType, + ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, wrapKeyIndex, masterWrapMech, pwArg); if (unwrappedWrappingKey) { goto install; @@ -5989,9 +5967,9 @@ ssl3_GetWrappingKey(sslSocket *ss, PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM); wswk.symWrapMechanism = masterWrapMech; - wswk.symWrapMechIndex = symWrapMechIndex; wswk.asymWrapMechanism = asymWrapMechanism; - wswk.authType = authType; + wswk.wrapMechIndex = wrapMechIndex; + wswk.wrapKeyIndex = wrapKeyIndex; wswk.wrappedSymKeyLen = wrappedKey.len; /* put it on disk. */ @@ -5999,7 +5977,8 @@ ssl3_GetWrappingKey(sslSocket *ss, * then abandon the value we just computed and * use the one we got from the disk. */ - if (ssl_SetWrappingKey(&wswk)) { + rv = ssl_SetWrappingKey(&wswk); + if (rv == SECSuccess) { /* somebody beat us to it. The original contents of our wswk * has been replaced with the content on disk. Now, discard * the key we just created and unwrap this new one. @@ -6007,7 +5986,7 @@ ssl3_GetWrappingKey(sslSocket *ss, PK11_FreeSymKey(unwrappedWrappingKey); unwrappedWrappingKey = - ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, authType, + ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, wrapKeyIndex, masterWrapMech, pwArg); } @@ -6377,7 +6356,7 @@ ssl_PickSignatureScheme(sslSocket *ss, PRUint32 policy; if (!ssl_SignatureSchemeValidForKey(!isTLS13 /* allowSha1 */, - PR_TRUE /* matchGroup */, + isTLS13 /* matchGroup */, keyType, group, preferred)) { continue; } @@ -6411,6 +6390,33 @@ ssl_PickSignatureScheme(sslSocket *ss, return SECFailure; } +static SECStatus +ssl_PickFallbackSignatureScheme(sslSocket *ss, SECKEYPublicKey *pubKey) +{ + PRBool isTLS12 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_2; + + switch (SECKEY_GetPublicKeyType(pubKey)) { + case rsaKey: + if (isTLS12) { + ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1; + } else { + ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1md5; + } + break; + case ecKey: + ss->ssl3.hs.signatureScheme = ssl_sig_ecdsa_sha1; + break; + case dsaKey: + ss->ssl3.hs.signatureScheme = ssl_sig_dsa_sha1; + break; + default: + PORT_Assert(0); + PORT_SetError(SEC_ERROR_INVALID_KEY); + return SECFailure; + } + return SECSuccess; +} + /* ssl3_PickServerSignatureScheme selects a signature scheme for signing the * handshake. Most of this is determined by the key pair we are using. * Prior to TLS 1.2, the MD5/SHA1 combination is always used. With TLS 1.2, a @@ -6424,26 +6430,7 @@ ssl3_PickServerSignatureScheme(sslSocket *ss) if (!isTLS12 || !ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) { /* If the client didn't provide any signature_algorithms extension then * we can assume that they support SHA-1: RFC5246, Section 7.4.1.4.1. */ - switch (SECKEY_GetPublicKeyType(keyPair->pubKey)) { - case rsaKey: - if (isTLS12) { - ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1; - } else { - ss->ssl3.hs.signatureScheme = ssl_sig_rsa_pkcs1_sha1md5; - } - break; - case ecKey: - ss->ssl3.hs.signatureScheme = ssl_sig_ecdsa_sha1; - break; - case dsaKey: - ss->ssl3.hs.signatureScheme = ssl_sig_dsa_sha1; - break; - default: - PORT_Assert(0); - PORT_SetError(SEC_ERROR_INVALID_KEY); - return SECFailure; - } - return SECSuccess; + return ssl_PickFallbackSignatureScheme(ss, keyPair->pubKey); } /* Sets error code, if needed. */ @@ -6461,9 +6448,21 @@ ssl_PickClientSignatureScheme(sslSocket *ss, const SSLSignatureScheme *schemes, SECKEYPublicKey *pubKey; SECStatus rv; + PRBool isTLS13 = (PRBool)ss->version >= SSL_LIBRARY_VERSION_TLS_1_3; pubKey = CERT_ExtractPublicKey(ss->ssl3.clientCertificate); PORT_Assert(pubKey); - if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 && + + if (!isTLS13 && numSchemes == 0) { + /* If the server didn't provide any signature algorithms + * then let's assume they support SHA-1. */ + rv = ssl_PickFallbackSignatureScheme(ss, pubKey); + SECKEY_DestroyPublicKey(pubKey); + return rv; + } + + PORT_Assert(schemes && numSchemes > 0); + + if (!isTLS13 && (SECKEY_GetPublicKeyType(pubKey) == rsaKey || SECKEY_GetPublicKeyType(pubKey) == dsaKey) && SECKEY_PublicKeyStrengthInBits(pubKey) <= 1024) { @@ -6606,7 +6605,7 @@ ssl3_SetCipherSuite(sslSocket *ss, ssl3CipherSuite chosenSuite, static SECStatus ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { - PRInt32 temp; /* allow for consume number failure */ + PRUint32 temp; PRBool suite_found = PR_FALSE; int i; int errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO; @@ -6649,11 +6648,21 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) goto loser; /* alert has been sent */ } - /* We got a HelloRetryRequest, but the server didn't pick 1.3. Scream. */ - if (ss->ssl3.hs.helloRetry && ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - desc = illegal_parameter; - errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO; - goto alert_loser; + /* The server didn't pick 1.3 although we either received a + * HelloRetryRequest, or we prepared to send early app data. */ + if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { + if (ss->ssl3.hs.helloRetry) { + /* SSL3_SendAlert() will uncache the SID. */ + desc = illegal_parameter; + errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO; + goto alert_loser; + } + if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) { + /* SSL3_SendAlert() will uncache the SID. */ + desc = illegal_parameter; + errCode = SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA; + goto alert_loser; + } } /* Check that the server negotiated the same version as it did @@ -6721,8 +6730,8 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } /* find selected cipher suite in our list. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); - if (temp < 0) { + rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, &b, &length); + if (rv != SECSuccess) { goto loser; /* alert has been sent */ } i = ssl3_config_match_init(ss); @@ -6767,8 +6776,8 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { /* find selected compression method in our list. */ - temp = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length); - if (temp < 0) { + rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 1, &b, &length); + if (rv != SECSuccess) { goto loser; /* alert has been sent */ } suite_found = PR_FALSE; @@ -7010,6 +7019,19 @@ ssl3_HandleServerHelloPart2(sslSocket *ss, const SECItem *sidBytes, else SSL_AtomicIncrementLong(&ssl3stats.hsh_sid_cache_misses); + /* We tried to resume a 1.3 session but the server negotiated 1.2. */ + if (ss->statelessResume) { + PORT_Assert(sid->version == SSL_LIBRARY_VERSION_TLS_1_3); + PORT_Assert(ss->ssl3.hs.currentSecret); + + /* Reset resumption state, only used by 1.3 code. */ + ss->statelessResume = PR_FALSE; + + /* Clear TLS 1.3 early data traffic key. */ + PK11_FreeSymKey(ss->ssl3.hs.currentSecret); + ss->ssl3.hs.currentSecret = NULL; + } + /* throw the old one away */ sid->u.ssl3.keys.resumable = PR_FALSE; ss->sec.uncache(sid); @@ -7276,16 +7298,17 @@ SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length, PLArenaPool *arena, CERTDistNames *ca_list) { - PRInt32 remaining; + PRUint32 remaining; int nnames = 0; dnameNode *node; + SECStatus rv; int i; - remaining = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); - if (remaining < 0) + rv = ssl3_ConsumeHandshakeNumber(ss, &remaining, 2, b, length); + if (rv != SECSuccess) return SECFailure; /* malformed, alert has been sent */ - if ((PRUint32)remaining > *length) + if (remaining > *length) goto alert_loser; ca_list->head = node = PORT_ArenaZNew(arena, dnameNode); @@ -7293,19 +7316,19 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length, goto no_mem; while (remaining > 0) { - PRInt32 len; + PRUint32 len; if (remaining < 2) goto alert_loser; /* malformed */ - node->name.len = len = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); - if (len <= 0) + rv = ssl3_ConsumeHandshakeNumber(ss, &len, 2, b, length); + if (rv != SECSuccess) return SECFailure; /* malformed, alert has been sent */ - - remaining -= 2; - if (remaining < len) + if (len == 0 || remaining < len + 2) goto alert_loser; /* malformed */ + remaining -= 2; + node->name.len = len; node->name.data = *b; *b += len; *length -= len; @@ -7353,7 +7376,7 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena, { SECStatus rv; SECItem buf; - SSLSignatureScheme *schemes; + SSLSignatureScheme *schemes = NULL; unsigned int numSchemes = 0; unsigned int max; @@ -7361,12 +7384,17 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena, if (rv != SECSuccess) { return SECFailure; } - /* An empty or odd-length value is invalid. */ - if (buf.len == 0 || (buf.len & 1) != 0) { + /* An odd-length value is invalid. */ + if ((buf.len & 1) != 0) { ssl3_ExtSendAlert(ss, alert_fatal, decode_error); return SECFailure; } + /* Let the caller decide whether to alert here. */ + if (buf.len == 0) { + goto done; + } + /* Limit the number of schemes we read. */ max = PR_MIN(buf.len / 2, MAX_SIGNATURE_SCHEMES); @@ -7381,9 +7409,9 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena, } for (; max; --max) { - PRInt32 tmp; - tmp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buf.data, &buf.len); - if (tmp < 0) { + PRUint32 tmp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &tmp, 2, &buf.data, &buf.len); + if (rv != SECSuccess) { PORT_Assert(0); PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; @@ -7400,6 +7428,7 @@ ssl_ParseSignatureSchemes(const sslSocket *ss, PLArenaPool *arena, schemes = NULL; } +done: *schemesOut = schemes; *numSchemesOut = numSchemes; return SECSuccess; @@ -8203,6 +8232,20 @@ ssl3_SelectServerCert(sslSocket *ss) const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def; PRCList *cursor; + /* If the client didn't include the supported groups extension, assume just + * P-256 support and disable all the other ECDHE groups. This also affects + * ECDHE group selection, but this function is called first. */ + if (!ssl3_ExtensionNegotiated(ss, ssl_supported_groups_xtn)) { + unsigned int i; + for (i = 0; i < SSL_NAMED_GROUP_COUNT; ++i) { + if (ss->namedGroupPreferences[i] && + ss->namedGroupPreferences[i]->keaType == ssl_kea_ecdh && + ss->namedGroupPreferences[i]->name != ssl_grp_ec_secp256r1) { + ss->namedGroupPreferences[i] = NULL; + } + } + } + /* This picks the first certificate that has: * a) the right authentication method, and * b) the right named curve (EC only) @@ -8213,19 +8256,17 @@ ssl3_SelectServerCert(sslSocket *ss) cursor != &ss->serverCerts; cursor = PR_NEXT_LINK(cursor)) { sslServerCert *cert = (sslServerCert *)cursor; - if (cert->certType.authType != kea_def->authKeyType) { + if (!SSL_CERT_IS(cert, kea_def->authKeyType)) { continue; } - if ((cert->certType.authType == ssl_auth_ecdsa || - cert->certType.authType == ssl_auth_ecdh_rsa || - cert->certType.authType == ssl_auth_ecdh_ecdsa) && - !ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) { + if (SSL_CERT_IS_EC(cert) && + !ssl_NamedGroupEnabled(ss, cert->namedCurve)) { continue; } /* Found one. */ ss->sec.serverCert = cert; - ss->sec.authType = cert->certType.authType; + ss->sec.authType = kea_def->authKeyType; ss->sec.authKeyBits = cert->serverKeyBits; /* Don't pick a signature scheme if we aren't going to use it. */ @@ -8247,7 +8288,7 @@ static SECStatus ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { sslSessionID *sid = NULL; - PRInt32 tmp; + PRUint32 tmp; unsigned int i; SECStatus rv; int errCode = SSL_ERROR_RX_MALFORMED_CLIENT_HELLO; @@ -8307,8 +8348,8 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) dtls_RehandshakeCleanup(ss); } - tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); - if (tmp < 0) + rv = ssl3_ConsumeHandshakeNumber(ss, &tmp, 2, &b, &length); + if (rv != SECSuccess) goto loser; /* malformed, alert already sent */ /* Translate the version. */ @@ -8361,9 +8402,9 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (length) { /* Get length of hello extensions */ - PRInt32 extension_length; - extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); - if (extension_length < 0) { + PRUint32 extension_length; + rv = ssl3_ConsumeHandshakeNumber(ss, &extension_length, 2, &b, &length); + if (rv != SECSuccess) { goto loser; /* alert already sent */ } if (extension_length != length) { @@ -8465,7 +8506,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) /* 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) { + if (ss->vrange.max > ss->version) { 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) @@ -8749,7 +8790,6 @@ compression_found: do { ssl3CipherSpec *pwSpec; SECItem wrappedMS; /* wrapped key */ - const sslServerCert *serverCert; if (sid->version != ss->version || sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite || @@ -8757,8 +8797,13 @@ compression_found: break; /* not an error */ } - serverCert = ssl_FindServerCert(ss, &sid->certType); - if (!serverCert || !serverCert->serverCert) { + /* server sids don't remember the server cert we previously sent, + ** but they do remember the slot we originally used, so we + ** can locate it again, provided that the current ssl socket + ** has had its server certs configured the same as the previous one. + */ + ss->sec.serverCert = ssl_FindServerCert(ss, sid->authType, sid->namedCurve); + if (!ss->sec.serverCert || !ss->sec.serverCert->serverCert) { /* A compatible certificate must not have been configured. It * might not be the same certificate, but we only find that out * when the ticket fails to decrypt. */ @@ -8806,7 +8851,7 @@ compression_found: PK11SymKey *wrapKey; /* wrapping key */ CK_FLAGS keyFlags = 0; - wrapKey = ssl3_GetWrappingKey(ss, NULL, serverCert, + wrapKey = ssl3_GetWrappingKey(ss, NULL, sid->u.ssl3.masterWrapMech, ss->pkcs11PinArg); if (!wrapKey) { @@ -8865,13 +8910,8 @@ compression_found: ss->sec.keaType = sid->keaType; ss->sec.keaKeyBits = sid->keaKeyBits; - /* server sids don't remember the server cert we previously sent, - ** but they do remember the slot we originally used, so we - ** can locate it again, provided that the current ssl socket - ** has had its server certs configured the same as the previous one. - */ - ss->sec.serverCert = serverCert; - ss->sec.localCert = CERT_DupCertificate(serverCert->serverCert); + ss->sec.localCert = + CERT_DupCertificate(ss->sec.serverCert->serverCert); /* Copy cached name in to pending spec */ if (sid != NULL && @@ -9063,16 +9103,8 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length, goto loser; } - rv = ssl3_InitState(ss); - if (rv != SECSuccess) { - ssl_ReleaseSSL3HandshakeLock(ss); - return rv; /* ssl3_InitState has set the error code. */ - } - rv = ssl3_RestartHandshakeHashes(ss); - if (rv != SECSuccess) { - ssl_ReleaseSSL3HandshakeLock(ss); - return rv; - } + ssl3_InitState(ss); + ssl3_RestartHandshakeHashes(ss); if (ss->ssl3.hs.ws != wait_client_hello) { desc = unexpected_message; @@ -9589,34 +9621,6 @@ ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 return SECSuccess; } -void -ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calen, SECItem **names, - int *nnames) -{ - SECItem *name; - CERTDistNames *ca_list; - int i; - - *calen = 0; - *names = NULL; - *nnames = 0; - - /* ssl3.ca_list is initialized to NULL, and never changed. */ - ca_list = ss->ssl3.ca_list; - if (!ca_list) { - ca_list = ssl3_server_ca_list; - } - - if (ca_list != NULL) { - *names = ca_list->names; - *nnames = ca_list->nnames; - } - - for (i = 0, name = *names; i < *nnames; i++, name++) { - *calen += 2 + name->len; - } -} - static SECStatus ssl3_SendCertificateRequest(sslSocket *ss) { @@ -9625,8 +9629,8 @@ ssl3_SendCertificateRequest(sslSocket *ss) SECStatus rv; int length; SECItem *names; - int calen; - int nnames; + unsigned int calen; + unsigned int nnames; SECItem *name; int i; int certTypesLength; @@ -9641,7 +9645,10 @@ ssl3_SendCertificateRequest(sslSocket *ss) isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2); - ssl3_GetCertificateRequestCAs(ss, &calen, &names, &nnames); + rv = ssl_GetCertificateRequestCAs(ss, &calen, &names, &nnames); + if (rv != SECSuccess) { + return rv; + } certTypes = certificate_types; certTypesLength = sizeof certificate_types; @@ -9727,17 +9734,15 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); - /* TLS 1.3 is handled by tls13_HandleCertificateVerify */ - PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2); - - isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); - if (ss->ssl3.hs.ws != wait_cert_verify) { desc = unexpected_message; errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY; goto alert_loser; } + /* TLS 1.3 is handled by tls13_HandleCertificateVerify */ + PORT_Assert(ss->ssl3.prSpec->version <= SSL_LIBRARY_VERSION_TLS_1_2); + if (!hashes) { PORT_Assert(0); desc = internal_error; @@ -9785,6 +9790,8 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, goto loser; /* malformed. */ } + isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); + /* XXX verify that the key & kea match */ rv = ssl3_VerifySignedHashes(ss, sigScheme, hashesForVerify, &signed_hash); if (rv != SECSuccess) { @@ -9915,9 +9922,9 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss, enc_pms.len = length; if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) { /* isTLS */ - PRInt32 kLen; - kLen = ssl3_ConsumeHandshakeNumber(ss, 2, &enc_pms.data, &enc_pms.len); - if (kLen < 0) { + PRUint32 kLen; + rv = ssl3_ConsumeHandshakeNumber(ss, &kLen, 2, &enc_pms.data, &enc_pms.len); + if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); return SECFailure; } @@ -10214,7 +10221,7 @@ ssl3_SendNewSessionTicket(sslSocket *ss) goto loser; /* This is a fixed value. */ - rv = ssl3_AppendHandshakeNumber(ss, TLS_EX_SESS_TICKET_LIFETIME_HINT, 4); + rv = ssl3_AppendHandshakeNumber(ss, ssl_ticket_lifetime, 4); if (rv != SECSuccess) goto loser; @@ -10237,6 +10244,7 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { SECStatus rv; SECItem ticketData; + PRUint32 temp; SSL_TRC(3, ("%d: SSL3[%d]: handle session_ticket handshake", SSL_GETPID(), ss->fd)); @@ -10257,14 +10265,19 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length) * until it has verified the server's Finished message." See the comment in * ssl3_FinishHandshake for more details. */ - ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_Time(); + ss->ssl3.hs.newSessionTicket.received_timestamp = PR_Now(); if (length < 4) { (void)SSL3_SendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET); return SECFailure; } - ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint = - (PRUint32)ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length); + + rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 4, &b, &length); + if (rv != SECSuccess) { + PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET); + return SECFailure; + } + ss->ssl3.hs.newSessionTicket.ticket_lifetime_hint = temp; rv = ssl3_ConsumeHandshakeVariable(ss, &ticketData, 2, &b, &length); if (rv != SECSuccess || length != 0) { @@ -10559,21 +10572,20 @@ ssl3_HandleCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length) SECStatus ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { - PRInt32 status, len; + PRUint32 status, len; + SECStatus rv; PORT_Assert(!ss->sec.isServer); /* Consume the CertificateStatusType enum */ - status = ssl3_ConsumeHandshakeNumber(ss, 1, &b, &length); - if (status != 1 /* ocsp */) { - ssl3_DecodeError(ss); /* sets error code */ - return SECFailure; + rv = ssl3_ConsumeHandshakeNumber(ss, &status, 1, &b, &length); + if (rv != SECSuccess || status != 1 /* ocsp */) { + return ssl3_DecodeError(ss); } - len = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); - if (len != length) { - ssl3_DecodeError(ss); /* sets error code */ - return SECFailure; + rv = ssl3_ConsumeHandshakeNumber(ss, &len, 3, &b, &length); + if (rv != SECSuccess || len != length) { + return ssl3_DecodeError(ss); } #define MAX_CERTSTATUS_LEN 0x1ffff /* 128k - 1 */ @@ -10630,8 +10642,8 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { ssl3CertNode *c; ssl3CertNode *lastCert = NULL; - PRInt32 remaining = 0; - PRInt32 size; + PRUint32 remaining = 0; + PRUint32 size; SECStatus rv; PRBool isServer = ss->sec.isServer; PRBool isTLS; @@ -10647,10 +10659,10 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ** normal no_certificates message to maximize interoperability. */ if (length) { - remaining = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); - if (remaining < 0) + rv = ssl3_ConsumeHandshakeNumber(ss, &remaining, 3, &b, &length); + if (rv != SECSuccess) goto loser; /* fatal alert already sent by ConsumeHandshake. */ - if ((PRUint32)remaining > length) + if (remaining > length) goto decode_loser; } @@ -10681,15 +10693,14 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } /* First get the peer cert. */ - remaining -= 3; - if (remaining < 0) + if (remaining < 3) goto decode_loser; - size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); - if (size <= 0) + remaining -= 3; + rv = ssl3_ConsumeHandshakeNumber(ss, &size, 3, &b, &length); + if (rv != SECSuccess) goto loser; /* fatal alert already sent by ConsumeHandshake. */ - - if (remaining < size) + if (size == 0 || remaining < size) goto decode_loser; certItem.data = b; @@ -10709,15 +10720,14 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) /* Now get all of the CA certs. */ while (remaining > 0) { - remaining -= 3; - if (remaining < 0) + if (remaining < 3) goto decode_loser; - size = ssl3_ConsumeHandshakeNumber(ss, 3, &b, &length); - if (size <= 0) + remaining -= 3; + rv = ssl3_ConsumeHandshakeNumber(ss, &size, 3, &b, &length); + if (rv != SECSuccess) goto loser; /* fatal alert already sent by ConsumeHandshake. */ - - if (remaining < size) + if (size == 0 || remaining < size) goto decode_loser; certItem.data = b; @@ -10746,9 +10756,6 @@ ssl3_CompleteHandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) lastCert = c; } - if (remaining != 0) - goto decode_loser; - SECKEY_UpdateCertPQG(ss->sec.peerCert); if (!isServer && @@ -11036,13 +11043,10 @@ ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec, PK11Context *prf_context; unsigned int retLen; + PORT_Assert(spec->master_secret); if (!spec->master_secret) { - const char *label = isServer ? "server finished" : "client finished"; - unsigned int len = 15; - HASH_HashType hashType = ssl3_GetTls12HashType(ss); - return ssl3_TLSPRFWithMasterSecret(spec, label, len, hashes->u.raw, - hashes->len, tlsFinished->verify_data, - sizeof tlsFinished->verify_data, hashType); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } if (spec->version < SSL_LIBRARY_VERSION_TLS_1_2) { @@ -11075,9 +11079,10 @@ ssl3_ComputeTLSFinished(sslSocket *ss, ssl3CipherSpec *spec, * ss->ssl3.crSpec). */ SECStatus -ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, - unsigned int labelLen, const unsigned char *val, unsigned int valLen, - unsigned char *out, unsigned int outLen, HASH_HashType tls12HashType) +ssl3_TLSPRFWithMasterSecret(sslSocket *ss, ssl3CipherSpec *spec, + const char *label, unsigned int labelLen, + const unsigned char *val, unsigned int valLen, + unsigned char *out, unsigned int outLen) { SECStatus rv = SECSuccess; @@ -11088,6 +11093,12 @@ ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, const char *label, unsigned int retLen; if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) { + /* Bug 1312976 non-SHA256 exporters are broken. */ + if (ssl3_GetPrfHashMechanism(ss) != CKM_SHA256) { + PORT_Assert(0); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } mech = CKM_NSS_TLS_PRF_GENERAL_SHA256; } prf_context = PK11_CreateContextBySymKey(mech, CKA_SIGN, @@ -11130,9 +11141,7 @@ ssl3_SendNextProto(sslSocket *ss) padding_len = 32 - ((ss->xtnData.nextProto.len + 2) % 32); - rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->xtnData.nextProto.len + - 2 + - padding_len); + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->xtnData.nextProto.len + 2 + padding_len); if (rv != SECSuccess) { return rv; /* error code set by AppendHandshakeHeader */ } @@ -11285,7 +11294,7 @@ fail: */ SECStatus ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid, - ssl3CipherSpec *spec, SSLAuthType authType) + ssl3CipherSpec *spec) { PK11SymKey *wrappingKey = NULL; PK11SlotInfo *symKeySlot; @@ -11339,8 +11348,7 @@ ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid, mechanism = PK11_GetBestWrapMechanism(symKeySlot); if (mechanism != CKM_INVALID_MECHANISM) { wrappingKey = - ssl3_GetWrappingKey(ss, symKeySlot, ss->sec.serverCert, - mechanism, pwArg); + ssl3_GetWrappingKey(ss, symKeySlot, mechanism, pwArg); if (wrappingKey) { mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */ } @@ -11547,9 +11555,7 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid) sid->expirationTime = sid->creationTime + ssl3_sid_timeout; sid->localCert = CERT_DupCertificate(ss->sec.localCert); if (ss->sec.isServer) { - memcpy(&sid->certType, &ss->sec.serverCert->certType, sizeof(sid->certType)); - } else { - sid->certType.authType = ssl_auth_null; + sid->namedCurve = ss->sec.serverCert->namedCurve; } if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && @@ -11573,8 +11579,7 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid) rv = SECSuccess; } else { rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid, - ss->ssl3.crSpec, - ss->ssl3.hs.kea_def->authKeyType); + ss->ssl3.crSpec); sid->u.ssl3.keys.msIsWrapped = PR_TRUE; } ssl_ReleaseSpecReadLock(ss); /*************************************/ @@ -11719,10 +11724,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length, /* Start new handshake hashes when we start a new handshake. Unless this is * TLS 1.3 and we sent a HelloRetryRequest. */ if (ss->ssl3.hs.msg_type == client_hello && !ss->ssl3.hs.helloRetry) { - rv = ssl3_RestartHandshakeHashes(ss); - if (rv != SECSuccess) { - return rv; - } + ssl3_RestartHandshakeHashes(ss); } /* We should not include hello_request and hello_verify_request messages * in the handshake hashes */ @@ -12508,17 +12510,14 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) ssl3CipherSpec *crSpec; SSL3ContentType rType; sslBuffer *plaintext; - sslBuffer temp_buf; + sslBuffer temp_buf = { NULL, 0, 0 }; SSL3AlertDescription alert = internal_error; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); if (!ss->ssl3.initialized) { ssl_GetSSL3HandshakeLock(ss); - rv = ssl3_InitState(ss); + ssl3_InitState(ss); ssl_ReleaseSSL3HandshakeLock(ss); - if (rv != SECSuccess) { - return rv; /* ssl3_InitState has set the error code. */ - } } /* check for Token Presence */ @@ -12565,25 +12564,11 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) /* If we will be decompressing the buffer we need to decrypt somewhere * other than into databuf */ if (crSpec->decompressor) { - temp_buf.buf = NULL; - temp_buf.space = 0; plaintext = &temp_buf; } else { plaintext = databuf; } - plaintext->len = 0; /* filled in by Unprotect call below. */ - if (plaintext->space < MAX_FRAGMENT_LENGTH) { - rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH + 2048); - if (rv != SECSuccess) { - ssl_ReleaseSpecReadLock(ss); /*************************/ - SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes", - SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048)); - /* sslBuffer_Grow has set a memory error code. */ - /* Perhaps we should send an alert. (but we have no memory!) */ - return SECFailure; - } - } /* We're waiting for another ClientHello, which will appear unencrypted. * Use the content type to tell whether this is should be discarded. @@ -12598,6 +12583,18 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) return SECSuccess; } + if (plaintext->space < MAX_FRAGMENT_LENGTH) { + rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH + 2048); + if (rv != SECSuccess) { + ssl_ReleaseSpecReadLock(ss); /*************************/ + SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes", + SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048)); + /* sslBuffer_Grow has set a memory error code. */ + /* Perhaps we should send an alert. (but we have no memory!) */ + return SECFailure; + } + } + #ifdef UNSAFE_FUZZER_MODE rv = Null_Cipher(NULL, plaintext->buf, (int *)&plaintext->len, plaintext->space, cText->buf->buf, cText->buf->len); @@ -12619,6 +12616,9 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd)); + /* Clear the temp buffer used for decompression upon failure. */ + sslBuffer_Clear(&temp_buf); + if (IS_DTLS(ss) || (ss->sec.isServer && ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_trial)) { @@ -12663,7 +12663,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) SSL3_COMPRESSION_MAX_EXPANSION)); /* sslBuffer_Grow has set a memory error code. */ /* Perhaps we should send an alert. (but we have no memory!) */ - PORT_Free(plaintext->buf); + sslBuffer_Clear(&temp_buf); return SECFailure; } } @@ -12701,12 +12701,12 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) } } - PORT_Free(plaintext->buf); + sslBuffer_Clear(&temp_buf); PORT_SetError(err); return SECFailure; } - PORT_Free(plaintext->buf); + sslBuffer_Clear(&temp_buf); } /* @@ -12836,16 +12836,14 @@ ssl3_InitCipherSpec(ssl3CipherSpec *spec) ** ssl3_HandleRecord() ** ** This function should perhaps acquire and release the SpecWriteLock. -** -** */ -SECStatus +void ssl3_InitState(sslSocket *ss) { PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); if (ss->ssl3.initialized) - return SECSuccess; /* Function should be idempotent */ + return; /* Function should be idempotent */ ss->ssl3.policy = SSL_ALLOWED; @@ -12900,7 +12898,6 @@ ssl3_InitState(sslSocket *ss) ssl_FilterSupportedGroups(ss); ss->ssl3.initialized = PR_TRUE; - return SECSuccess; } /* record the export policy for this cipher suite */ @@ -13280,8 +13277,6 @@ ssl3_DestroySSL3Info(sslSocket *ss) tls13_DestroyEarlyData(&ss->ssl3.hs.bufferedEarlyData); ss->ssl3.initialized = PR_FALSE; - - SECITEM_FreeItem(&ss->xtnData.nextProto, PR_FALSE); } #define MAP_NULL(x) (((x) != 0) ? (x) : SEC_OID_NULL_CIPHER) diff --git a/nss/lib/ssl/ssl3ecc.c b/nss/lib/ssl/ssl3ecc.c index 72c4ba5..2b2a611 100644 --- a/nss/lib/ssl/ssl3ecc.c +++ b/nss/lib/ssl/ssl3ecc.c @@ -31,13 +31,6 @@ #include <stdio.h> -#ifndef PK11_SETATTRS -#define PK11_SETATTRS(x, id, v, l) \ - (x)->type = (id); \ - (x)->pValue = (v); \ - (x)->ulValueLen = (l); -#endif - SECStatus ssl_NamedGroup2ECParams(PLArenaPool *arena, const sslNamedGroupDef *ecGroup, SECKEYECParams *params) @@ -257,16 +250,6 @@ loser: return SECFailure; } -/* This function returns the size of the key_exchange field in - * the KeyShareEntry structure, i.e.: - * opaque point <1..2^8-1>; */ -unsigned int -tls13_SizeOfECDHEKeyShareKEX(const SECKEYPublicKey *pubKey) -{ - PORT_Assert(pubKey->keyType == ecKey); - return pubKey->u.ec.publicValue.len; -} - /* This function encodes the key_exchange field in * the KeyShareEntry structure. */ SECStatus @@ -303,7 +286,7 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, serverKeyPair->pubKey->u.ec.DEREncodedParams.len; clntPubKey.u.ec.DEREncodedParams.data = serverKeyPair->pubKey->u.ec.DEREncodedParams.data; - clntPubKey.u.ec.encoding = serverKeyPair->pubKey->u.ec.encoding; + clntPubKey.u.ec.encoding = ECPoint_Undefined; rv = ssl3_ConsumeHandshakeVariable(ss, &clntPubKey.u.ec.publicValue, 1, &b, &length); @@ -387,11 +370,7 @@ ssl_ImportECDHKeyShare(sslSocket *ss, SECKEYPublicKey *peerKey, ssl_MapLowLevelError(SSL_ERROR_RX_MALFORMED_ECDHE_KEY_SHARE); return SECFailure; } - if (ecGroup->name == ssl_grp_ec_curve25519) { - peerKey->u.ec.encoding = ECPoint_XOnly; - } else { - peerKey->u.ec.encoding = ECPoint_Uncompressed; - } + peerKey->u.ec.encoding = ECPoint_Undefined; /* copy publicValue in peerKey */ ecPoint.data = b; @@ -440,23 +419,19 @@ ssl_GetECGroupForServerSocket(sslSocket *ss) return NULL; } - if (cert->certType.authType == ssl_auth_rsa_sign) { + if (SSL_CERT_IS(cert, ssl_auth_rsa_sign) || + SSL_CERT_IS(cert, ssl_auth_rsa_pss)) { certKeySize = SECKEY_PublicKeyStrengthInBits(cert->serverKeyPair->pubKey); - certKeySize = - SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize); - } else if (cert->certType.authType == ssl_auth_ecdsa || - cert->certType.authType == ssl_auth_ecdh_rsa || - cert->certType.authType == ssl_auth_ecdh_ecdsa) { - const sslNamedGroupDef *groupDef = cert->certType.namedCurve; - + certKeySize = SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize); + } else if (SSL_CERT_IS_EC(cert)) { /* We won't select a certificate unless the named curve has been * negotiated (or supported_curves was absent), double check that. */ - PORT_Assert(groupDef->keaType == ssl_kea_ecdh); - PORT_Assert(ssl_NamedGroupEnabled(ss, groupDef)); - if (!ssl_NamedGroupEnabled(ss, groupDef)) { + PORT_Assert(cert->namedCurve->keaType == ssl_kea_ecdh); + PORT_Assert(ssl_NamedGroupEnabled(ss, cert->namedCurve)); + if (!ssl_NamedGroupEnabled(ss, cert->namedCurve)) { return NULL; } - certKeySize = groupDef->bits; + certKeySize = cert->namedCurve->bits; } else { PORT_Assert(0); return NULL; diff --git a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c index 0da41be..7700be2 100644 --- a/nss/lib/ssl/ssl3ext.c +++ b/nss/lib/ssl/ssl3ext.c @@ -87,6 +87,10 @@ static const ssl3ExtensionHandler serverCertificateHandlers[] = { { -1, NULL } }; +static const ssl3ExtensionHandler certificateRequestHandlers[] = { + { -1, NULL } +}; + /* Tables of functions to format TLS hello extensions, one function per * extension. * These static tables are for the formatting of client hello extensions. @@ -122,6 +126,7 @@ static const ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] { ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn }, { ssl_tls13_psk_key_exchange_modes_xtn, &tls13_ClientSendPskKeyExchangeModesXtn }, + { ssl_padding_xtn, &ssl3_ClientSendPaddingExtension }, /* The pre_shared_key extension MUST be last. */ { ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn }, /* any extra entries will appear as { 0, NULL } */ @@ -174,15 +179,15 @@ ssl3_ParseExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length) while (*length) { SECStatus rv; - PRInt32 extension_type; + PRUint32 extension_type; SECItem extension_data = { siBuffer, NULL, 0 }; TLSExtension *extension; PRCList *cursor; /* Get the extension's type field */ - extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); - if (extension_type < 0) { /* failure to decode extension_type */ - return SECFailure; /* alert already sent */ + rv = ssl3_ConsumeHandshakeNumber(ss, &extension_type, 2, b, length); + if (rv != SECSuccess) { + return SECFailure; /* alert already sent */ } SSL_TRC(10, ("%d: SSL3[%d]: parsing extension %d", @@ -249,7 +254,10 @@ ssl3_HandleParsedExtensions(sslSocket *ss, SSL3HandshakeType handshakeMessage) { const ssl3ExtensionHandler *handlers; - PRBool isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3; + /* HelloRetryRequest doesn't set ss->version. It might be safe to + * do so, but we weren't entirely sure. TODO(ekr@rtfm.com). */ + PRBool isTLS13 = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) || + (handshakeMessage == hello_retry_request); PRCList *cursor; switch (handshakeMessage) { @@ -277,6 +285,10 @@ ssl3_HandleParsedExtensions(sslSocket *ss, PORT_Assert(!ss->sec.isServer); handlers = serverCertificateHandlers; break; + case certificate_request: + PORT_Assert(!ss->sec.isServer); + handlers = certificateRequestHandlers; + break; default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); PORT_Assert(0); @@ -508,22 +520,22 @@ ssl3_ExtDecodeError(const sslSocket *ss) } SECStatus -ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRInt32 bytes, +ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRUint32 bytes, SSL3Opaque **b, PRUint32 *length) { return ssl3_ConsumeHandshake((sslSocket *)ss, v, bytes, b, length); } -PRInt32 -ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRInt32 bytes, - SSL3Opaque **b, PRUint32 *length) +SECStatus +ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRUint32 *num, + PRUint32 bytes, SSL3Opaque **b, PRUint32 *length) { - return ssl3_ConsumeHandshakeNumber((sslSocket *)ss, bytes, b, length); + return ssl3_ConsumeHandshakeNumber((sslSocket *)ss, num, bytes, b, length); } SECStatus ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i, - PRInt32 bytes, SSL3Opaque **b, + PRUint32 bytes, SSL3Opaque **b, PRUint32 *length) { return ssl3_ConsumeHandshakeVariable((sslSocket *)ss, i, bytes, b, length); diff --git a/nss/lib/ssl/ssl3ext.h b/nss/lib/ssl/ssl3ext.h index f93ad65..0aff523 100644 --- a/nss/lib/ssl/ssl3ext.h +++ b/nss/lib/ssl/ssl3ext.h @@ -54,6 +54,9 @@ struct TLSExtensionDataStr { PRUint16 advertised[SSL_MAX_EXTENSIONS]; PRUint16 negotiated[SSL_MAX_EXTENSIONS]; + /* Amount of padding we need to add. */ + PRUint16 paddingLen; + /* SessionTicket Extension related data. */ PRBool ticketTimestampVerified; PRBool emptySessionTicket; @@ -130,9 +133,8 @@ SECStatus ssl3_RegisterExtensionSender(const sslSocket *ss, PRInt32 ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, const ssl3HelloExtensionSender *sender); -unsigned int ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength); -PRInt32 ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, - PRUint32 maxBytes); +void ssl3_CalculatePaddingExtLen(sslSocket *ss, + unsigned int clientHelloLength); /* Thunks to let us operate on const sslSocket* objects. */ SECStatus ssl3_ExtAppendHandshake(const sslSocket *ss, const void *void_src, @@ -145,12 +147,13 @@ SECStatus ssl3_ExtAppendHandshakeVariable(const sslSocket *ss, void ssl3_ExtSendAlert(const sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc); void ssl3_ExtDecodeError(const sslSocket *ss); -SECStatus ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRInt32 bytes, +SECStatus ssl3_ExtConsumeHandshake(const sslSocket *ss, void *v, PRUint32 bytes, SSL3Opaque **b, PRUint32 *length); -PRInt32 ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRInt32 bytes, - SSL3Opaque **b, PRUint32 *length); +SECStatus ssl3_ExtConsumeHandshakeNumber(const sslSocket *ss, PRUint32 *num, + PRUint32 bytes, SSL3Opaque **b, + PRUint32 *length); SECStatus ssl3_ExtConsumeHandshakeVariable(const sslSocket *ss, SECItem *i, - PRInt32 bytes, SSL3Opaque **b, + PRUint32 bytes, SSL3Opaque **b, PRUint32 *length); #endif diff --git a/nss/lib/ssl/ssl3exthandle.c b/nss/lib/ssl/ssl3exthandle.c index 2a80e26..c9c99ab 100644 --- a/nss/lib/ssl/ssl3exthandle.c +++ b/nss/lib/ssl/ssl3exthandle.c @@ -16,22 +16,16 @@ #include "ssl3exthandle.h" #include "tls13exthandle.h" /* For tls13_ServerSendStatusRequestXtn. */ -static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; -static PK11SymKey *session_ticket_enc_key = NULL; -static PK11SymKey *session_ticket_mac_key = NULL; - -static PRCallOnceType generate_session_keys_once; - -static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss, - SECItem *data, EncryptedSessionTicket *enc_session_ticket); static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes); -static SECStatus ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes); +static SECStatus ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, + PRUint32 bytes); static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize); -static SECStatus ssl3_GetSessionTicketKeys(sslSocket *ss, - PK11SymKey **aes_key, PK11SymKey **mac_key); -static SECStatus ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes); + +PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; /* 2 days in seconds */ +#define TLS_EX_SESS_TICKET_VERSION (0x0105) +#define TLS_EX_SESS_TICKET_MAC_LENGTH 32 /* * Write bytes. Using this function means the SECItem structure @@ -76,83 +70,6 @@ ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize) return rv; } -SECStatus -ssl3_SessionTicketShutdown(void *appData, void *nssData) -{ - if (session_ticket_enc_key) { - PK11_FreeSymKey(session_ticket_enc_key); - session_ticket_enc_key = NULL; - } - if (session_ticket_mac_key) { - PK11_FreeSymKey(session_ticket_mac_key); - session_ticket_mac_key = NULL; - } - PORT_Memset(&generate_session_keys_once, 0, - sizeof(generate_session_keys_once)); - return SECSuccess; -} - -static PRStatus -ssl3_GenerateSessionTicketKeys(void *data) -{ - SECStatus rv; - sslSocket *ss = (sslSocket *)data; - sslServerCertType certType = { ssl_auth_rsa_decrypt, NULL }; - const sslServerCert *sc; - SECKEYPrivateKey *svrPrivKey; - SECKEYPublicKey *svrPubKey; - - sc = ssl_FindServerCert(ss, &certType); - if (!sc || !sc->serverKeyPair) { - SSL_DBG(("%d: SSL[%d]: No ssl_auth_rsa_decrypt cert and key pair", - SSL_GETPID(), ss->fd)); - goto loser; - } - svrPrivKey = sc->serverKeyPair->privKey; - svrPubKey = sc->serverKeyPair->pubKey; - if (svrPrivKey == NULL || svrPubKey == NULL) { - SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.", - SSL_GETPID(), ss->fd)); - goto loser; - } - - /* Get a copy of the session keys from shared memory. */ - PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX, - sizeof(SESS_TICKET_KEY_NAME_PREFIX)); - if (!ssl_GetSessionTicketKeys(svrPrivKey, svrPubKey, ss->pkcs11PinArg, - &key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN], - &session_ticket_enc_key, &session_ticket_mac_key)) - return PR_FAILURE; - - rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL); - if (rv != SECSuccess) - goto loser; - - return PR_SUCCESS; - -loser: - ssl3_SessionTicketShutdown(NULL, NULL); - return PR_FAILURE; -} - -static SECStatus -ssl3_GetSessionTicketKeys(sslSocket *ss, PK11SymKey **aes_key, - PK11SymKey **mac_key) -{ - if (PR_CallOnceWithArg(&generate_session_keys_once, - ssl3_GenerateSessionTicketKeys, ss) != - PR_SUCCESS) - return SECFailure; - - if (session_ticket_enc_key == NULL || - session_ticket_mac_key == NULL) - return SECFailure; - - *aes_key = session_ticket_enc_key; - *mac_key = session_ticket_mac_key; - return SECSuccess; -} - /* Format an SNI extension, using the name from the socket's URL, * unless that name is a dotted decimal string. * Used by client and server. @@ -223,7 +140,8 @@ SECStatus ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECItem *names = NULL; - PRInt32 listLenBytes = 0; + PRUint32 listLenBytes = 0; + SECStatus rv; if (!ss->sec.isServer) { return SECSuccess; /* ignore extension */ @@ -236,8 +154,8 @@ ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint1 } /* length of server_name_list */ - listLenBytes = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (listLenBytes < 0) { + rv = ssl3_ExtConsumeHandshakeNumber(ss, &listLenBytes, 2, &data->data, &data->len); + if (rv != SECSuccess) { goto loser; /* alert already sent */ } if (listLenBytes == 0 || listLenBytes != data->len) { @@ -247,12 +165,11 @@ ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint1 /* Read ServerNameList. */ while (data->len > 0) { SECItem tmp; - SECStatus rv; - PRInt32 type; + PRUint32 type; /* Read Name Type. */ - type = ssl3_ExtConsumeHandshakeNumber(ss, 1, &data->data, &data->len); - if (type < 0) { /* i.e., SECFailure cast to PRint32 */ + rv = ssl3_ExtConsumeHandshakeNumber(ss, &type, 1, &data->data, &data->len); + if (rv != SECSuccess) { /* alert sent in ConsumeHandshakeNumber */ goto loser; } @@ -372,11 +289,7 @@ ssl3_SendSessionTicketXtn( if (session_ticket->ticket.data) { if (xtnData->ticketTimestampVerified) { extension_length += session_ticket->ticket.len; - } else if (!append && - (session_ticket->ticket_lifetime_hint == 0 || - (session_ticket->ticket_lifetime_hint + - session_ticket->received_timestamp > - ssl_Time()))) { + } else if (!append && ssl_TicketTimeValid(session_ticket)) { extension_length += session_ticket->ticket.len; xtnData->ticketTimestampVerified = PR_TRUE; } @@ -418,31 +331,54 @@ loser: } static SECStatus -ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data, - EncryptedSessionTicket *enc_session_ticket) +ssl3_ParseEncryptedSessionTicket(sslSocket *ss, const SECItem *data, + EncryptedSessionTicket *encryptedTicket) { - if (ssl3_ConsumeFromItem(data, &enc_session_ticket->key_name, + SECItem copy = *data; + + if (ssl3_ConsumeFromItem(©, &encryptedTicket->key_name, SESS_TICKET_KEY_NAME_LEN) != SECSuccess) return SECFailure; - if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv, + if (ssl3_ConsumeFromItem(©, &encryptedTicket->iv, AES_BLOCK_SIZE) != SECSuccess) return SECFailure; - if (ssl3_ConsumeHandshakeVariable(ss, &enc_session_ticket->encrypted_state, - 2, &data->data, &data->len) != + if (ssl3_ConsumeHandshakeVariable(ss, &encryptedTicket->encrypted_state, + 2, ©.data, ©.len) != SECSuccess) return SECFailure; - if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac, + if (ssl3_ConsumeFromItem(©, &encryptedTicket->mac, TLS_EX_SESS_TICKET_MAC_LENGTH) != SECSuccess) return SECFailure; - if (data->len != 0) /* Make sure that we have consumed all bytes. */ + if (copy.len != 0) /* Make sure that we have consumed all bytes. */ return SECFailure; return SECSuccess; } +PRBool +ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag) +{ + const unsigned char *data = ss->opt.nextProtoNego.data; + unsigned int length = ss->opt.nextProtoNego.len; + unsigned int offset = 0; + + if (!tag->len) + return PR_TRUE; + + while (offset < length) { + unsigned int taglen = (unsigned int)data[offset]; + if ((taglen == tag->len) && + !PORT_Memcmp(data + offset + 1, tag->data, tag->len)) + return PR_TRUE; + offset += 1 + taglen; + } + + return PR_FALSE; +} + /* handle an incoming Next Protocol Negotiation extension. */ SECStatus ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, @@ -542,7 +478,7 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData, SECStatus ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { - int count; + PRUint32 count; SECStatus rv; /* We expressly don't want to allow ALPN on renegotiation, @@ -556,8 +492,8 @@ ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRU /* Unlike NPN, ALPN has extra redundant length information so that * the extension is the same in both ClientHello and ServerHello. */ - count = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (count != data->len) { + rv = ssl3_ExtConsumeHandshakeNumber(ss, &count, 2, &data->data, &data->len); + if (rv != SECSuccess || count != data->len) { ssl3_ExtDecodeError(ss); return SECFailure; } @@ -621,7 +557,7 @@ SECStatus ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; - PRInt32 list_len; + PRUint32 list_len; SECItem protocol_name; if (ssl3_ExtensionNegotiated(ss, ssl_next_proto_nego_xtn)) { @@ -639,9 +575,10 @@ ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRU return SECFailure; } - list_len = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + rv = ssl3_ExtConsumeHandshakeNumber(ss, &list_len, 2, &data->data, + &data->len); /* The list has to be the entire extension. */ - if (list_len != data->len) { + if (rv != SECSuccess || list_len != data->len) { ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); return SECFailure; @@ -656,6 +593,12 @@ ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRU return SECFailure; } + if (!ssl_AlpnTagAllowed(ss, &protocol_name)) { + ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter); + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); + return SECFailure; + } + SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE); xtnData->nextProtoState = SSL_NEXT_PROTO_SELECTED; xtnData->negotiated[xtnData->numNegotiated++] = ex_type; @@ -963,23 +906,20 @@ ssl3_EncodeSessionTicket(sslSocket *ss, PRUint32 cert_length = 0; PRUint8 length_buf[4]; PRUint32 now; + unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; PK11SymKey *aes_key = NULL; PK11SymKey *mac_key = NULL; - CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC; PK11Context *aes_ctx; - CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC; PK11Context *hmac_ctx = NULL; unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; unsigned int computed_mac_length; unsigned char iv[AES_BLOCK_SIZE]; SECItem ivItem; SECItem *srvName = NULL; - PRUint32 srvNameLen = 0; CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value, * must be >= 0 */ ssl3CipherSpec *spec; - const sslServerCertType *certType; - SECItem alpnSelection = { siBuffer, NULL, 0 }; + SECItem *alpnSelection = NULL; SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake", SSL_GETPID(), ss->fd)); @@ -988,7 +928,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) { - cert_length = 3 + ss->sec.ci.sid->peerCert->derCert.len; + cert_length = 2 + ss->sec.ci.sid->peerCert->derCert.len; } /* Get IV and encryption keys */ @@ -998,7 +938,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, if (rv != SECSuccess) goto loser; - rv = ssl3_GetSessionTicketKeys(ss, &aes_key, &mac_key); + rv = ssl_GetSessionTicketKeys(ss, key_name, &aes_key, &mac_key); if (rv != SECSuccess) goto loser; @@ -1017,8 +957,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, sslSessionID sid; PORT_Memset(&sid, 0, sizeof(sslSessionID)); - rv = ssl3_CacheWrappedMasterSecret(ss, &sid, spec, - ss->ssl3.hs.kea_def->authKeyType); + rv = ssl3_CacheWrappedMasterSecret(ss, &sid, spec); if (rv == SECSuccess) { if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms)) goto loser; @@ -1035,17 +974,14 @@ ssl3_EncodeSessionTicket(sslSocket *ss, } /* Prep to send negotiated name */ srvName = &ss->sec.ci.sid->u.ssl3.srvName; - if (srvName->data && srvName->len) { - srvNameLen = 2 + srvName->len; /* len bytes + name len */ - } - if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && - ss->xtnData.nextProto.data) { - alpnSelection = ss->xtnData.nextProto; - } + PORT_Assert(ss->xtnData.nextProtoState == SSL_NEXT_PROTO_SELECTED || + ss->xtnData.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED || + ss->xtnData.nextProto.len == 0); + alpnSelection = &ss->xtnData.nextProto; ciphertext_length = - sizeof(PRUint16) /* ticket_version */ + sizeof(PRUint16) /* ticket version */ + sizeof(SSL3ProtocolVersion) /* ssl_version */ + sizeof(ssl3CipherSuite) /* ciphersuite */ + 1 /* compression */ @@ -1057,15 +993,19 @@ ssl3_EncodeSessionTicket(sslSocket *ss, + ms_item.len /* master_secret */ + 1 /* client_auth_type */ + cert_length /* cert */ - + 1 /* server name type */ - + srvNameLen /* name len + length field */ + + 2 + srvName->len /* name len + length field */ + 1 /* extendedMasterSecretUsed */ + sizeof(ticket->ticket_lifetime_hint) /* ticket lifetime hint */ + sizeof(ticket->flags) /* ticket flags */ - + 1 + alpnSelection.len; /* npn value + length field. */ + + 1 + alpnSelection->len /* alpn value + length field */ + + 4; /* maxEarlyData */ +#ifdef UNSAFE_FUZZER_MODE + padding_length = 0; +#else padding_length = AES_BLOCK_SIZE - (ciphertext_length % AES_BLOCK_SIZE); +#endif ciphertext_length += padding_length; if (SECITEM_AllocItem(NULL, &plaintext_item, ciphertext_length) == NULL) @@ -1073,7 +1013,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, plaintext = plaintext_item; - /* ticket_version */ + /* ticket version */ rv = ssl3_AppendNumberToItem(&plaintext, TLS_EX_SESS_TICKET_VERSION, sizeof(PRUint16)); if (rv != SECSuccess) @@ -1111,22 +1051,15 @@ ssl3_EncodeSessionTicket(sslSocket *ss, goto loser; /* certificate type */ - certType = &ss->sec.serverCert->certType; - PORT_Assert(certType->authType == ss->sec.authType); - switch (ss->sec.authType) { - case ssl_auth_ecdsa: - case ssl_auth_ecdh_rsa: - case ssl_auth_ecdh_ecdsa: - PORT_Assert(certType->namedCurve); - PORT_Assert(certType->namedCurve->keaType == ssl_kea_ecdh); - /* EC curves only use the second of the two bytes. */ - PORT_Assert(certType->namedCurve->name < 256); - rv = ssl3_AppendNumberToItem(&plaintext, - certType->namedCurve->name, 1); - break; - default: - rv = ssl3_AppendNumberToItem(&plaintext, 0, 1); - break; + PORT_Assert(SSL_CERT_IS(ss->sec.serverCert, ss->sec.authType)); + if (SSL_CERT_IS_EC(ss->sec.serverCert)) { + const sslServerCert *cert = ss->sec.serverCert; + PORT_Assert(cert->namedCurve); + /* EC curves only use the second of the two bytes. */ + PORT_Assert(cert->namedCurve->name < 256); + rv = ssl3_AppendNumberToItem(&plaintext, cert->namedCurve->name, 1); + } else { + rv = ssl3_AppendNumberToItem(&plaintext, 0, 1); } if (rv != SECSuccess) goto loser; @@ -1145,13 +1078,13 @@ ssl3_EncodeSessionTicket(sslSocket *ss, if (rv != SECSuccess) goto loser; - /* client_identity */ + /* client identity */ if (ss->opt.requestCertificate && ss->sec.ci.sid->peerCert) { rv = ssl3_AppendNumberToItem(&plaintext, CLIENT_AUTH_CERTIFICATE, 1); if (rv != SECSuccess) goto loser; rv = ssl3_AppendNumberToItem(&plaintext, - ss->sec.ci.sid->peerCert->derCert.len, 3); + ss->sec.ci.sid->peerCert->derCert.len, 2); if (rv != SECSuccess) goto loser; rv = ssl3_AppendToItem(&plaintext, @@ -1172,23 +1105,14 @@ ssl3_EncodeSessionTicket(sslSocket *ss, if (rv != SECSuccess) goto loser; - if (srvNameLen) { - /* Name Type (sni_host_name) */ - rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1); - if (rv != SECSuccess) - goto loser; - /* HostName (length and value) */ - rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2); - if (rv != SECSuccess) - goto loser; + /* HostName (length and value) */ + rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2); + if (rv != SECSuccess) + goto loser; + if (srvName->len) { rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len); if (rv != SECSuccess) goto loser; - } else { - /* No Name */ - rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME, 1); - if (rv != SECSuccess) - goto loser; } /* extendedMasterSecretUsed */ @@ -1203,17 +1127,22 @@ ssl3_EncodeSessionTicket(sslSocket *ss, if (rv != SECSuccess) goto loser; - /* NPN value. */ - PORT_Assert(alpnSelection.len < 256); - rv = ssl3_AppendNumberToItem(&plaintext, alpnSelection.len, 1); + /* ALPN value. */ + PORT_Assert(alpnSelection->len < 256); + rv = ssl3_AppendNumberToItem(&plaintext, alpnSelection->len, 1); if (rv != SECSuccess) goto loser; - if (alpnSelection.len) { - rv = ssl3_AppendToItem(&plaintext, alpnSelection.data, alpnSelection.len); + if (alpnSelection->len) { + rv = ssl3_AppendToItem(&plaintext, alpnSelection->data, + alpnSelection->len); if (rv != SECSuccess) goto loser; } + rv = ssl3_AppendNumberToItem(&plaintext, ssl_max_early_data_size, 4); + if (rv != SECSuccess) + goto loser; + PORT_Assert(plaintext.len == padding_length); for (i = 0; i < padding_length; i++) plaintext.data[i] = (unsigned char)padding_length; @@ -1225,7 +1154,11 @@ ssl3_EncodeSessionTicket(sslSocket *ss, /* Generate encrypted portion of ticket. */ PORT_Assert(aes_key); - aes_ctx = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT, aes_key, &ivItem); +#ifdef UNSAFE_FUZZER_MODE + ciphertext.len = plaintext_item.len; + PORT_Memcpy(ciphertext.data, plaintext_item.data, plaintext_item.len); +#else + aes_ctx = PK11_CreateContextBySymKey(CKM_AES_CBC, CKA_ENCRYPT, aes_key, &ivItem); if (!aes_ctx) goto loser; @@ -1236,14 +1169,15 @@ ssl3_EncodeSessionTicket(sslSocket *ss, PK11_DestroyContext(aes_ctx, PR_TRUE); if (rv != SECSuccess) goto loser; +#endif /* Convert ciphertext length to network order. */ - length_buf[0] = (ciphertext.len >> 8) & 0xff; - length_buf[1] = (ciphertext.len) & 0xff; + (void)ssl_EncodeUintX(ciphertext.len, 2, length_buf); /* Compute MAC. */ PORT_Assert(mac_key); - hmac_ctx = PK11_CreateContextBySymKey(macMech, CKA_SIGN, mac_key, &macParam); + hmac_ctx = PK11_CreateContextBySymKey(CKM_SHA256_HMAC, CKA_SIGN, mac_key, + &macParam); if (!hmac_ctx) goto loser; @@ -1338,434 +1272,525 @@ ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData return SECSuccess; } -/* Generic ticket processing code, common to TLS 1.0-1.2 and - * TLS 1.3. */ -SECStatus -ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) +static SECStatus +ssl_DecryptSessionTicket(sslSocket *ss, const SECItem *rawTicket, + const EncryptedSessionTicket *encryptedTicket, + SECItem *decryptedTicket) { SECStatus rv; - SECItem *decrypted_state = NULL; - SessionTicket *parsed_session_ticket = NULL; - sslSessionID *sid = NULL; - SSL3Statistics *ssl3stats; - PRUint32 i; - SECItem extension_data; - EncryptedSessionTicket enc_session_ticket; - unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH]; - unsigned int computed_mac_length; - PK11SymKey *aes_key = NULL; - PK11SymKey *mac_key = NULL; - PK11Context *hmac_ctx; - CK_MECHANISM_TYPE macMech = CKM_SHA256_HMAC; - PK11Context *aes_ctx; - CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC; - unsigned char *padding; - PRUint32 padding_length; - unsigned char *buffer; - unsigned int buffer_len; - PRInt32 temp; - SECItem cert_item; - PRInt8 nameType = TLS_STE_NO_SERVER_NAME; + unsigned char keyName[SESS_TICKET_KEY_NAME_LEN]; + + PK11SymKey *macKey = NULL; + PK11Context *hmacCtx; + unsigned char computedMac[TLS_EX_SESS_TICKET_MAC_LENGTH]; + unsigned int computedMacLength; SECItem macParam = { siBuffer, NULL, 0 }; - SECItem alpn_item; - SECItem ivItem; - /* Turn off stateless session resumption if the client sends a - * SessionTicket extension, even if the extension turns out to be - * malformed (ss->sec.ci.sid is non-NULL when doing session - * renegotiation.) - */ - if (ss->sec.ci.sid != NULL) { - ss->sec.uncache(ss->sec.ci.sid); - ssl_FreeSID(ss->sec.ci.sid); - ss->sec.ci.sid = NULL; - } + PK11SymKey *aesKey = NULL; +#ifndef UNSAFE_FUZZER_MODE + PK11Context *aesCtx; + SECItem ivItem; - extension_data.data = data->data; /* Keep a copy for future use. */ - extension_data.len = data->len; + unsigned int i; + SSL3Opaque *padding; + SSL3Opaque paddingLength; +#endif - if (ssl3_ParseEncryptedSessionTicket(ss, data, &enc_session_ticket) != - SECSuccess) { - return SECSuccess; /* Pretend it isn't there */ + PORT_Assert(!decryptedTicket->data); + PORT_Assert(!decryptedTicket->len); + if (rawTicket->len < TLS_EX_SESS_TICKET_MAC_LENGTH) { + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; } /* Get session ticket keys. */ - rv = ssl3_GetSessionTicketKeys(ss, &aes_key, &mac_key); + rv = ssl_GetSessionTicketKeys(ss, keyName, &aesKey, &macKey); if (rv != SECSuccess) { SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.", SSL_GETPID(), ss->fd)); - goto loser; + return SECFailure; /* code already set */ } - /* If the ticket sent by the client was generated under a key different - * from the one we have, bypass ticket processing. + /* If the ticket sent by the client was generated under a key different from + * the one we have, bypass ticket processing. This reports success, meaning + * that the handshake completes, but doesn't resume. */ - if (PORT_Memcmp(enc_session_ticket.key_name, key_name, + if (PORT_Memcmp(encryptedTicket->key_name, keyName, SESS_TICKET_KEY_NAME_LEN) != 0) { +#ifndef UNSAFE_FUZZER_MODE SSL_DBG(("%d: SSL[%d]: Session ticket key_name sent mismatch.", SSL_GETPID(), ss->fd)); - goto no_ticket; + return SECSuccess; +#endif } - /* Verify the MAC on the ticket. MAC verification may also - * fail if the MAC key has been recently refreshed. - */ - PORT_Assert(mac_key); - hmac_ctx = PK11_CreateContextBySymKey(macMech, CKA_SIGN, mac_key, &macParam); - if (!hmac_ctx) { + /* Verify the MAC on the ticket. */ + PORT_Assert(macKey); + hmacCtx = PK11_CreateContextBySymKey(CKM_SHA256_HMAC, CKA_SIGN, macKey, + &macParam); + if (!hmacCtx) { SSL_DBG(("%d: SSL[%d]: Unable to create HMAC context: %d.", SSL_GETPID(), ss->fd, PORT_GetError())); - goto no_ticket; - } else { - SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.", - SSL_GETPID(), ss->fd)); - } - rv = PK11_DigestBegin(hmac_ctx); - if (rv != SECSuccess) { - PK11_DestroyContext(hmac_ctx, PR_TRUE); - goto no_ticket; + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } - rv = PK11_DigestOp(hmac_ctx, extension_data.data, - extension_data.len - - TLS_EX_SESS_TICKET_MAC_LENGTH); + + SSL_DBG(("%d: SSL[%d]: Successfully created HMAC context.", + SSL_GETPID(), ss->fd)); + do { + rv = PK11_DigestBegin(hmacCtx); + if (rv != SECSuccess) { + break; + } + rv = PK11_DigestOp(hmacCtx, rawTicket->data, + rawTicket->len - TLS_EX_SESS_TICKET_MAC_LENGTH); + if (rv != SECSuccess) { + break; + } + rv = PK11_DigestFinal(hmacCtx, computedMac, &computedMacLength, + sizeof(computedMac)); + } while (0); + PK11_DestroyContext(hmacCtx, PR_TRUE); if (rv != SECSuccess) { - PK11_DestroyContext(hmac_ctx, PR_TRUE); - goto no_ticket; + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } - rv = PK11_DigestFinal(hmac_ctx, computed_mac, - &computed_mac_length, sizeof(computed_mac)); - PK11_DestroyContext(hmac_ctx, PR_TRUE); - if (rv != SECSuccess) - goto no_ticket; - if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac, - computed_mac_length) != - 0) { + if (NSS_SecureMemcmp(computedMac, encryptedTicket->mac, + computedMacLength) != 0) { +#ifndef UNSAFE_FUZZER_MODE SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.", SSL_GETPID(), ss->fd)); - goto no_ticket; + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; +#endif } - /* We ignore key_name for now. - * This is ok as MAC verification succeeded. - */ - /* Decrypt the ticket. */ /* Plaintext is shorter than the ciphertext due to padding. */ - decrypted_state = SECITEM_AllocItem(NULL, NULL, - enc_session_ticket.encrypted_state.len); - - PORT_Assert(aes_key); - ivItem.data = enc_session_ticket.iv; + if (!SECITEM_AllocItem(NULL, decryptedTicket, + encryptedTicket->encrypted_state.len)) { + return SECFailure; /* code already set */ + } + + PORT_Assert(aesKey); +#ifdef UNSAFE_FUZZER_MODE + decryptedTicket->len = encryptedTicket->encrypted_state.len; + PORT_Memcpy(decryptedTicket->data, + encryptedTicket->encrypted_state.data, + encryptedTicket->encrypted_state.len); +#else + ivItem.data = encryptedTicket->iv; ivItem.len = AES_BLOCK_SIZE; - aes_ctx = PK11_CreateContextBySymKey(cipherMech, CKA_DECRYPT, - aes_key, &ivItem); - if (!aes_ctx) { + aesCtx = PK11_CreateContextBySymKey(CKM_AES_CBC, CKA_DECRYPT, aesKey, + &ivItem); + if (!aesCtx) { SSL_DBG(("%d: SSL[%d]: Unable to create AES context.", SSL_GETPID(), ss->fd)); - goto no_ticket; + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } - rv = PK11_CipherOp(aes_ctx, decrypted_state->data, - (int *)&decrypted_state->len, decrypted_state->len, - enc_session_ticket.encrypted_state.data, - enc_session_ticket.encrypted_state.len); - PK11_Finalize(aes_ctx); - PK11_DestroyContext(aes_ctx, PR_TRUE); - if (rv != SECSuccess) - goto no_ticket; + do { + rv = PK11_CipherOp(aesCtx, decryptedTicket->data, + (int *)&decryptedTicket->len, decryptedTicket->len, + encryptedTicket->encrypted_state.data, + encryptedTicket->encrypted_state.len); + if (rv != SECSuccess) { + break; + } + rv = PK11_Finalize(aesCtx); + if (rv != SECSuccess) { + break; + } + } while (0); + PK11_DestroyContext(aesCtx, PR_TRUE); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } /* Check padding. */ - padding_length = - (PRUint32)decrypted_state->data[decrypted_state->len - 1]; - if (padding_length == 0 || padding_length > AES_BLOCK_SIZE) - goto no_ticket; + paddingLength = decryptedTicket->data[decryptedTicket->len - 1]; + if (paddingLength == 0 || paddingLength > AES_BLOCK_SIZE) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } - padding = &decrypted_state->data[decrypted_state->len - padding_length]; - for (i = 0; i < padding_length; i++, padding++) { - if (padding_length != (PRUint32)*padding) - goto no_ticket; + padding = &decryptedTicket->data[decryptedTicket->len - paddingLength]; + for (i = 0; i < paddingLength; i++, padding++) { + if (paddingLength != *padding) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } } + decryptedTicket->len -= paddingLength; +#endif /* UNSAFE_FUZZER_MODE */ - /* Deserialize session state. */ - buffer = decrypted_state->data; - buffer_len = decrypted_state->len; + return SECSuccess; +} - parsed_session_ticket = PORT_ZAlloc(sizeof(SessionTicket)); - if (parsed_session_ticket == NULL) { - rv = SECFailure; - goto loser; +static SECStatus +ssl_ParseSessionTicket(sslSocket *ss, const SECItem *decryptedTicket, + SessionTicket *parsedTicket) +{ + PRUint32 temp; + SECStatus rv; + + SSL3Opaque *buffer = decryptedTicket->data; + unsigned int len = decryptedTicket->len; + + PORT_Memset(parsedTicket, 0, sizeof(*parsedTicket)); + parsedTicket->valid = PR_FALSE; + + /* If the decrypted ticket is empty, then report success, but leave the + * ticket marked as invalid. */ + if (decryptedTicket->len == 0) { + return SECSuccess; } - /* Read ticket_version and reject if the version is wrong */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); - if (temp != TLS_EX_SESS_TICKET_VERSION) - goto no_ticket; + /* Read ticket version. */ + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 2, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } - parsed_session_ticket->ticket_version = (SSL3ProtocolVersion)temp; + /* Skip the ticket if the version is wrong. This won't result in a + * handshake failure, just a failure to resume. */ + if (temp != TLS_EX_SESS_TICKET_VERSION) { + return SECSuccess; + } /* Read SSLVersion. */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->ssl_version = (SSL3ProtocolVersion)temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 2, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->ssl_version = (SSL3ProtocolVersion)temp; + if (!ssl3_VersionIsSupported(ss->protocolVariant, + parsedTicket->ssl_version)) { + /* This socket doesn't support the version from the ticket. */ + return SECSuccess; + } /* Read cipher_suite. */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->cipher_suite = (ssl3CipherSuite)temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 2, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->cipher_suite = (ssl3CipherSuite)temp; /* Read compression_method. */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->compression_method = (SSLCompressionMethod)temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->compression_method = (SSLCompressionMethod)temp; /* Read cipher spec parameters. */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->authType = (SSLAuthType)temp; - temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->authKeyBits = (PRUint32)temp; - temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->keaType = (SSLKEAType)temp; - temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->keaKeyBits = (PRUint32)temp; - - /* Read certificate slot */ - parsed_session_ticket->certType.authType = parsed_session_ticket->authType; - temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - switch (parsed_session_ticket->authType) { - case ssl_auth_ecdsa: - case ssl_auth_ecdh_rsa: - case ssl_auth_ecdh_ecdsa: { - const sslNamedGroupDef *group = - ssl_LookupNamedGroup((SSLNamedGroup)temp); - if (!group || group->keaType != ssl_kea_ecdh) { - goto no_ticket; - } - parsed_session_ticket->certType.namedCurve = group; - } break; - default: - break; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->authType = (SSLAuthType)temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } + parsedTicket->authKeyBits = temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->keaType = (SSLKEAType)temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->keaKeyBits = temp; - /* Read wrapped master_secret. */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->ms_is_wrapped = (PRBool)temp; - - temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->msWrapMech = (CK_MECHANISM_TYPE)temp; - - temp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->ms_length = (PRUint16)temp; - if (parsed_session_ticket->ms_length == 0 || /* sanity check MS. */ - parsed_session_ticket->ms_length > - sizeof(parsed_session_ticket->master_secret)) - goto no_ticket; - - /* Allow for the wrapped master secret to be longer. */ - if (buffer_len < parsed_session_ticket->ms_length) - goto no_ticket; - PORT_Memcpy(parsed_session_ticket->master_secret, buffer, - parsed_session_ticket->ms_length); - buffer += parsed_session_ticket->ms_length; - buffer_len -= parsed_session_ticket->ms_length; - - /* Read client_identity */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->client_identity.client_auth_type = - (ClientAuthenticationType)temp; - switch (parsed_session_ticket->client_identity.client_auth_type) { + /* Read the optional named curve. */ + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + if (parsedTicket->authType == ssl_auth_ecdsa || + parsedTicket->authType == ssl_auth_ecdh_rsa || + parsedTicket->authType == ssl_auth_ecdh_ecdsa) { + const sslNamedGroupDef *group = + ssl_LookupNamedGroup((SSLNamedGroup)temp); + if (!group || group->keaType != ssl_kea_ecdh) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->namedCurve = group; + } + + /* Read the master secret (and how it is wrapped). */ + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + PORT_Assert(temp == PR_TRUE || temp == PR_FALSE); + parsedTicket->ms_is_wrapped = (PRBool)temp; + + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->msWrapMech = (CK_MECHANISM_TYPE)temp; + + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 2, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + if (temp == 0 || temp > sizeof(parsedTicket->master_secret)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->ms_length = (PRUint16)temp; + + /* Read the master secret. */ + rv = ssl3_ExtConsumeHandshake(ss, parsedTicket->master_secret, + parsedTicket->ms_length, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + /* Read client identity */ + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->client_auth_type = (ClientAuthenticationType)temp; + switch (parsedTicket->client_auth_type) { case CLIENT_AUTH_ANONYMOUS: break; case CLIENT_AUTH_CERTIFICATE: - rv = ssl3_ExtConsumeHandshakeVariable(ss, &cert_item, 3, - &buffer, &buffer_len); - if (rv != SECSuccess) - goto no_ticket; - rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->peer_cert, - &cert_item); - if (rv != SECSuccess) - goto no_ticket; + rv = ssl3_ExtConsumeHandshakeVariable(ss, &parsedTicket->peer_cert, 2, + &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } break; default: - goto no_ticket; + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } /* Read timestamp. */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 4, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; - parsed_session_ticket->timestamp = (PRUint32)temp; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->timestamp = temp; /* Read server name */ - nameType = - ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (nameType != TLS_STE_NO_SERVER_NAME) { - SECItem name_item; - rv = ssl3_ExtConsumeHandshakeVariable(ss, &name_item, 2, &buffer, - &buffer_len); - if (rv != SECSuccess) - goto no_ticket; - rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName, - &name_item); - if (rv != SECSuccess) - goto no_ticket; - parsed_session_ticket->srvName.type = nameType; + rv = ssl3_ExtConsumeHandshakeVariable(ss, &parsedTicket->srvName, 2, + &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } /* Read extendedMasterSecretUsed */ - temp = ssl3_ExtConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); - if (temp < 0) - goto no_ticket; + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } PORT_Assert(temp == PR_TRUE || temp == PR_FALSE); - parsed_session_ticket->extendedMasterSecretUsed = (PRBool)temp; + parsedTicket->extendedMasterSecretUsed = (PRBool)temp; - rv = ssl3_ExtConsumeHandshake(ss, &parsed_session_ticket->flags, 4, - &buffer, &buffer_len); - if (rv != SECSuccess) - goto no_ticket; - parsed_session_ticket->flags = PR_ntohl(parsed_session_ticket->flags); + rv = ssl3_ExtConsumeHandshake(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->flags = PR_ntohl(temp); - rv = ssl3_ExtConsumeHandshakeVariable(ss, &alpn_item, 1, &buffer, &buffer_len); - if (rv != SECSuccess) - goto no_ticket; - if (alpn_item.len != 0) { - rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->alpnSelection, - &alpn_item); - if (rv != SECSuccess) - goto no_ticket; - if (alpn_item.len >= 256) - goto no_ticket; + rv = ssl3_ExtConsumeHandshakeVariable(ss, &parsedTicket->alpnSelection, 1, + &buffer, &len); + PORT_Assert(parsedTicket->alpnSelection.len < 256); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; } + rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 4, &buffer, &len); + if (rv != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + parsedTicket->maxEarlyData = temp; + +#ifndef UNSAFE_FUZZER_MODE /* Done parsing. Check that all bytes have been consumed. */ - if (buffer_len != padding_length) - goto no_ticket; + if (len != 0) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } +#endif - /* Use the ticket if it has not expired, otherwise free the allocated - * memory since the ticket is of no use. - */ - if (parsed_session_ticket->timestamp != 0 && - parsed_session_ticket->timestamp + - TLS_EX_SESS_TICKET_LIFETIME_HINT > - ssl_Time()) { - - sid = ssl3_NewSessionID(ss, PR_TRUE); - if (sid == NULL) { - rv = SECFailure; + parsedTicket->valid = PR_TRUE; + return SECSuccess; +} + +static SECStatus +ssl_CreateSIDFromTicket(sslSocket *ss, const SECItem *rawTicket, + SessionTicket *parsedTicket, sslSessionID **out) +{ + sslSessionID *sid; + SECStatus rv; + + sid = ssl3_NewSessionID(ss, PR_TRUE); + if (sid == NULL) { + return SECFailure; + } + + /* Copy over parameters. */ + sid->version = parsedTicket->ssl_version; + sid->u.ssl3.cipherSuite = parsedTicket->cipher_suite; + sid->u.ssl3.compression = parsedTicket->compression_method; + sid->authType = parsedTicket->authType; + sid->authKeyBits = parsedTicket->authKeyBits; + sid->keaType = parsedTicket->keaType; + sid->keaKeyBits = parsedTicket->keaKeyBits; + sid->namedCurve = parsedTicket->namedCurve; + + rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.locked.sessionTicket.ticket, + rawTicket); + if (rv != SECSuccess) { + goto loser; + } + sid->u.ssl3.locked.sessionTicket.flags = parsedTicket->flags; + sid->u.ssl3.locked.sessionTicket.max_early_data_size = + parsedTicket->maxEarlyData; + + if (parsedTicket->ms_length > + sizeof(sid->u.ssl3.keys.wrapped_master_secret)) { + goto loser; + } + PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret, + parsedTicket->master_secret, parsedTicket->ms_length); + sid->u.ssl3.keys.wrapped_master_secret_len = parsedTicket->ms_length; + sid->u.ssl3.masterWrapMech = parsedTicket->msWrapMech; + sid->u.ssl3.keys.msIsWrapped = parsedTicket->ms_is_wrapped; + sid->u.ssl3.masterValid = PR_TRUE; + sid->u.ssl3.keys.resumable = PR_TRUE; + sid->u.ssl3.keys.extendedMasterSecretUsed = parsedTicket->extendedMasterSecretUsed; + + /* Copy over client cert from session ticket if there is one. */ + if (parsedTicket->peer_cert.data != NULL) { + PORT_Assert(!sid->peerCert); + sid->peerCert = CERT_NewTempCertificate(ss->dbHandle, + &parsedTicket->peer_cert, + NULL, PR_FALSE, PR_TRUE); + if (!sid->peerCert) { goto loser; } + } - /* Copy over parameters. */ - sid->version = parsed_session_ticket->ssl_version; - sid->u.ssl3.cipherSuite = parsed_session_ticket->cipher_suite; - sid->u.ssl3.compression = parsed_session_ticket->compression_method; - sid->authType = parsed_session_ticket->authType; - sid->authKeyBits = parsed_session_ticket->authKeyBits; - sid->keaType = parsed_session_ticket->keaType; - sid->keaKeyBits = parsed_session_ticket->keaKeyBits; - memcpy(&sid->certType, &parsed_session_ticket->certType, - sizeof(sslServerCertType)); - - if (SECITEM_CopyItem(NULL, &sid->u.ssl3.locked.sessionTicket.ticket, - &extension_data) != SECSuccess) - goto no_ticket; - sid->u.ssl3.locked.sessionTicket.flags = parsed_session_ticket->flags; - - if (parsed_session_ticket->ms_length > - sizeof(sid->u.ssl3.keys.wrapped_master_secret)) - goto no_ticket; - PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret, - parsed_session_ticket->master_secret, - parsed_session_ticket->ms_length); - sid->u.ssl3.keys.wrapped_master_secret_len = - parsed_session_ticket->ms_length; - sid->u.ssl3.masterWrapMech = parsed_session_ticket->msWrapMech; - sid->u.ssl3.keys.msIsWrapped = - parsed_session_ticket->ms_is_wrapped; - sid->u.ssl3.masterValid = PR_TRUE; - sid->u.ssl3.keys.resumable = PR_TRUE; - sid->u.ssl3.keys.extendedMasterSecretUsed = parsed_session_ticket->extendedMasterSecretUsed; - - /* Copy over client cert from session ticket if there is one. */ - if (parsed_session_ticket->peer_cert.data != NULL) { - if (sid->peerCert != NULL) - CERT_DestroyCertificate(sid->peerCert); - sid->peerCert = CERT_NewTempCertificate(ss->dbHandle, - &parsed_session_ticket->peer_cert, NULL, PR_FALSE, PR_TRUE); - if (sid->peerCert == NULL) { - rv = SECFailure; - goto loser; - } - } - if (parsed_session_ticket->srvName.data != NULL) { - if (sid->u.ssl3.srvName.data) { - SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); - } - sid->u.ssl3.srvName = parsed_session_ticket->srvName; + /* Transfer ownership of the remaining items. */ + if (parsedTicket->srvName.data != NULL) { + SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE); + rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.srvName, + &parsedTicket->srvName); + if (rv != SECSuccess) { + goto loser; } - if (parsed_session_ticket->alpnSelection.data != NULL) { - sid->u.ssl3.alpnSelection = parsed_session_ticket->alpnSelection; - /* So we don't free below. */ - parsed_session_ticket->alpnSelection.data = NULL; + } + if (parsedTicket->alpnSelection.data != NULL) { + rv = SECITEM_CopyItem(NULL, &sid->u.ssl3.alpnSelection, + &parsedTicket->alpnSelection); + if (rv != SECSuccess) { + goto loser; } - ss->statelessResume = PR_TRUE; - ss->sec.ci.sid = sid; } - if (0) { - no_ticket: + *out = sid; + return SECSuccess; + +loser: + ssl_FreeSID(sid); + return SECFailure; +} + +/* Generic ticket processing code, common to all TLS versions. */ +SECStatus +ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data) +{ + EncryptedSessionTicket encryptedTicket; + SECItem decryptedTicket = { siBuffer, NULL, 0 }; + SessionTicket parsedTicket; + SECStatus rv; + + if (ss->sec.ci.sid != NULL) { + ss->sec.uncache(ss->sec.ci.sid); + ssl_FreeSID(ss->sec.ci.sid); + ss->sec.ci.sid = NULL; + } + + rv = ssl3_ParseEncryptedSessionTicket(ss, data, &encryptedTicket); + if (rv != SECSuccess) { + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; + } + + rv = ssl_DecryptSessionTicket(ss, data, &encryptedTicket, + &decryptedTicket); + if (rv != SECSuccess) { + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; + } + + rv = ssl_ParseSessionTicket(ss, &decryptedTicket, &parsedTicket); + if (rv != SECSuccess) { + SSL3Statistics *ssl3stats; + SSL_DBG(("%d: SSL[%d]: Session ticket parsing failed.", SSL_GETPID(), ss->fd)); ssl3stats = SSL_GetStatistics(); SSL_AtomicIncrementLong(&ssl3stats->hch_sid_ticket_parse_failures); + goto loser; /* code already set */ } - rv = SECSuccess; -loser: - /* ss->sec.ci.sid == sid if it did NOT come here via goto statement - * in that case do not free sid - */ - if (sid && (ss->sec.ci.sid != sid)) { - ssl_FreeSID(sid); - sid = NULL; - } - if (decrypted_state != NULL) { - SECITEM_FreeItem(decrypted_state, PR_TRUE); - decrypted_state = NULL; - } + /* Use the ticket if it is valid and unexpired. */ + if (parsedTicket.valid && + parsedTicket.timestamp + ssl_ticket_lifetime > ssl_Time()) { + sslSessionID *sid; - if (parsed_session_ticket != NULL) { - if (parsed_session_ticket->peer_cert.data) { - SECITEM_FreeItem(&parsed_session_ticket->peer_cert, PR_FALSE); - } - if (parsed_session_ticket->alpnSelection.data) { - SECITEM_FreeItem(&parsed_session_ticket->alpnSelection, PR_FALSE); + rv = ssl_CreateSIDFromTicket(ss, data, &parsedTicket, &sid); + if (rv != SECSuccess) { + goto loser; /* code already set */ } - PORT_ZFree(parsed_session_ticket, sizeof(SessionTicket)); + ss->statelessResume = PR_TRUE; + ss->sec.ci.sid = sid; } - return rv; + SECITEM_ZfreeItem(&decryptedTicket, PR_FALSE); + PORT_Memset(&parsedTicket, 0, sizeof(parsedTicket)); + return SECSuccess; + +loser: + SECITEM_ZfreeItem(&decryptedTicket, PR_FALSE); + PORT_Memset(&parsedTicket, 0, sizeof(parsedTicket)); + return SECFailure; } SECStatus @@ -2145,7 +2170,8 @@ ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUi &xtnData->clientSigSchemes, &xtnData->numClientSigScheme, &data->data, &data->len); - if (rv != SECSuccess) { + if (rv != SECSuccess || xtnData->numClientSigScheme == 0) { + ssl3_ExtSendAlert(ss, alert_fatal, decode_error); PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); return SECFailure; } @@ -2216,55 +2242,73 @@ ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool /* Takes the size of the ClientHello, less the record header, and determines how * much padding is required. */ -unsigned int -ssl3_CalculatePaddingExtensionLength(unsigned int clientHelloLength) +void +ssl3_CalculatePaddingExtLen(sslSocket *ss, + unsigned int clientHelloLength) { unsigned int recordLength = 1 /* handshake message type */ + 3 /* handshake message length */ + clientHelloLength; - unsigned int extensionLength; + unsigned int extensionLen; + + /* Don't pad for DTLS, for SSLv3, or for renegotiation. */ + if (IS_DTLS(ss) || + ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_0 || + ss->firstHsDone) { + return; + } + /* A padding extension may be included to ensure that the record containing + * the ClientHello doesn't have a length between 256 and 511 bytes + * (inclusive). Initial ClientHello records with such lengths trigger bugs + * in F5 devices. */ if (recordLength < 256 || recordLength >= 512) { - return 0; + return; } - extensionLength = 512 - recordLength; + extensionLen = 512 - recordLength; /* Extensions take at least four bytes to encode. Always include at least - * one byte of data if including the extension. Some servers (e.g. - * WebSphere Application Server 7.0 and Tomcat) will time out or terminate - * the connection if the last extension in the client hello is empty. */ - if (extensionLength < 4 + 1) { - extensionLength = 4 + 1; + * one byte of data if we are padding. Some servers will time out or + * terminate the connection if the last ClientHello extension is empty. */ + if (extensionLen < 4 + 1) { + extensionLen = 4 + 1; } - return extensionLength; + ss->xtnData.paddingLen = extensionLen - 4; } -/* ssl3_AppendPaddingExtension possibly adds an extension which ensures that a +/* ssl3_SendPaddingExtension possibly adds an extension which ensures that a * ClientHello record is either < 256 bytes or is >= 512 bytes. This ensures * that we don't trigger bugs in F5 products. */ PRInt32 -ssl3_AppendPaddingExtension(sslSocket *ss, unsigned int extensionLen, - PRUint32 maxBytes) +ssl3_ClientSendPaddingExtension(const sslSocket *ss, TLSExtensionData *xtnData, + PRBool append, PRUint32 maxBytes) { - unsigned int paddingLen = extensionLen - 4; - static unsigned char padding[252]; + static unsigned char padding[252] = { 0 }; + unsigned int extensionLen; + SECStatus rv; - if (extensionLen == 0) { + /* On the length-calculation pass, report zero total length. The record + * will be larger on the second pass if needed. */ + if (!append || !xtnData->paddingLen) { return 0; } + extensionLen = xtnData->paddingLen + 4; if (extensionLen > maxBytes || - !paddingLen || - paddingLen > sizeof(padding)) { + xtnData->paddingLen > sizeof(padding)) { PORT_Assert(0); return -1; } - if (SECSuccess != ssl3_ExtAppendHandshakeNumber(ss, ssl_padding_xtn, 2)) + rv = ssl3_ExtAppendHandshakeNumber(ss, ssl_padding_xtn, 2); + if (rv != SECSuccess) { return -1; - if (SECSuccess != ssl3_ExtAppendHandshakeVariable(ss, padding, paddingLen, 2)) + } + rv = ssl3_ExtAppendHandshakeVariable(ss, padding, xtnData->paddingLen, 2); + if (rv != SECSuccess) { return -1; + } return extensionLen; } @@ -2484,7 +2528,8 @@ ssl3_HandleSupportedPointFormatsXtn(const sslSocket *ss, TLSExtensionData *xtnDa static SECStatus ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data) { - PRInt32 list_len; + SECStatus rv; + PRUint32 list_len; unsigned int i; const sslNamedGroupDef *enabled[SSL_NAMED_GROUP_COUNT] = { 0 }; PORT_Assert(SSL_NAMED_GROUP_COUNT == PR_ARRAY_SIZE(enabled)); @@ -2495,8 +2540,8 @@ ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data) } /* get the length of elliptic_curve_list */ - list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { + rv = ssl3_ConsumeHandshakeNumber(ss, &list_len, 2, &data->data, &data->len); + if (rv != SECSuccess || data->len != list_len || (data->len % 2) != 0) { (void)ssl3_DecodeError(ss); return SECFailure; } @@ -2510,9 +2555,10 @@ ssl_UpdateSupportedGroups(sslSocket *ss, SECItem *data) /* Read groups from data and enable if in |enabled| */ while (data->len) { const sslNamedGroupDef *group; - PRInt32 curve_name = - ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (curve_name < 0) { + PRUint32 curve_name; + rv = ssl3_ConsumeHandshakeNumber(ss, &curve_name, 2, &data->data, + &data->len); + if (rv != SECSuccess) { return SECFailure; /* fatal alert already sent */ } group = ssl_LookupNamedGroup(curve_name); diff --git a/nss/lib/ssl/ssl3exthandle.h b/nss/lib/ssl/ssl3exthandle.h index 65223d6..5fdbe90 100644 --- a/nss/lib/ssl/ssl3exthandle.h +++ b/nss/lib/ssl/ssl3exthandle.h @@ -49,6 +49,9 @@ PRInt32 ssl3_ClientSendSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData SECStatus ssl3_ServerHandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data); +PRInt32 ssl3_ClientSendPaddingExtension(const sslSocket *ss, TLSExtensionData *xtnData, + PRBool append, PRUint32 maxBytes); + PRInt32 ssl3_ClientSendSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRBool append, PRUint32 maxBytes); diff --git a/nss/lib/ssl/ssl3gthr.c b/nss/lib/ssl/ssl3gthr.c index 2bcc1d0..cf6f4cb 100644 --- a/nss/lib/ssl/ssl3gthr.c +++ b/nss/lib/ssl/ssl3gthr.c @@ -32,6 +32,7 @@ ssl3_InitGather(sslGather *gs) gs->readOffset = 0; gs->dtlsPacketOffset = 0; gs->dtlsPacket.len = 0; + gs->rejectV2Records = PR_FALSE; status = sslBuffer_Grow(&gs->buf, 4096); return status; } @@ -147,8 +148,11 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs) switch (gs->state) { case GS_HEADER: /* Check for SSLv2 handshakes. Always assume SSLv3 on clients, - * support SSLv2 handshakes only when ssl2gs != NULL. */ - if (!ssl2gs || ssl3_isLikelyV3Hello(gs->hdr)) { + * support SSLv2 handshakes only when ssl2gs != NULL. + * Always assume v3 after we received the first record. */ + if (!ssl2gs || + ss->gs.rejectV2Records || + ssl3_isLikelyV3Hello(gs->hdr)) { /* Should have a non-SSLv2 record header in gs->hdr. Extract * the length of the following encrypted data, and then * read in the rest of the record into gs->inbuf. */ @@ -183,7 +187,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs) /* This is the max length for an encrypted SSLv3+ fragment. */ if (!v2HdrLength && gs->remainder > (MAX_FRAGMENT_LENGTH + 2048)) { - SSL3_SendAlert(ss, alert_fatal, unexpected_message); + SSL3_SendAlert(ss, alert_fatal, record_overflow); gs->state = GS_INIT; PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); return SECFailure; @@ -205,13 +209,28 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs) * many into the gs->hdr[] buffer. Copy them over into inbuf so * that we can properly process the hello record later. */ if (v2HdrLength) { + /* Reject v2 records that don't even carry enough data to + * resemble a valid ClientHello header. */ + if (gs->remainder < SSL_HL_CLIENT_HELLO_HBYTES) { + SSL3_SendAlert(ss, alert_fatal, illegal_parameter); + PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO); + return SECFailure; + } + + PORT_Assert(lbp); gs->inbuf.len = 5 - v2HdrLength; PORT_Memcpy(lbp, gs->hdr + v2HdrLength, gs->inbuf.len); gs->remainder -= gs->inbuf.len; lbp += gs->inbuf.len; } - break; /* End this case. Continue around the loop. */ + if (gs->remainder > 0) { + break; /* End this case. Continue around the loop. */ + } + + /* FALL THROUGH if (gs->remainder == 0) as we just received + * an empty record and there's really no point in calling + * ssl_DefRecv() with buf=NULL and len=0. */ case GS_DATA: /* @@ -219,6 +238,10 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs) */ SSL_TRC(10, ("%d: SSL[%d]: got record of %d bytes", SSL_GETPID(), ss->fd, gs->inbuf.len)); + + /* reject any v2 records from now on */ + ss->gs.rejectV2Records = PR_TRUE; + gs->state = GS_INIT; return 1; } diff --git a/nss/lib/ssl/ssl3prot.h b/nss/lib/ssl/ssl3prot.h index 146cba4..60a978b 100644 --- a/nss/lib/ssl/ssl3prot.h +++ b/nss/lib/ssl/ssl3prot.h @@ -287,7 +287,7 @@ typedef struct { /* NewSessionTicket handshake message. */ typedef struct { - PRUint32 received_timestamp; + PRTime received_timestamp; PRUint32 ticket_lifetime_hint; PRUint32 flags; PRUint32 ticket_age_add; @@ -305,13 +305,6 @@ typedef enum { CLIENT_AUTH_CERTIFICATE = 1 } ClientAuthenticationType; -typedef struct { - ClientAuthenticationType client_auth_type; - union { - SSL3Opaque *certificate_list; - } identity; -} ClientIdentity; - #define SESS_TICKET_KEY_NAME_LEN 16 #define SESS_TICKET_KEY_NAME_PREFIX "NSS!" #define SESS_TICKET_KEY_NAME_PREFIX_LEN 4 @@ -324,8 +317,4 @@ typedef struct { unsigned char *mac; } EncryptedSessionTicket; -#define TLS_EX_SESS_TICKET_MAC_LENGTH 32 - -#define TLS_STE_NO_SERVER_NAME -1 - #endif /* __ssl3proto_h_ */ diff --git a/nss/lib/ssl/sslcert.c b/nss/lib/ssl/sslcert.c index ea52455..388fc09 100644 --- a/nss/lib/ssl/sslcert.c +++ b/nss/lib/ssl/sslcert.c @@ -13,42 +13,91 @@ #include "nss.h" /* for NSS_RegisterShutdown */ #include "prinit.h" /* for PR_CallOnceWithArg */ -static const PRCallOnceType pristineCallOnce; -static PRCallOnceType setupServerCAListOnce; +/* This global item is used only in servers. It is is initialized by + * SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest(). + */ +static struct { + PRCallOnceType setup; + CERTDistNames *names; +} ssl_server_ca_list; static SECStatus -serverCAListShutdown(void *appData, void *nssData) +ssl_ServerCAListShutdown(void *appData, void *nssData) { - PORT_Assert(ssl3_server_ca_list); - if (ssl3_server_ca_list) { - CERT_FreeDistNames(ssl3_server_ca_list); - ssl3_server_ca_list = NULL; + PORT_Assert(ssl_server_ca_list.names); + if (ssl_server_ca_list.names) { + CERT_FreeDistNames(ssl_server_ca_list.names); } - setupServerCAListOnce = pristineCallOnce; + PORT_Memset(&ssl_server_ca_list, 0, sizeof(ssl_server_ca_list)); return SECSuccess; } static PRStatus -serverCAListSetup(void *arg) +ssl_SetupCAListOnce(void *arg) { CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg; - SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL); + SECStatus rv = NSS_RegisterShutdown(ssl_ServerCAListShutdown, NULL); PORT_Assert(SECSuccess == rv); if (SECSuccess == rv) { - ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle); + ssl_server_ca_list.names = CERT_GetSSLCACerts(dbHandle); return PR_SUCCESS; } return PR_FAILURE; } +SECStatus +ssl_SetupCAList(sslSocket *ss) +{ + if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_server_ca_list.setup, + &ssl_SetupCAListOnce, + (void *)(ss->dbHandle))) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + return SECSuccess; +} + +SECStatus +ssl_GetCertificateRequestCAs(sslSocket *ss, unsigned int *calen, + SECItem **names, unsigned int *nnames) +{ + SECItem *name; + CERTDistNames *ca_list; + unsigned int i; + + *calen = 0; + *names = NULL; + *nnames = 0; + + /* ssl3.ca_list is initialized to NULL, and never changed. */ + ca_list = ss->ssl3.ca_list; + if (!ca_list) { + if (ssl_SetupCAList(ss) != SECSuccess) { + return SECFailure; + } + ca_list = ssl_server_ca_list.names; + } + + if (ca_list != NULL) { + *names = ca_list->names; + *nnames = ca_list->nnames; + } + + for (i = 0, name = *names; i < *nnames; i++, name++) { + *calen += 2 + name->len; + } + return SECSuccess; +} + sslServerCert * -ssl_NewServerCert(const sslServerCertType *certType) +ssl_NewServerCert() { sslServerCert *sc = PORT_ZNew(sslServerCert); if (!sc) { return NULL; } - memcpy(&sc->certType, certType, sizeof(sc->certType)); + sc->authTypes = 0; + sc->namedCurve = NULL; sc->serverCert = NULL; sc->serverCertChain = NULL; sc->certStatusArray = NULL; @@ -61,11 +110,14 @@ ssl_CopyServerCert(const sslServerCert *oc) { sslServerCert *sc; - sc = ssl_NewServerCert(&oc->certType); + sc = ssl_NewServerCert(); if (!sc) { return NULL; } + sc->authTypes = oc->authTypes; + sc->namedCurve = oc->namedCurve; + if (oc->serverCert && oc->serverCertChain) { sc->serverCert = CERT_DupCertificate(oc->serverCert); if (!sc->serverCert) @@ -129,9 +181,9 @@ ssl_FreeServerCert(sslServerCert *sc) PORT_ZFree(sc, sizeof(*sc)); } -sslServerCert * -ssl_FindServerCert(const sslSocket *ss, - const sslServerCertType *certType) +const sslServerCert * +ssl_FindServerCert(const sslSocket *ss, SSLAuthType authType, + const sslNamedGroupDef *namedCurve) { PRCList *cursor; @@ -139,68 +191,21 @@ ssl_FindServerCert(const sslSocket *ss, cursor != &ss->serverCerts; cursor = PR_NEXT_LINK(cursor)) { sslServerCert *cert = (sslServerCert *)cursor; - if (cert->certType.authType != certType->authType) { + if (!SSL_CERT_IS(cert, authType)) { continue; } - switch (cert->certType.authType) { - case ssl_auth_ecdsa: - case ssl_auth_ecdh_rsa: - case ssl_auth_ecdh_ecdsa: - /* Note: For deprecated APIs, we need to be able to find and - match a slot with any named curve. */ - if (certType->namedCurve && - cert->certType.namedCurve != certType->namedCurve) { - continue; - } - break; - default: - break; + if (SSL_CERT_IS_EC(cert)) { + /* Note: For deprecated APIs, we need to be able to find and + match a slot with any named curve. */ + if (namedCurve && cert->namedCurve != namedCurve) { + continue; + } } return cert; } return NULL; } -sslServerCert * -ssl_FindServerCertByAuthType(const sslSocket *ss, SSLAuthType authType) -{ - sslServerCertType certType; - certType.authType = authType; - /* Setting the named curve to NULL ensures that all EC certificates - * are matched when searching for this slot. */ - certType.namedCurve = NULL; - return ssl_FindServerCert(ss, &certType); -} - -SECStatus -ssl_OneTimeCertSetup(sslSocket *ss, const sslServerCert *sc) -{ - if (PR_SUCCESS != PR_CallOnceWithArg(&setupServerCAListOnce, - &serverCAListSetup, - (void *)(ss->dbHandle))) { - return SECFailure; - } - return SECSuccess; -} - -/* Determine which slot a certificate fits into. SSLAuthType is known, but - * extra information needs to be worked out from the cert and key. */ -static void -ssl_PopulateCertType(sslServerCertType *certType, SSLAuthType authType, - CERTCertificate *cert, sslKeyPair *keyPair) -{ - certType->authType = authType; - switch (authType) { - case ssl_auth_ecdsa: - case ssl_auth_ecdh_rsa: - case ssl_auth_ecdh_ecdsa: - certType->namedCurve = ssl_ECPubKey2NamedGroup(keyPair->pubKey); - break; - default: - break; - } -} - static SECStatus ssl_PopulateServerCert(sslServerCert *sc, CERTCertificate *cert, const CERTCertificateList *certChain) @@ -232,21 +237,43 @@ ssl_PopulateServerCert(sslServerCert *sc, CERTCertificate *cert, static SECStatus ssl_PopulateKeyPair(sslServerCert *sc, sslKeyPair *keyPair) { - /* Copy over the key pair. */ if (sc->serverKeyPair) { ssl_FreeKeyPair(sc->serverKeyPair); + sc->serverKeyPair = NULL; } if (keyPair) { + KeyType keyType = SECKEY_GetPublicKeyType(keyPair->pubKey); + PORT_Assert(keyType == SECKEY_GetPrivateKeyType(keyPair->privKey)); + + if (keyType == ecKey) { + sc->namedCurve = ssl_ECPubKey2NamedGroup(keyPair->pubKey); + if (!sc->namedCurve) { + /* Unsupported curve. */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + } + /* Get the size of the cert's public key, and remember it. */ sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey); if (sc->serverKeyBits == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } SECKEY_CacheStaticFlags(keyPair->privKey); sc->serverKeyPair = ssl_GetKeyPairRef(keyPair); + + if (SSL_CERT_IS(sc, ssl_auth_rsa_decrypt)) { + /* This will update the global session ticket key pair with this + * key, if a value hasn't been set already. */ + if (ssl_MaybeSetSessionTicketKeyPair(keyPair) != SECSuccess) { + return SECFailure; + } + } } else { sc->serverKeyPair = NULL; + sc->namedCurve = NULL; } return SECSuccess; } @@ -281,12 +308,39 @@ ssl_PopulateSignedCertTimestamps(sslServerCert *sc, return SECSuccess; } +/* Find any existing certificates that overlap with the new certificate and + * either remove any supported authentication types that overlap with the new + * certificate or - if they have no types left - remove them entirely. */ +static void +ssl_ClearMatchingCerts(sslSocket *ss, sslAuthTypeMask authTypes, + const sslNamedGroupDef *namedCurve) +{ + PRCList *cursor = PR_NEXT_LINK(&ss->serverCerts); + + while (cursor != &ss->serverCerts) { + sslServerCert *sc = (sslServerCert *)cursor; + cursor = PR_NEXT_LINK(cursor); + if ((sc->authTypes & authTypes) == 0) { + continue; + } + /* namedCurve will be NULL only for legacy functions. */ + if (namedCurve != NULL && sc->namedCurve != namedCurve) { + continue; + } + + sc->authTypes &= ~authTypes; + if (sc->authTypes == 0) { + PR_REMOVE_LINK(&sc->link); + ssl_FreeServerCert(sc); + } + } +} + static SECStatus -ssl_ConfigCert(sslSocket *ss, CERTCertificate *cert, - sslKeyPair *keyPair, const SSLExtraServerCertData *data) +ssl_ConfigCert(sslSocket *ss, sslAuthTypeMask authTypes, + CERTCertificate *cert, sslKeyPair *keyPair, + const SSLExtraServerCertData *data) { - sslServerCert *oldsc; - sslServerCertType certType; SECStatus rv; sslServerCert *sc = NULL; int error_code = SEC_ERROR_NO_MEMORY; @@ -294,34 +348,26 @@ ssl_ConfigCert(sslSocket *ss, CERTCertificate *cert, PORT_Assert(cert); PORT_Assert(keyPair); PORT_Assert(data); - PORT_Assert(data->authType != ssl_auth_null); + PORT_Assert(authTypes); - if (!cert || !keyPair || !data || data->authType == ssl_auth_null) { + if (!cert || !keyPair || !data || !authTypes) { error_code = SEC_ERROR_INVALID_ARGS; goto loser; } - ssl_PopulateCertType(&certType, data->authType, cert, keyPair); - - /* Delete any existing certificate that matches this one, since we can only - * use one certificate of a given type. */ - oldsc = ssl_FindServerCert(ss, &certType); - if (oldsc) { - PR_REMOVE_LINK(&oldsc->link); - ssl_FreeServerCert(oldsc); - } - sc = ssl_NewServerCert(&certType); + sc = ssl_NewServerCert(); if (!sc) { goto loser; } + sc->authTypes = authTypes; rv = ssl_PopulateServerCert(sc, cert, data->certChain); if (rv != SECSuccess) { goto loser; } rv = ssl_PopulateKeyPair(sc, keyPair); if (rv != SECSuccess) { - error_code = SEC_ERROR_INVALID_ARGS; + error_code = PORT_GetError(); goto loser; } rv = ssl_PopulateOCSPResponses(sc, data->stapledOCSPResponses); @@ -332,23 +378,12 @@ ssl_ConfigCert(sslSocket *ss, CERTCertificate *cert, if (rv != SECSuccess) { goto loser; } + ssl_ClearMatchingCerts(ss, sc->authTypes, sc->namedCurve); PR_APPEND_LINK(&sc->link, &ss->serverCerts); - - /* This one-time setup depends on having the certificate in place. */ - rv = ssl_OneTimeCertSetup(ss, sc); - if (rv != SECSuccess) { - PR_REMOVE_LINK(&sc->link); - error_code = PORT_GetError(); - goto loser; - } return SECSuccess; loser: - if (sc) { - ssl_FreeServerCert(sc); - } - /* This is the only way any of the calls above can fail, except the one time - * setup, which doesn't land here. */ + ssl_FreeServerCert(sc); PORT_SetError(error_code); return SECFailure; } @@ -382,114 +417,55 @@ ssl_GetEcdhAuthType(CERTCertificate *cert) } } -/* This function examines the key usages of the given RSA-PKCS1 certificate - * and configures one or multiple server certificates based on that data. - * - * If the data argument contains an authType value other than ssl_auth_null, - * then only that slot will be used. If that choice is invalid, - * then this will fail. */ -static SECStatus -ssl_ConfigRsaPkcs1CertByUsage(sslSocket *ss, CERTCertificate *cert, - sslKeyPair *keyPair, - SSLExtraServerCertData *data) -{ - SECStatus rv = SECFailure; - - PRBool ku_sig = (PRBool)(cert->keyUsage & KU_DIGITAL_SIGNATURE); - PRBool ku_enc = (PRBool)(cert->keyUsage & KU_KEY_ENCIPHERMENT); - - if ((data->authType == ssl_auth_rsa_sign && ku_sig) || - (data->authType == ssl_auth_rsa_pss && ku_sig) || - (data->authType == ssl_auth_rsa_decrypt && ku_enc)) { - return ssl_ConfigCert(ss, cert, keyPair, data); - } - - if (data->authType != ssl_auth_null || !(ku_sig || ku_enc)) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (ku_sig) { - data->authType = ssl_auth_rsa_sign; - rv = ssl_ConfigCert(ss, cert, keyPair, data); - if (rv != SECSuccess) { - return rv; - } - - /* This certificate is RSA, assume that it's also PSS. */ - data->authType = ssl_auth_rsa_pss; - rv = ssl_ConfigCert(ss, cert, keyPair, data); - if (rv != SECSuccess) { - return rv; - } - } - - if (ku_enc) { - /* If ku_sig=true we configure signature and encryption slots with the - * same cert. This is bad form, but there are enough dual-usage RSA - * certs that we can't really break by limiting this to one type. */ - data->authType = ssl_auth_rsa_decrypt; - rv = ssl_ConfigCert(ss, cert, keyPair, data); - if (rv != SECSuccess) { - return rv; - } - } - - return rv; -} - /* This function examines the type of certificate and its key usage and - * configures a certificate based on that information. For some certificates - * this can mean that multiple server certificates are configured. + * chooses which authTypes apply. For some certificates + * this can mean that multiple authTypes. * - * If the data argument contains an authType value other than ssl_auth_null, - * then only that slot will be used. If that choice is invalid, - * then this will fail. */ -static SECStatus -ssl_ConfigCertByUsage(sslSocket *ss, CERTCertificate *cert, - sslKeyPair *keyPair, const SSLExtraServerCertData *data) + * If the targetAuthType is not ssl_auth_null, then only that type will be used. + * If that choice is invalid, then this function will fail. */ +static sslAuthTypeMask +ssl_GetCertificateAuthTypes(CERTCertificate *cert, SSLAuthType targetAuthType) { - SECStatus rv = SECFailure; - SSLExtraServerCertData arg; + sslAuthTypeMask authTypes = 0; SECOidTag tag; - PORT_Assert(data); - /* Take a (shallow) copy so that we can play with it */ - memcpy(&arg, data, sizeof(arg)); - tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm); switch (tag) { case SEC_OID_X500_RSA_ENCRYPTION: case SEC_OID_PKCS1_RSA_ENCRYPTION: - return ssl_ConfigRsaPkcs1CertByUsage(ss, cert, keyPair, &arg); + if (cert->keyUsage & KU_DIGITAL_SIGNATURE) { + authTypes |= 1 << ssl_auth_rsa_sign; + /* This certificate is RSA, assume that it's also PSS. */ + authTypes |= 1 << ssl_auth_rsa_pss; + } + + if (cert->keyUsage & KU_KEY_ENCIPHERMENT) { + /* If ku_sig=true we configure signature and encryption slots with the + * same cert. This is bad form, but there are enough dual-usage RSA + * certs that we can't really break by limiting this to one type. */ + authTypes |= 1 << ssl_auth_rsa_decrypt; + } + break; case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: if (cert->keyUsage & KU_DIGITAL_SIGNATURE) { - arg.authType = ssl_auth_rsa_pss; + authTypes |= 1 << ssl_auth_rsa_pss; } break; case SEC_OID_ANSIX9_DSA_SIGNATURE: if (cert->keyUsage & KU_DIGITAL_SIGNATURE) { - arg.authType = ssl_auth_dsa; + authTypes |= 1 << ssl_auth_dsa; } break; case SEC_OID_ANSIX962_EC_PUBLIC_KEY: + if (cert->keyUsage & KU_DIGITAL_SIGNATURE) { + authTypes |= 1 << ssl_auth_ecdsa; + } + /* Again, bad form to have dual usage and we don't prevent it. */ if (cert->keyUsage & KU_KEY_ENCIPHERMENT) { - if ((cert->keyUsage & KU_DIGITAL_SIGNATURE) && - arg.authType == ssl_auth_null) { - /* See above regarding bad practice. */ - arg.authType = ssl_auth_ecdsa; - rv = ssl_ConfigCert(ss, cert, keyPair, &arg); - if (rv != SECSuccess) { - return rv; - } - } - - arg.authType = ssl_GetEcdhAuthType(cert); - } else if (cert->keyUsage & KU_DIGITAL_SIGNATURE) { - arg.authType = ssl_auth_ecdsa; + authTypes |= 1 << ssl_GetEcdhAuthType(cert); } break; @@ -498,27 +474,33 @@ ssl_ConfigCertByUsage(sslSocket *ss, CERTCertificate *cert, } /* Check that we successfully picked an authType */ - if (arg.authType == ssl_auth_null) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* |data->authType| has to either agree or be ssl_auth_null. */ - if (data && data->authType != ssl_auth_null && - data->authType != arg.authType) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + if (targetAuthType != ssl_auth_null) { + authTypes &= 1 << targetAuthType; } - return ssl_ConfigCert(ss, cert, keyPair, &arg); + return authTypes; } /* This function adopts pubKey and destroys it if things go wrong. */ static sslKeyPair * -ssl_MakeKeyPairForCert(SECKEYPrivateKey *key, SECKEYPublicKey *pubKey) +ssl_MakeKeyPairForCert(SECKEYPrivateKey *key, CERTCertificate *cert) { sslKeyPair *keyPair = NULL; + SECKEYPublicKey *pubKey = NULL; SECKEYPrivateKey *privKeyCopy = NULL; PK11SlotInfo *bestSlot; + pubKey = CERT_ExtractPublicKey(cert); + if (!pubKey) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return NULL; + } + + if (SECKEY_GetPublicKeyType(pubKey) != SECKEY_GetPrivateKeyType(key)) { + SECKEY_DestroyPublicKey(pubKey); + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + if (key->pkcs11Slot) { bestSlot = PK11_ReferenceSlot(key->pkcs11Slot); if (bestSlot) { @@ -545,20 +527,18 @@ ssl_MakeKeyPairForCert(SECKEYPrivateKey *key, SECKEYPublicKey *pubKey) if (privKeyCopy) { SECKEY_DestroyPrivateKey(privKeyCopy); } - /* We adopted the public key, so we're responsible. */ - if (pubKey) { - SECKEY_DestroyPublicKey(pubKey); - } + SECKEY_DestroyPublicKey(pubKey); + PORT_SetError(SEC_ERROR_NO_MEMORY); } return keyPair; } /* Configure a certificate and private key. * - * This function examines the certificate and key to determine which slot (or - * slots) to place the information in. As long as certificates are different - * (based on having different values of sslServerCertType), then this function - * can be called multiple times and the certificates will all be remembered. + * This function examines the certificate and key to determine the type (or + * types) of authentication the certificate supports. As long as certificates + * are different (different authTypes and maybe keys in different ec groups), + * then this function can be called multiple times. */ SECStatus SSL_ConfigServerCert(PRFileDesc *fd, CERTCertificate *cert, @@ -566,12 +546,12 @@ SSL_ConfigServerCert(PRFileDesc *fd, CERTCertificate *cert, const SSLExtraServerCertData *data, unsigned int data_len) { sslSocket *ss; - SECKEYPublicKey *pubKey; sslKeyPair *keyPair; SECStatus rv; SSLExtraServerCertData dataCopy = { ssl_auth_null, NULL, NULL, NULL }; + sslAuthTypeMask authTypes; ss = ssl_FindSocket(fd); if (!ss) { @@ -591,21 +571,23 @@ SSL_ConfigServerCert(PRFileDesc *fd, CERTCertificate *cert, PORT_Memcpy(&dataCopy, data, data_len); } - pubKey = CERT_ExtractPublicKey(cert); - if (!pubKey) { + authTypes = ssl_GetCertificateAuthTypes(cert, dataCopy.authType); + if (!authTypes) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - keyPair = ssl_MakeKeyPairForCert(key, pubKey); + keyPair = ssl_MakeKeyPairForCert(key, cert); if (!keyPair) { - /* pubKey is adopted by ssl_MakeKeyPairForCert() */ - PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } - rv = ssl_ConfigCertByUsage(ss, cert, keyPair, &dataCopy); + rv = ssl_ConfigCert(ss, authTypes, cert, keyPair, &dataCopy); ssl_FreeKeyPair(keyPair); - return rv; + if (rv != SECSuccess) { + return SECFailure; + } + return SECSuccess; } /*******************************************************************/ @@ -630,164 +612,148 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, * ssl_ConfigCertByUsage(), only checking against the type of key and ignoring * things like usage. */ static PRBool -ssl_CertSuitableForAuthType(CERTCertificate *cert, SSLAuthType authType) +ssl_CertSuitableForAuthType(CERTCertificate *cert, sslAuthTypeMask authTypes) { SECOidTag tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm); - switch (authType) { - case ssl_auth_rsa_decrypt: - case ssl_auth_rsa_sign: - return tag == SEC_OID_X500_RSA_ENCRYPTION || - tag == SEC_OID_PKCS1_RSA_ENCRYPTION; - case ssl_auth_dsa: - return tag == SEC_OID_ANSIX9_DSA_SIGNATURE; - case ssl_auth_ecdsa: - case ssl_auth_ecdh_rsa: - case ssl_auth_ecdh_ecdsa: - return tag == SEC_OID_ANSIX962_EC_PUBLIC_KEY; - case ssl_auth_null: - case ssl_auth_kea: - case ssl_auth_rsa_pss: /* not supported with deprecated APIs */ - return PR_FALSE; + sslAuthTypeMask mask = 0; + switch (tag) { + case SEC_OID_X500_RSA_ENCRYPTION: + case SEC_OID_PKCS1_RSA_ENCRYPTION: + mask |= 1 << ssl_auth_rsa_decrypt; + mask |= 1 << ssl_auth_rsa_sign; + break; + case SEC_OID_ANSIX9_DSA_SIGNATURE: + mask |= 1 << ssl_auth_dsa; + break; + case SEC_OID_ANSIX962_EC_PUBLIC_KEY: + mask |= 1 << ssl_auth_ecdsa; + mask |= 1 << ssl_auth_ecdh_rsa; + mask |= 1 << ssl_auth_ecdh_ecdsa; + break; default: - PORT_Assert(0); - return PR_FALSE; + break; + } + PORT_Assert(authTypes); + /* Simply test that no inappropriate auth types are set. */ + return (authTypes & ~mask) == 0; +} + +/* Lookup a cert for the legacy configuration functions. An exact match on + * authTypes and ignoring namedCurve will ensure that values configured using + * legacy functions are overwritten by other legacy functions. */ +static sslServerCert * +ssl_FindCertWithMask(sslSocket *ss, sslAuthTypeMask authTypes) +{ + PRCList *cursor; + + for (cursor = PR_NEXT_LINK(&ss->serverCerts); + cursor != &ss->serverCerts; + cursor = PR_NEXT_LINK(cursor)) { + sslServerCert *cert = (sslServerCert *)cursor; + if (cert->authTypes == authTypes) { + return cert; + } } + return NULL; } -/* This finds an existing server cert slot and unlinks it, or it makes a new +/* This finds an existing server cert in a matching slot that can be reused. + * Failing that, it removes any other certs that might conflict and makes a new * server cert slot of the right type. */ static sslServerCert * -ssl_FindOrMakeCertType(sslSocket *ss, SSLAuthType authType) +ssl_FindOrMakeCert(sslSocket *ss, sslAuthTypeMask authTypes) { sslServerCert *sc; - sslServerCertType certType; - certType.authType = authType; - /* Setting the named curve to NULL ensures that all EC certificates - * are matched when searching for this slot. */ - certType.namedCurve = NULL; - sc = ssl_FindServerCert(ss, &certType); + /* Reuse a perfect match. Note that there is a problem here with use of + * multiple EC certificates that have keys on different curves: these + * deprecated functions will match the first found and overwrite that + * certificate, potentially leaving the other values with a duplicate curve. + * Configuring multiple EC certificates are only possible with the new + * functions, so this is not something that is worth fixing. */ + sc = ssl_FindCertWithMask(ss, authTypes); if (sc) { PR_REMOVE_LINK(&sc->link); return sc; } - return ssl_NewServerCert(&certType); + /* Ignore the namedCurve parameter. Like above, this means that legacy + * functions will clobber values set with the new functions blindly. */ + ssl_ClearMatchingCerts(ss, authTypes, NULL); + + sc = ssl_NewServerCert(); + if (sc) { + sc->authTypes = authTypes; + } + return sc; } -static void -ssl_RemoveCertAndKeyByAuthType(sslSocket *ss, SSLAuthType authType) +static sslAuthTypeMask +ssl_KeaTypeToAuthTypeMask(SSLKEAType keaType) { - sslServerCert *sc; + switch (keaType) { + case ssl_kea_rsa: + return (1 << ssl_auth_rsa_decrypt) | + (1 << ssl_auth_rsa_sign); - sc = ssl_FindServerCertByAuthType(ss, authType); - if (sc) { - (void)ssl_PopulateServerCert(sc, NULL, NULL); - (void)ssl_PopulateKeyPair(sc, NULL); - /* Leave the entry linked here because the old API expects that. There - * might be OCSP stapling values or signed certificate timestamps still - * present that will subsequently be used. */ - /* For ECC certificates, also leave the namedCurve parameter on the slot - * unchanged; the value will be updated when a key is added. */ + case ssl_kea_dh: + return 1 << ssl_auth_dsa; + + case ssl_kea_ecdh: + return (1 << ssl_auth_ecdsa) | + (1 << ssl_auth_ecdh_rsa) | + (1 << ssl_auth_ecdh_ecdsa); + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); } + return 0; } static SECStatus -ssl_AddCertAndKeyByAuthType(sslSocket *ss, SSLAuthType authType, - CERTCertificate *cert, - const CERTCertificateList *certChainOpt, - sslKeyPair *keyPair) +ssl_AddCertChain(sslSocket *ss, CERTCertificate *cert, + const CERTCertificateList *certChainOpt, + SECKEYPrivateKey *key, sslAuthTypeMask authTypes) { sslServerCert *sc; + sslKeyPair *keyPair; SECStatus rv; + PRErrorCode err = SEC_ERROR_NO_MEMORY; - if (!ssl_CertSuitableForAuthType(cert, authType)) { + if (!ssl_CertSuitableForAuthType(cert, authTypes)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - sc = ssl_FindOrMakeCertType(ss, authType); + sc = ssl_FindOrMakeCert(ss, authTypes); if (!sc) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - rv = ssl_PopulateKeyPair(sc, keyPair); - if (rv != SECSuccess) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); goto loser; } - /* Now that we have a key pair, update the details of the slot. Many of the - * legacy functions create a slot with a namedCurve of NULL, which - * makes the slot unusable; this corrects that. */ - ssl_PopulateCertType(&sc->certType, authType, cert, keyPair); + rv = ssl_PopulateServerCert(sc, cert, certChainOpt); if (rv != SECSuccess) { - PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } - PR_APPEND_LINK(&sc->link, &ss->serverCerts); - return ssl_OneTimeCertSetup(ss, sc); -loser: - ssl_FreeServerCert(sc); - return SECFailure; -} - -static SECStatus -ssl_AddCertsByKEA(sslSocket *ss, CERTCertificate *cert, - const CERTCertificateList *certChainOpt, - SECKEYPrivateKey *key, SSLKEAType certType) -{ - SECKEYPublicKey *pubKey; - sslKeyPair *keyPair; - SECStatus rv; - pubKey = CERT_ExtractPublicKey(cert); - if (!pubKey) { - return SECFailure; - } - - keyPair = ssl_MakeKeyPairForCert(key, pubKey); + keyPair = ssl_MakeKeyPairForCert(key, cert); if (!keyPair) { - /* Note: pubKey is adopted or freed by ssl_MakeKeyPairForCert() - * depending on whether it succeeds or not. */ - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; + /* Error code is set by ssl_MakeKeyPairForCert */ + goto loser; } - - switch (certType) { - case ssl_kea_rsa: - rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_rsa_decrypt, - cert, certChainOpt, keyPair); - if (rv != SECSuccess) { - return SECFailure; - } - rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_rsa_sign, - cert, certChainOpt, keyPair); - break; - - case ssl_kea_dh: - rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_dsa, - cert, certChainOpt, keyPair); - break; - - case ssl_kea_ecdh: - rv = ssl_AddCertAndKeyByAuthType(ss, ssl_auth_ecdsa, - cert, certChainOpt, keyPair); - if (rv != SECSuccess) { - return SECFailure; - } - rv = ssl_AddCertAndKeyByAuthType(ss, ssl_GetEcdhAuthType(cert), - cert, certChainOpt, keyPair); - break; - - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - rv = SECFailure; - break; + rv = ssl_PopulateKeyPair(sc, keyPair); + ssl_FreeKeyPair(keyPair); + if (rv != SECSuccess) { + err = PORT_GetError(); + goto loser; } - ssl_FreeKeyPair(keyPair); - return rv; + PR_APPEND_LINK(&sc->link, &ss->serverCerts); + return SECSuccess; + +loser: + ssl_FreeServerCert(sc); + PORT_SetError(err); + return SECFailure; } /* Public deprecated function */ @@ -797,6 +763,7 @@ SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, SECKEYPrivateKey *key, SSLKEAType certType) { sslSocket *ss; + sslAuthTypeMask authTypes; ss = ssl_FindSocket(fd); if (!ss) { @@ -808,52 +775,25 @@ SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, return SECFailure; } + authTypes = ssl_KeaTypeToAuthTypeMask(certType); + if (!authTypes) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (!cert) { - switch (certType) { - case ssl_kea_rsa: - ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_rsa_decrypt); - ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_rsa_sign); - break; - - case ssl_kea_dh: - ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_dsa); - break; - - case ssl_kea_ecdh: - ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_ecdsa); - ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_ecdh_rsa); - ssl_RemoveCertAndKeyByAuthType(ss, ssl_auth_ecdh_ecdsa); - break; - - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + sslServerCert *sc = ssl_FindCertWithMask(ss, authTypes); + if (sc) { + (void)ssl_PopulateServerCert(sc, NULL, NULL); + (void)ssl_PopulateKeyPair(sc, NULL); + /* Leave the entry linked here because the old API expects that. + * There might be OCSP stapling values or signed certificate + * timestamps still present that will subsequently be used. */ } return SECSuccess; } - return ssl_AddCertsByKEA(ss, cert, certChainOpt, key, certType); -} - -static SECStatus -ssl_SetOCSPResponsesInSlot(sslSocket *ss, SSLAuthType authType, - const SECItemArray *responses) -{ - sslServerCert *sc; - SECStatus rv; - - sc = ssl_FindOrMakeCertType(ss, authType); - if (!sc) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - rv = ssl_PopulateOCSPResponses(sc, responses); - if (rv == SECSuccess) { - PR_APPEND_LINK(&sc->link, &ss->serverCerts); - } else { - ssl_FreeServerCert(sc); - } - return rv; + return ssl_AddCertChain(ss, cert, certChainOpt, key, authTypes); } /* Public deprecated function */ @@ -862,6 +802,8 @@ SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses, SSLKEAType certType) { sslSocket *ss; + sslServerCert *sc; + sslAuthTypeMask authTypes; SECStatus rv; ss = ssl_FindSocket(fd); @@ -871,49 +813,28 @@ SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses, return SECFailure; } - switch (certType) { - case ssl_kea_rsa: - rv = ssl_SetOCSPResponsesInSlot(ss, ssl_auth_rsa_decrypt, responses); - if (rv != SECSuccess) { - return SECFailure; - } - return ssl_SetOCSPResponsesInSlot(ss, ssl_auth_rsa_sign, responses); - - case ssl_kea_dh: - return ssl_SetOCSPResponsesInSlot(ss, ssl_auth_dsa, responses); - - case ssl_kea_ecdh: - rv = ssl_SetOCSPResponsesInSlot(ss, ssl_auth_ecdsa, responses); - if (rv != SECSuccess) { - return SECFailure; - } - rv = ssl_SetOCSPResponsesInSlot(ss, ssl_auth_ecdh_rsa, responses); - if (rv != SECSuccess) { - return SECFailure; - } - return ssl_SetOCSPResponsesInSlot(ss, ssl_auth_ecdh_ecdsa, responses); - - default: - SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetStapledOCSPResponses", - SSL_GETPID(), fd)); - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + authTypes = ssl_KeaTypeToAuthTypeMask(certType); + if (!authTypes) { + SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetStapledOCSPResponses", + SSL_GETPID(), fd)); + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } -} -static SECStatus -ssl_SetSignedTimestampsInSlot(sslSocket *ss, SSLAuthType authType, - const SECItem *scts) -{ - sslServerCert *sc; - SECStatus rv; + if (!responses) { + sc = ssl_FindCertWithMask(ss, authTypes); + if (sc) { + (void)ssl_PopulateOCSPResponses(sc, NULL); + } + return SECSuccess; + } - sc = ssl_FindOrMakeCertType(ss, authType); + sc = ssl_FindOrMakeCert(ss, authTypes); if (!sc) { - PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } - rv = ssl_PopulateSignedCertTimestamps(sc, scts); + + rv = ssl_PopulateOCSPResponses(sc, responses); if (rv == SECSuccess) { PR_APPEND_LINK(&sc->link, &ss->serverCerts); } else { @@ -928,6 +849,8 @@ SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts, SSLKEAType certType) { sslSocket *ss; + sslServerCert *sc; + sslAuthTypeMask authTypes; SECStatus rv; ss = ssl_FindSocket(fd); @@ -937,34 +860,34 @@ SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts, return SECFailure; } - switch (certType) { - case ssl_kea_rsa: - rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_rsa_decrypt, scts); - if (rv != SECSuccess) { - return SECFailure; - } - return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_rsa_sign, scts); + authTypes = ssl_KeaTypeToAuthTypeMask(certType); + if (!authTypes) { + SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetSignedCertTimestamps", + SSL_GETPID(), fd)); + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } - case ssl_kea_dh: - return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_dsa, scts); + if (!scts) { + sc = ssl_FindCertWithMask(ss, authTypes); + if (sc) { + (void)ssl_PopulateSignedCertTimestamps(sc, NULL); + } + return SECSuccess; + } - case ssl_kea_ecdh: - rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdsa, scts); - if (rv != SECSuccess) { - return SECFailure; - } - rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdh_rsa, scts); - if (rv != SECSuccess) { - return SECFailure; - } - return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdh_ecdsa, scts); + sc = ssl_FindOrMakeCert(ss, authTypes); + if (!sc) { + return SECFailure; + } - default: - SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetSignedCertTimestamps", - SSL_GETPID(), fd)); - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + rv = ssl_PopulateSignedCertTimestamps(sc, scts); + if (rv == SECSuccess) { + PR_APPEND_LINK(&sc->link, &ss->serverCerts); + } else { + ssl_FreeServerCert(sc); } + return rv; } /* Public deprecated function. */ diff --git a/nss/lib/ssl/sslcert.h b/nss/lib/ssl/sslcert.h index 052c7d6..fb31d13 100644 --- a/nss/lib/ssl/sslcert.h +++ b/nss/lib/ssl/sslcert.h @@ -13,26 +13,21 @@ #include "secitem.h" #include "keyhi.h" -/* The following struct identifies a single slot into which a certificate can be -** loaded. The authType field determines the basic slot, then additional -** parameters further narrow the slot. -** -** An EC key (ssl_auth_ecdsa or ssl_auth_ecdh_*) is assigned to a slot based on -** the named curve of the key. -*/ -typedef struct sslServerCertTypeStr { - SSLAuthType authType; +/* This type is a bitvector that is indexed by SSLAuthType values. Note that + * the bit for ssl_auth_null(0) - the least significant bit - isn't used. */ +typedef PRUint16 sslAuthTypeMask; +PR_STATIC_ASSERT(sizeof(sslAuthTypeMask) * 8 >= ssl_auth_size); + +typedef struct sslServerCertStr { + PRCList link; /* The linked list link */ + + /* The auth types that this certificate provides. */ + sslAuthTypeMask authTypes; /* For ssl_auth_ecdsa and ssl_auth_ecdh_*. This is only the named curve * of the end-entity certificate key. The keys in other certificates in * the chain aren't directly relevant to the operation of TLS (though it * might make certificate validation difficult, libssl doesn't care). */ const sslNamedGroupDef *namedCurve; -} sslServerCertType; - -typedef struct sslServerCertStr { - PRCList link; /* The linked list link */ - - sslServerCertType certType; /* The certificate slot this occupies */ /* Configuration state for server sockets */ CERTCertificate *serverCert; @@ -48,12 +43,18 @@ typedef struct sslServerCertStr { SECItem signedCertTimestamps; } sslServerCert; -extern sslServerCert *ssl_NewServerCert(const sslServerCertType *slot); +#define SSL_CERT_IS(c, t) ((c)->authTypes & (1 << (t))) +#define SSL_CERT_IS_ONLY(c, t) ((c)->authTypes == (1 << (t))) +#define SSL_CERT_IS_EC(c) \ + ((c)->authTypes & ((1 << ssl_auth_ecdsa) | \ + (1 << ssl_auth_ecdh_rsa) | \ + (1 << ssl_auth_ecdh_ecdsa))) + +extern sslServerCert *ssl_NewServerCert(); extern sslServerCert *ssl_CopyServerCert(const sslServerCert *oc); -extern sslServerCert *ssl_FindServerCert(const sslSocket *ss, - const sslServerCertType *slot); -extern sslServerCert *ssl_FindServerCertByAuthType(const sslSocket *ss, - SSLAuthType authType); +extern const sslServerCert *ssl_FindServerCert( + const sslSocket *ss, SSLAuthType authType, + const sslNamedGroupDef *namedCurve); extern void ssl_FreeServerCert(sslServerCert *sc); #endif /* __sslcert_h_ */ diff --git a/nss/lib/ssl/ssldef.c b/nss/lib/ssl/ssldef.c index 77a744c..be5bcb2 100644 --- a/nss/lib/ssl/ssldef.c +++ b/nss/lib/ssl/ssldef.c @@ -66,6 +66,8 @@ ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) PRFileDesc *lower = ss->fd->lower; int rv; + PORT_Assert(buf && len > 0); + rv = lower->methods->recv(lower, (void *)buf, len, flags, ss->rTimeout); if (rv < 0) { DEFINE_ERROR diff --git a/nss/lib/ssl/sslerr.h b/nss/lib/ssl/sslerr.h index 751c335..865077c 100644 --- a/nss/lib/ssl/sslerr.h +++ b/nss/lib/ssl/sslerr.h @@ -244,6 +244,8 @@ typedef enum { SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION = (SSL_ERROR_BASE + 157), SSL_ERROR_MALFORMED_PSK_KEY_EXCHANGE_MODES = (SSL_ERROR_BASE + 158), SSL_ERROR_MISSING_PSK_KEY_EXCHANGE_MODES = (SSL_ERROR_BASE + 159), + SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA = (SSL_ERROR_BASE + 160), + SSL_ERROR_TOO_MUCH_EARLY_DATA = (SSL_ERROR_BASE + 161), SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ } SSLErrorCodes; #endif /* NO_SECURITY_ERROR_ENUM */ diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h index 09c3783..55fb8cb 100644 --- a/nss/lib/ssl/sslimpl.h +++ b/nss/lib/ssl/sslimpl.h @@ -34,7 +34,7 @@ #include "sslt.h" /* for some formerly private types, now public */ typedef struct sslSocketStr sslSocket; - +typedef struct ssl3CipherSpecStr ssl3CipherSpec; #include "ssl3ext.h" /* to make some of these old enums public without namespace pollution, @@ -125,7 +125,8 @@ typedef enum { SSLAppOpRead = 0, #define SSL3_MASTER_SECRET_LENGTH 48 /* number of wrap mechanisms potentially used to wrap master secrets. */ -#define SSL_NUM_WRAP_MECHS 16 +#define SSL_NUM_WRAP_MECHS 15 +#define SSL_NUM_WRAP_KEYS 6 /* This makes the cert cache entry exactly 4k. */ #define SSL_MAX_CACHED_CERT_LEN 4060 @@ -200,6 +201,9 @@ typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr, unsigned char *sid, unsigned int sidLen, CERTCertDBHandle *dbHandle); +typedef void (*sslCipherSpecChangedFunc)(void *arg, + PRBool sending, + ssl3CipherSpec *newSpec); /* Socket ops */ struct sslSocketOpsStr { @@ -367,6 +371,10 @@ struct sslGatherStr { /* the start of the buffered DTLS record in dtlsPacket */ unsigned int dtlsPacketOffset; + + /* tracks whether we've seen a v3-type record before and must reject + * any further v2-type records. */ + PRBool rejectV2Records; }; /* sslGather.state */ @@ -469,7 +477,7 @@ typedef struct DTLSRecvdRecordsStr { ** Access to the pointers to these specs, and all the specs' contents ** (direct and indirect) is protected by the reader/writer lock ss->specLock. */ -typedef struct { +struct ssl3CipherSpecStr { PRCList link; const ssl3BulkCipherDef *cipher_def; const ssl3MACDef *mac_def; @@ -496,10 +504,13 @@ typedef struct { SECItem msItem; DTLSEpoch epoch; DTLSRecvdRecords recvdRecords; + /* The number of 0-RTT bytes that can be sent or received in TLS 1.3. This + * will be zero for everything but 0-RTT. */ + PRUint32 earlyDataRemaining; PRUint8 refCt; const char *phase; -} ssl3CipherSpec; +}; typedef enum { never_cached, in_client_cache, @@ -523,10 +534,10 @@ struct sslSessionIDStr { */ CERTCertificate *peerCert; - SECItemArray peerCertStatus; /* client only */ - const char *peerID; /* client only */ - const char *urlSvrName; /* client only */ - sslServerCertType certType; + SECItemArray peerCertStatus; /* client only */ + const char *peerID; /* client only */ + const char *urlSvrName; /* client only */ + const sslNamedGroupDef *namedCurve; /* (server) for certificate lookup */ CERTCertificate *localCert; PRIPv6Addr addr; @@ -862,7 +873,6 @@ typedef struct SSL3HandshakeStateStr { TLS13CertificateRequest *certificateRequest; PRCList cipherSpecs; /* The cipher specs in the sequence they * will be applied. */ - ssl3CipherSpec *nullSpec; /* In case 0-RTT is rejected. */ sslZeroRttState zeroRttState; /* Are we doing a 0-RTT handshake? */ sslZeroRttIgnore zeroRttIgnore; /* Are we ignoring 0-RTT? */ ssl3CipherSuite zeroRttSuite; /* The cipher suite we used for 0-RTT. */ @@ -894,6 +904,11 @@ struct ssl3StateStr { ssl3CipherSpec *cwSpec; /* current write spec. */ ssl3CipherSpec *pwSpec; /* pending write spec. */ + /* Internal callback for when we do a cipher suite change. Used for + * debugging in TLS 1.3. This can only be set by non-public functions. */ + sslCipherSpecChangedFunc changedCipherSpecFunc; + void *changedCipherSpecArg; + CERTCertificate *clientCertificate; /* used by client */ SECKEYPrivateKey *clientPrivateKey; /* used by client */ CERTCertificateList *clientCertChain; /* used by client */ @@ -971,13 +986,13 @@ typedef struct SSLWrappedSymWrappingKeyStr { CK_MECHANISM_TYPE asymWrapMechanism; /* mechanism used to wrap the SymmetricWrappingKey using * server's public and/or private keys. */ - SSLAuthType authType; /* type of keys used to wrap SymWrapKey*/ - PRInt32 symWrapMechIndex; + PRInt16 wrapMechIndex; + PRUint16 wrapKeyIndex; PRUint16 wrappedSymKeyLen; } SSLWrappedSymWrappingKey; typedef struct SessionTicketStr { - PRUint16 ticket_version; + PRBool valid; SSL3ProtocolVersion ssl_version; ssl3CipherSuite cipher_suite; SSLCompressionMethod compression_method; @@ -985,7 +1000,8 @@ typedef struct SessionTicketStr { PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; - sslServerCertType certType; + const sslNamedGroupDef *namedCurve; /* For certificate lookup. */ + /* * msWrapMech contains a meaningful value only if ms_is_wrapped is true. */ @@ -994,12 +1010,13 @@ typedef struct SessionTicketStr { PRUint16 ms_length; SSL3Opaque master_secret[48]; PRBool extendedMasterSecretUsed; - ClientIdentity client_identity; + ClientAuthenticationType client_auth_type; SECItem peer_cert; PRUint32 timestamp; PRUint32 flags; SECItem srvName; /* negotiated server name */ SECItem alpnSelection; + PRUint32 maxEarlyData; } SessionTicket; /* @@ -1121,6 +1138,10 @@ struct sslSocketStr { void *getClientAuthDataArg; SSLSNISocketConfig sniSocketConfig; void *sniSocketConfigArg; + SSLAlertCallback alertReceivedCallback; + void *alertReceivedCallbackArg; + SSLAlertCallback alertSentCallback; + void *alertSentCallbackArg; SSLBadCertHandler handleBadCert; void *badCertArg; SSLHandshakeCallback handshakeCallback; @@ -1208,17 +1229,13 @@ struct sslSocketStr { SSLProtocolVariant protocolVariant; }; -/* All the global data items declared here should be protected using the -** ssl_global_data_lock, which is a reader/writer lock. -*/ -extern NSSRWLock *ssl_global_data_lock; extern char ssl_debug; extern char ssl_trace; extern FILE *ssl_trace_iob; extern FILE *ssl_keylog_iob; -extern CERTDistNames *ssl3_server_ca_list; -extern PRUint32 ssl_sid_timeout; extern PRUint32 ssl3_sid_timeout; +extern PRUint32 ssl_ticket_lifetime; +extern PRUint32 ssl_max_early_data_size; extern const char *const ssl3_cipherName[]; @@ -1338,8 +1355,8 @@ extern SECStatus ssl_CipherPrefSetDefault(PRInt32 which, PRBool enabled); extern SECStatus ssl3_ConstrainRangeByPolicy(void); -extern SECStatus ssl3_InitState(sslSocket *ss); -extern SECStatus ssl3_RestartHandshakeHashes(sslSocket *ss); +extern void ssl3_InitState(sslSocket *ss); +extern void ssl3_RestartHandshakeHashes(sslSocket *ss); extern SECStatus ssl3_UpdateHandshakeHashes(sslSocket *ss, const unsigned char *b, unsigned int l); @@ -1479,6 +1496,14 @@ extern PRInt32 ssl3_SendRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, */ #define SSL_LIBRARY_VERSION_NONE 0 +/* SSL_LIBRARY_VERSION_MIN_SUPPORTED is the minimum version that this version + * of libssl supports. Applications should use SSL_VersionRangeGetSupported at + * runtime to determine which versions are supported by the version of libssl + * in use. + */ +#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM SSL_LIBRARY_VERSION_TLS_1_1 +#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM SSL_LIBRARY_VERSION_3_0 + /* SSL_LIBRARY_VERSION_MAX_SUPPORTED is the maximum version that this version * of libssl supports. Applications should use SSL_VersionRangeGetSupported at * runtime to determine which versions are supported by the version of libssl @@ -1627,7 +1652,6 @@ extern SECStatus ssl3_SendECDHServerKeyExchange(sslSocket *ss); extern SECStatus ssl_ImportECDHKeyShare( sslSocket *ss, SECKEYPublicKey *peerKey, SSL3Opaque *b, PRUint32 length, const sslNamedGroupDef *curve); -unsigned int tls13_SizeOfECDHEKeyShareKEX(const SECKEYPublicKey *pubKey); SECStatus tls13_EncodeECDHEKeyShareKEX(const sslSocket *ss, const SECKEYPublicKey *pubKey); @@ -1647,12 +1671,13 @@ extern SECStatus ssl3_AppendHandshakeVariable(sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize); extern SECStatus ssl3_AppendSignatureAndHashAlgorithm( sslSocket *ss, const SSLSignatureAndHashAlg *sigAndHash); -extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, +extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRUint32 bytes, SSL3Opaque **b, PRUint32 *length); -extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, - SSL3Opaque **b, PRUint32 *length); +extern SECStatus ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRUint32 *num, + PRUint32 bytes, SSL3Opaque **b, + PRUint32 *length); extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, - PRInt32 bytes, SSL3Opaque **b, + PRUint32 bytes, SSL3Opaque **b, PRUint32 *length); extern PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to); @@ -1671,8 +1696,7 @@ extern SECStatus ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash, extern SECStatus ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme, SSL3Hashes *hash, SECItem *buf); extern SECStatus ssl3_CacheWrappedMasterSecret( - sslSocket *ss, sslSessionID *sid, - ssl3CipherSpec *spec, SSLAuthType authType); + sslSocket *ss, sslSessionID *sid, ssl3CipherSpec *spec); extern void ssl3_FreeSniNameArray(TLSExtensionData *xtnData); /* Hello Extension related routines. */ @@ -1681,15 +1705,10 @@ extern void ssl3_SetSIDSessionTicket(sslSessionID *sid, SECStatus ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket_input, SECItem *ticket_data); -extern PRBool ssl_GetSessionTicketKeys(SECKEYPrivateKey *svrPrivKey, - SECKEYPublicKey *svrPubKey, void *pwArg, - unsigned char *keyName, PK11SymKey **aesKey, - PK11SymKey **macKey); -extern SECStatus ssl3_SessionTicketShutdown(void *appData, void *nssData); - -/* Tell clients to consider tickets valid for this long. */ -#define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */ -#define TLS_EX_SESS_TICKET_VERSION (0x0103) +SECStatus ssl_MaybeSetSessionTicketKeyPair(const sslKeyPair *keyPair); +SECStatus ssl_GetSessionTicketKeys(sslSocket *ss, unsigned char *keyName, + PK11SymKey **encKey, PK11SymKey **macKey); +void ssl_ResetSessionTicketKeys(); extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char *data, unsigned int length); @@ -1703,8 +1722,8 @@ extern void ssl_FreePRSocket(PRFileDesc *fd); extern int ssl3_config_match_init(sslSocket *); /* calls for accessing wrapping keys across processes. */ -extern PRBool -ssl_GetWrappingKey(PRInt32 symWrapMechIndex, SSLAuthType authType, +extern SECStatus +ssl_GetWrappingKey(unsigned int symWrapMechIndex, unsigned int wrapKeyIndex, SSLWrappedSymWrappingKey *wswk); /* The caller passes in the new value it wants @@ -1716,7 +1735,7 @@ ssl_GetWrappingKey(PRInt32 symWrapMechIndex, SSLAuthType authType, * This is all done while holding the locks/semaphores necessary to make * the operation atomic. */ -extern PRBool +extern SECStatus ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk); /* get rid of the symmetric wrapping key references. */ @@ -1781,8 +1800,8 @@ SECStatus ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b, PRUint32 length); SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32 *len); -void ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calenp, SECItem **namesp, - int *nnamesp); +SECStatus ssl_GetCertificateRequestCAs(sslSocket *ss, unsigned int *calenp, + SECItem **namesp, unsigned int *nnamesp); SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b, PRUint32 *length, PLArenaPool *arena, CERTDistNames *ca_list); @@ -1802,7 +1821,6 @@ SECStatus ssl_CreateStaticECDHEKey(sslSocket *ss, SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags); PK11SymKey *ssl3_GetWrappingKey(sslSocket *ss, PK11SlotInfo *masterSecretSlot, - const sslServerCert *serverCert, CK_MECHANISM_TYPE masterWrapMech, void *pwArg); SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid); @@ -1835,6 +1853,7 @@ extern void ssl3_CheckCipherSuiteOrderConsistency(); extern int ssl_MapLowLevelError(int hiLevelError); extern PRUint32 ssl_Time(void); +extern PRBool ssl_TicketTimeValid(const NewSessionTicket *ticket); extern void SSL_AtomicIncrementLong(long *x); @@ -1844,11 +1863,12 @@ extern HASH_HashType ssl3_GetTls12HashType(sslSocket *ss); extern SECStatus -ssl3_TLSPRFWithMasterSecret(ssl3CipherSpec *spec, +ssl3_TLSPRFWithMasterSecret(sslSocket *ss, ssl3CipherSpec *spec, const char *label, unsigned int labelLen, const unsigned char *val, unsigned int valLen, - unsigned char *out, unsigned int outLen, - HASH_HashType tls12HashType); + unsigned char *out, unsigned int outLen); + +PRBool ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag); #ifdef TRACE #define SSL_TRACE(msg) ssl_Trace msg diff --git a/nss/lib/ssl/sslinfo.c b/nss/lib/ssl/sslinfo.c index 665109d..88162d8 100644 --- a/nss/lib/ssl/sslinfo.c +++ b/nss/lib/ssl/sslinfo.c @@ -140,6 +140,20 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, inf.valuesSet = ss->ssl3.hs.preliminaryInfo; inf.protocolVersion = ss->version; inf.cipherSuite = ss->ssl3.hs.cipher_suite; + inf.canSendEarlyData = !ss->sec.isServer && + (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent || + ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted); + /* We shouldn't be able to send early data if the handshake is done. */ + PORT_Assert(!ss->firstHsDone || !inf.canSendEarlyData); + + if (ss->sec.ci.sid && + (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent || + ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted)) { + inf.maxEarlyDataSize = + ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size; + } else { + inf.maxEarlyDataSize = 0; + } memcpy(info, &inf, inf.length); return SECSuccess; @@ -219,6 +233,9 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd, #define F_NFIPS_NSTD 0, 0, 1, 0 /* i.e., trash */ #define F_EXPORT 0, 1, 0, 0 /* i.e., trash */ +// RFC 5705 +#define MAX_CONTEXT_LEN PR_UINT16_MAX - 1 + static const SSLCipherSuiteInfo suiteInfo[] = { /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */ { 0, CS_(TLS_AES_128_GCM_SHA256), S_ANY, K_ANY, C_AESGCM, B_128, M_AEAD_128, F_FIPS_STD, A_ANY }, @@ -425,6 +442,11 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, out, outLen); } + if (hasContext && contextLen > MAX_CONTEXT_LEN) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + /* construct PRF arguments */ valLen = SSL3_RANDOM_LENGTH * 2; if (hasContext) { @@ -455,9 +477,8 @@ SSL_ExportKeyingMaterial(PRFileDesc *fd, PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED); rv = SECFailure; } else { - HASH_HashType ht = ssl3_GetTls12HashType(ss); - rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val, - valLen, out, outLen, ht); + rv = ssl3_TLSPRFWithMasterSecret(ss, ss->ssl3.cwSpec, label, labelLen, + val, valLen, out, outLen); } ssl_ReleaseSpecReadLock(ss); diff --git a/nss/lib/ssl/sslmutex.c b/nss/lib/ssl/sslmutex.c index 560a9e8..10b6cf5 100644 --- a/nss/lib/ssl/sslmutex.c +++ b/nss/lib/ssl/sslmutex.c @@ -60,7 +60,8 @@ single_process_sslMutex_Lock(sslMutex* pMutex) return SECSuccess; } -#if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) +#if defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || \ + (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) || defined(__GLIBC__) #include <unistd.h> #include <fcntl.h> diff --git a/nss/lib/ssl/sslmutex.h b/nss/lib/ssl/sslmutex.h index 7611148..3f63ed8 100644 --- a/nss/lib/ssl/sslmutex.h +++ b/nss/lib/ssl/sslmutex.h @@ -49,7 +49,8 @@ typedef struct { typedef int sslPID; -#elif defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) +#elif defined(LINUX) || defined(AIX) || defined(BEOS) || defined(BSDI) || \ + (defined(NETBSD) && __NetBSD_Version__ < 500000000) || defined(OPENBSD) || defined(__GLIBC__) #include <sys/types.h> #include "prtypes.h" diff --git a/nss/lib/ssl/sslnonce.c b/nss/lib/ssl/sslnonce.c index 91cc870..7ad1c6b 100644 --- a/nss/lib/ssl/sslnonce.c +++ b/nss/lib/ssl/sslnonce.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file implements the CLIENT Session ID cache. * @@ -18,7 +19,6 @@ #include <time.h> #endif -PRUint32 ssl_sid_timeout = 100; PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */ static sslSessionID *cache = NULL; @@ -460,6 +460,20 @@ ssl_Time(void) return myTime; } +PRBool +ssl_TicketTimeValid(const NewSessionTicket *ticket) +{ + PRTime endTime; + + if (ticket->ticket_lifetime_hint == 0) { + return PR_TRUE; + } + + endTime = ticket->received_timestamp + + (PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC); + return endTime > PR_Now(); +} + void ssl3_SetSIDSessionTicket(sslSessionID *sid, /*in/out*/ NewSessionTicket *newSessionTicket) diff --git a/nss/lib/ssl/sslsecur.c b/nss/lib/ssl/sslsecur.c index eecf443..8bec3d3 100644 --- a/nss/lib/ssl/sslsecur.c +++ b/nss/lib/ssl/sslsecur.c @@ -478,7 +478,7 @@ sslBuffer_Append(sslBuffer *b, const void *data, unsigned int len) void sslBuffer_Clear(sslBuffer *b) { - if (b->len > 0) { + if (b->buf) { PORT_Free(b->buf); b->buf = NULL; b->len = 0; @@ -884,6 +884,7 @@ int ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) { int rv = 0; + PRBool zeroRtt = PR_FALSE; SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", SSL_GETPID(), ss->fd, len)); @@ -923,19 +924,20 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) * Case 2: TLS 1.3 0-RTT */ if (!ss->firstHsDone) { - PRBool falseStart = PR_FALSE; + PRBool allowEarlySend = PR_FALSE; + ssl_Get1stHandshakeLock(ss); if (ss->opt.enableFalseStart || (ss->opt.enable0RttData && !ss->sec.isServer)) { ssl_GetSSL3HandshakeLock(ss); /* The client can sometimes send before the handshake is fully * complete. In TLS 1.2: false start; in TLS 1.3: 0-RTT. */ - falseStart = ss->ssl3.hs.canFalseStart || - ss->ssl3.hs.zeroRttState == ssl_0rtt_sent || - ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted; + zeroRtt = ss->ssl3.hs.zeroRttState == ssl_0rtt_sent || + ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted; + allowEarlySend = ss->ssl3.hs.canFalseStart || zeroRtt; ssl_ReleaseSSL3HandshakeLock(ss); } - if (!falseStart && ss->handshake) { + if (!allowEarlySend && ss->handshake) { rv = ssl_Do1stHandshake(ss); } ssl_Release1stHandshakeLock(ss); @@ -945,6 +947,20 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) goto done; } + if (zeroRtt) { + /* There's a limit to the number of early data octets we can send. + * + * Note that taking this lock doesn't prevent the cipher specs from + * being changed out between here and when records are ultimately + * encrypted. The only effect of that is to occasionally do an + * unnecessary short write when data is identified as 0-RTT here but + * 1-RTT later. + */ + ssl_GetSpecReadLock(ss); + len = tls13_LimitEarlyData(ss, content_application_data, len); + ssl_ReleaseSpecReadLock(ss); + } + /* Check for zero length writes after we do housekeeping so we make forward * progress. */ @@ -959,19 +975,6 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) goto done; } - if (!ss->firstHsDone) { -#ifdef DEBUG - ssl_GetSSL3HandshakeLock(ss); - PORT_Assert(!ss->sec.isServer && - (ss->ssl3.hs.canFalseStart || - ss->ssl3.hs.zeroRttState == ssl_0rtt_sent || - ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted)); - ssl_ReleaseSSL3HandshakeLock(ss); -#endif - SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start", - SSL_GETPID(), ss->fd)); - } - ssl_GetXmitBufLock(ss); rv = ssl3_SendApplicationData(ss, buf, len, flags); ssl_ReleaseXmitBufLock(ss); @@ -994,6 +997,42 @@ ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len) } SECStatus +SSL_AlertReceivedCallback(PRFileDesc *fd, SSLAlertCallback cb, void *arg) +{ + sslSocket *ss; + + ss = ssl_FindSocket(fd); + if (!ss) { + SSL_DBG(("%d: SSL[%d]: unable to find socket in SSL_AlertReceivedCallback", + SSL_GETPID(), fd)); + return SECFailure; + } + + ss->alertReceivedCallback = cb; + ss->alertReceivedCallbackArg = arg; + + return SECSuccess; +} + +SECStatus +SSL_AlertSentCallback(PRFileDesc *fd, SSLAlertCallback cb, void *arg) +{ + sslSocket *ss; + + ss = ssl_FindSocket(fd); + if (!ss) { + SSL_DBG(("%d: SSL[%d]: unable to find socket in SSL_AlertSentCallback", + SSL_GETPID(), fd)); + return SECFailure; + } + + ss->alertSentCallback = cb; + ss->alertSentCallbackArg = arg; + + return SECSuccess; +} + +SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg) { sslSocket *ss; diff --git a/nss/lib/ssl/sslsnce.c b/nss/lib/ssl/sslsnce.c index 4a4005c..cf86edc 100644 --- a/nss/lib/ssl/sslsnce.c +++ b/nss/lib/ssl/sslsnce.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* This file implements the SERVER Session ID cache. * NOTE: The contents of this file are NOT used by the client. * @@ -33,7 +34,7 @@ * sidCacheSet sidCacheSets[ numSIDCacheSets ]; * sidCacheEntry sidCacheData[ numSIDCacheEntries]; * certCacheEntry certCacheData[numCertCacheEntries]; - * SSLWrappedSymWrappingKey keyCacheData[ssl_auth_size][SSL_NUM_WRAP_MECHS]; + * SSLWrappedSymWrappingKey keyCacheData[SSL_NUM_WRAP_KEYS][SSL_NUM_WRAP_MECHS]; * PRUint8 keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN] * encKeyCacheEntry ticketEncKey; // Wrapped * encKeyCacheEntry ticketMacKey; // Wrapped @@ -54,6 +55,7 @@ #include "base64.h" #include "keyhi.h" #include "blapit.h" +#include "nss.h" /* for NSS_RegisterShutdown */ #include "sechash.h" #include <stdio.h> @@ -109,7 +111,7 @@ struct sidCacheEntryStr { /* 4 */ PRInt32 certIndex; /* 4 */ PRInt32 srvNameIndex; /* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */ - /* 2 */ PRUint16 certTypeArgs; + /* 2 */ PRUint16 namedCurve; /*104 */} ssl3; /* force sizeof(sidCacheEntry) to be a multiple of cache line size */ @@ -440,17 +442,12 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from) to->u.ssl3.srvNameIndex = -1; PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID, to->sessionIDLength); - to->u.ssl3.certTypeArgs = 0U; - switch (from->authType) { - case ssl_auth_ecdsa: - case ssl_auth_ecdh_rsa: - case ssl_auth_ecdh_ecdsa: - PORT_Assert(from->certType.namedCurve); - to->u.ssl3.certTypeArgs = - (PRUint16)from->certType.namedCurve->name; - break; - default: - break; + to->u.ssl3.namedCurve = 0U; + if (from->authType == ssl_auth_ecdsa || + from->authType == ssl_auth_ecdh_rsa || + from->authType == ssl_auth_ecdh_ecdsa) { + PORT_Assert(from->namedCurve); + to->u.ssl3.namedCurve = (PRUint16)from->namedCurve->name; } SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x " @@ -526,16 +523,11 @@ ConvertToSID(sidCacheEntry *from, if (to->peerCert == NULL) goto loser; } - to->certType.authType = from->authType; - switch (from->authType) { - case ssl_auth_ecdsa: - case ssl_auth_ecdh_rsa: - case ssl_auth_ecdh_ecdsa: - to->certType.namedCurve = - ssl_LookupNamedGroup((SSLNamedGroup)from->u.ssl3.certTypeArgs); - break; - default: - break; + if (from->authType == ssl_auth_ecdsa || + from->authType == ssl_auth_ecdh_rsa || + from->authType == ssl_auth_ecdh_ecdsa) { + to->namedCurve = + ssl_LookupNamedGroup((SSLNamedGroup)from->u.ssl3.namedCurve); } to->version = from->version; @@ -983,7 +975,7 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries, cache->certCacheSize = (char *)cache->keyCacheData - (char *)cache->certCacheData; - cache->numKeyCacheEntries = ssl_auth_size * SSL_NUM_WRAP_MECHS; + cache->numKeyCacheEntries = SSL_NUM_WRAP_KEYS * SSL_NUM_WRAP_MECHS; ptr = (ptrdiff_t)(cache->keyCacheData + cache->numKeyCacheEntries); ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT); @@ -1608,36 +1600,255 @@ StopLockPoller(cacheDesc *cache) * Code dealing with shared wrapped symmetric wrapping keys below * ************************************************************************/ -/* If now is zero, it implies that the lock is not held, and must be -** aquired here. -*/ +/* The asymmetric key we use for wrapping the symmetric ticket keys. This is a + * global structure that can be initialized without a socket. Access is + * synchronized on the reader-writer lock. This is setup either by calling + * SSL_SetSessionTicketKeyPair() or by configuring a certificate of the + * ssl_auth_rsa_decrypt type. */ +static struct { + PRCallOnceType setup; + PRRWLock *lock; + SECKEYPublicKey *pubKey; + SECKEYPrivateKey *privKey; + PRBool configured; +} ssl_session_ticket_key_pair; + +/* The symmetric ticket keys. This requires a socket to construct and requires + * that the global structure be initialized before use. */ +static struct { + PRCallOnceType setup; + unsigned char keyName[SESS_TICKET_KEY_NAME_LEN]; + PK11SymKey *encKey; + PK11SymKey *macKey; +} ssl_session_ticket_keys; + +static void +ssl_CleanupSessionTicketKeyPair() +{ + if (ssl_session_ticket_key_pair.pubKey) { + PORT_Assert(ssl_session_ticket_key_pair.privKey); + SECKEY_DestroyPublicKey(ssl_session_ticket_key_pair.pubKey); + SECKEY_DestroyPrivateKey(ssl_session_ticket_key_pair.privKey); + } +} + +void +ssl_ResetSessionTicketKeys() +{ + if (ssl_session_ticket_keys.encKey) { + PORT_Assert(ssl_session_ticket_keys.macKey); + PK11_FreeSymKey(ssl_session_ticket_keys.encKey); + PK11_FreeSymKey(ssl_session_ticket_keys.macKey); + } + PORT_Memset(&ssl_session_ticket_keys, 0, + sizeof(ssl_session_ticket_keys)); +} + +static SECStatus +ssl_SessionTicketShutdown(void *appData, void *nssData) +{ + ssl_CleanupSessionTicketKeyPair(); + PR_DestroyRWLock(ssl_session_ticket_key_pair.lock); + PORT_Memset(&ssl_session_ticket_key_pair, 0, + sizeof(ssl_session_ticket_key_pair)); + + ssl_ResetSessionTicketKeys(); + return SECSuccess; +} + +static PRStatus +ssl_SessionTicketSetup(void) +{ + SECStatus rv = NSS_RegisterShutdown(ssl_SessionTicketShutdown, NULL); + if (rv != SECSuccess) { + return PR_FAILURE; + } + ssl_session_ticket_key_pair.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL); + if (!ssl_session_ticket_key_pair.lock) { + return PR_FAILURE; + } + return PR_SUCCESS; +} + +/* Configure a session ticket key pair. |explicitConfig| is set to true for + * calls to SSL_SetSessionTicketKeyPair(), false for implicit configuration. + * This assumes that the setup has been run. */ +static SECStatus +ssl_SetSessionTicketKeyPair(SECKEYPublicKey *pubKey, + SECKEYPrivateKey *privKey, + PRBool explicitConfig) +{ + SECKEYPublicKey *pubKeyCopy; + SECKEYPrivateKey *privKeyCopy; + + PORT_Assert(ssl_session_ticket_key_pair.lock); + + pubKeyCopy = SECKEY_CopyPublicKey(pubKey); + if (!pubKeyCopy) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + return SECFailure; + } + + privKeyCopy = SECKEY_CopyPrivateKey(privKey); + if (!privKeyCopy) { + SECKEY_DestroyPublicKey(pubKeyCopy); + PORT_SetError(SEC_ERROR_NO_MEMORY); + return SECFailure; + } + + PR_RWLock_Wlock(ssl_session_ticket_key_pair.lock); + ssl_CleanupSessionTicketKeyPair(); + ssl_session_ticket_key_pair.pubKey = pubKeyCopy; + ssl_session_ticket_key_pair.privKey = privKeyCopy; + ssl_session_ticket_key_pair.configured = explicitConfig; + PR_RWLock_Unlock(ssl_session_ticket_key_pair.lock); + return SECSuccess; +} + +SECStatus +SSL_SetSessionTicketKeyPair(SECKEYPublicKey *pubKey, + SECKEYPrivateKey *privKey) +{ + if (SECKEY_GetPublicKeyType(pubKey) != rsaKey || + SECKEY_GetPrivateKeyType(privKey) != rsaKey) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + if (PR_SUCCESS != PR_CallOnce(&ssl_session_ticket_key_pair.setup, + &ssl_SessionTicketSetup)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + return ssl_SetSessionTicketKeyPair(pubKey, privKey, PR_TRUE); +} + +/* When configuring a server cert, we should save the RSA key in case it is + * needed for ticket encryption. This saves the latest copy, unless there has + * been an explicit call to SSL_SetSessionTicketKeyPair(). */ +SECStatus +ssl_MaybeSetSessionTicketKeyPair(const sslKeyPair *keyPair) +{ + PRBool configured; + + if (PR_SUCCESS != PR_CallOnce(&ssl_session_ticket_key_pair.setup, + &ssl_SessionTicketSetup)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + PR_RWLock_Rlock(ssl_session_ticket_key_pair.lock); + configured = ssl_session_ticket_key_pair.configured; + PR_RWLock_Unlock(ssl_session_ticket_key_pair.lock); + if (configured) { + return SECSuccess; + } + return ssl_SetSessionTicketKeyPair(keyPair->pubKey, + keyPair->privKey, PR_FALSE); +} + +static SECStatus +ssl_GetSessionTicketKeyPair(SECKEYPublicKey **pubKey, + SECKEYPrivateKey **privKey) +{ + if (PR_SUCCESS != PR_CallOnce(&ssl_session_ticket_key_pair.setup, + &ssl_SessionTicketSetup)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + PR_RWLock_Rlock(ssl_session_ticket_key_pair.lock); + *pubKey = ssl_session_ticket_key_pair.pubKey; + *privKey = ssl_session_ticket_key_pair.privKey; + PR_RWLock_Unlock(ssl_session_ticket_key_pair.lock); + if (!*pubKey) { + PORT_Assert(!*privKey); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + PORT_Assert(*privKey); + return SECSuccess; +} + static PRBool -getSvrWrappingKey(PRInt32 symWrapMechIndex, - SSLAuthType authType, +ssl_GenerateSessionTicketKeys(void *pwArg, unsigned char *keyName, + PK11SymKey **aesKey, PK11SymKey **macKey); + +static PRStatus +ssl_GenerateSessionTicketKeysOnce(void *arg) +{ + SECStatus rv; + + /* Get a copy of the session keys from shared memory. */ + PORT_Memcpy(ssl_session_ticket_keys.keyName, + SESS_TICKET_KEY_NAME_PREFIX, + sizeof(SESS_TICKET_KEY_NAME_PREFIX)); + /* This function calls ssl_GetSessionTicketKeyPair(), which initializes the + * key pair stuff. That allows this to use the same shutdown function. */ + rv = ssl_GenerateSessionTicketKeys(arg, ssl_session_ticket_keys.keyName, + &ssl_session_ticket_keys.encKey, + &ssl_session_ticket_keys.macKey); + if (rv != SECSuccess) { + return PR_FAILURE; + } + + return PR_SUCCESS; +} + +SECStatus +ssl_GetSessionTicketKeys(sslSocket *ss, unsigned char *keyName, + PK11SymKey **encKey, PK11SymKey **macKey) +{ + if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_session_ticket_keys.setup, + &ssl_GenerateSessionTicketKeysOnce, + ss->pkcs11PinArg)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + if (!ssl_session_ticket_keys.encKey || !ssl_session_ticket_keys.macKey) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + PORT_Memcpy(keyName, ssl_session_ticket_keys.keyName, + sizeof(ssl_session_ticket_keys.keyName)); + *encKey = ssl_session_ticket_keys.encKey; + *macKey = ssl_session_ticket_keys.macKey; + return SECSuccess; +} + +/* If lockTime is zero, it implies that the lock is not held, and must be + * aquired here. + */ +static SECStatus +getSvrWrappingKey(unsigned int symWrapMechIndex, + unsigned int wrapKeyIndex, SSLWrappedSymWrappingKey *wswk, cacheDesc *cache, PRUint32 lockTime) { - PRUint32 ndx = (authType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex; + PRUint32 ndx = (wrapKeyIndex * SSL_NUM_WRAP_MECHS) + symWrapMechIndex; SSLWrappedSymWrappingKey *pwswk = cache->keyCacheData + ndx; PRUint32 now = 0; - PRBool rv = PR_FALSE; + PRBool rv = SECFailure; if (!cache->cacheMem) { /* cache is uninitialized */ PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED); - return rv; + return SECFailure; } if (!lockTime) { - lockTime = now = LockSidCacheLock(cache->keyCacheLock, now); - if (!lockTime) { - return rv; + now = LockSidCacheLock(cache->keyCacheLock, 0); + if (!now) { + return SECFailure; } } - if (pwswk->authType == authType && - pwswk->symWrapMechIndex == symWrapMechIndex && + if (pwswk->wrapKeyIndex == wrapKeyIndex && + pwswk->wrapMechIndex == symWrapMechIndex && pwswk->wrappedSymKeyLen != 0) { *wswk = *pwswk; - rv = PR_TRUE; + rv = SECSuccess; } if (now) { UnlockSidCacheLock(cache->keyCacheLock); @@ -1645,28 +1856,25 @@ getSvrWrappingKey(PRInt32 symWrapMechIndex, return rv; } -PRBool -ssl_GetWrappingKey(PRInt32 symWrapMechIndex, - SSLAuthType authType, +SECStatus +ssl_GetWrappingKey(unsigned int wrapMechIndex, + unsigned int wrapKeyIndex, SSLWrappedSymWrappingKey *wswk) { - PRBool rv; - - PORT_Assert((unsigned)authType < ssl_auth_size); - PORT_Assert((unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS); - if ((unsigned)authType < ssl_auth_size && - (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) { - rv = getSvrWrappingKey(symWrapMechIndex, authType, wswk, - &globalCache, 0); - } else { - rv = PR_FALSE; + PORT_Assert(wrapMechIndex < SSL_NUM_WRAP_MECHS); + PORT_Assert(wrapKeyIndex < SSL_NUM_WRAP_KEYS); + if (wrapMechIndex >= SSL_NUM_WRAP_MECHS || + wrapKeyIndex >= SSL_NUM_WRAP_KEYS) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } - return rv; + return getSvrWrappingKey(wrapMechIndex, wrapKeyIndex, wswk, + &globalCache, 0); } /* Wrap and cache a session ticket key. */ -static PRBool +static SECStatus WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey, const char *keyName, encKeyCacheEntry *cacheEntry) { @@ -1682,13 +1890,13 @@ WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey, SECSuccess) { SSL_DBG(("%d: SSL[%s]: Unable to wrap session ticket %s.", SSL_GETPID(), "unknown", keyName)); - return PR_FALSE; + return SECFailure; } cacheEntry->length = wrappedKey.len; - return PR_TRUE; + return SECSuccess; } -static PRBool +static SECStatus GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, PK11SymKey **macKey) { @@ -1712,7 +1920,7 @@ GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, SECSuccess) { SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.", SSL_GETPID(), "unknown")); - goto loser; + return SECFailure; } mechanismArray[0] = CKM_AES_CBC; @@ -1735,17 +1943,17 @@ GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN); *aesKey = aesKeyTmp; *macKey = macKeyTmp; - return PR_TRUE; + return SECSuccess; loser: if (aesKeyTmp) PK11_FreeSymKey(aesKeyTmp); if (macKeyTmp) PK11_FreeSymKey(macKeyTmp); - return PR_FALSE; + return SECFailure; } -static PRBool +static SECStatus GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, unsigned char *keyName, PK11SymKey **aesKey, PK11SymKey **macKey) @@ -1753,31 +1961,35 @@ GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg, PK11SymKey *aesKeyTmp = NULL; PK11SymKey *macKeyTmp = NULL; cacheDesc *cache = &globalCache; + SECStatus rv; - if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) { - goto loser; + rv = GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp); + if (rv != SECSuccess) { + return SECFailure; } if (cache->cacheMem) { /* Export the keys to the shared cache in wrapped form. */ - if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey)) + rv = WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey); + if (rv != SECSuccess) { goto loser; - if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey)) + } + rv = WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey); + if (rv != SECSuccess) { goto loser; + } } *aesKey = aesKeyTmp; *macKey = macKeyTmp; - return PR_TRUE; + return SECSuccess; loser: - if (aesKeyTmp) - PK11_FreeSymKey(aesKeyTmp); - if (macKeyTmp) - PK11_FreeSymKey(macKeyTmp); - return PR_FALSE; + PK11_FreeSymKey(aesKeyTmp); + PK11_FreeSymKey(macKeyTmp); + return SECFailure; } -static PRBool +static SECStatus UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName, PK11SymKey **aesKey, PK11SymKey **macKey) { @@ -1810,52 +2022,48 @@ UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName, SESS_TICKET_KEY_VAR_NAME_LEN); *aesKey = aesKeyTmp; *macKey = macKeyTmp; - return PR_TRUE; + return SECSuccess; loser: if (aesKeyTmp) PK11_FreeSymKey(aesKeyTmp); if (macKeyTmp) PK11_FreeSymKey(macKeyTmp); - return PR_FALSE; + return SECFailure; } -PRBool -ssl_GetSessionTicketKeys(SECKEYPrivateKey *svrPrivKey, - SECKEYPublicKey *svrPubKey, void *pwArg, - unsigned char *keyName, PK11SymKey **aesKey, - PK11SymKey **macKey) +static SECStatus +ssl_GenerateSessionTicketKeys(void *pwArg, unsigned char *keyName, + PK11SymKey **encKey, PK11SymKey **macKey) { - PRUint32 now = 0; - PRBool rv = PR_FALSE; - PRBool keysGenerated = PR_FALSE; + SECKEYPrivateKey *svrPrivKey; + SECKEYPublicKey *svrPubKey; + PRUint32 now; + SECStatus rv; cacheDesc *cache = &globalCache; - if (!cache->cacheMem) { - /* cache is uninitialized. Generate keys and return them - * without caching. */ - return GenerateTicketKeys(pwArg, keyName, aesKey, macKey); + rv = ssl_GetSessionTicketKeyPair(&svrPubKey, &svrPrivKey); + if (rv != SECSuccess || !cache->cacheMem) { + /* No key pair for wrapping, or the cache is uninitialized. Generate + * keys and return them without caching. */ + return GenerateTicketKeys(pwArg, keyName, encKey, macKey); } - now = LockSidCacheLock(cache->keyCacheLock, now); + now = LockSidCacheLock(cache->keyCacheLock, 0); if (!now) - return rv; + return SECFailure; - if (!*(cache->ticketKeysValid)) { + if (*(cache->ticketKeysValid)) { + rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, encKey, macKey); + } else { /* Keys do not exist, create them. */ - if (!GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName, - aesKey, macKey)) - goto loser; - keysGenerated = PR_TRUE; - *(cache->ticketKeysValid) = 1; + rv = GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName, + encKey, macKey); + if (rv == SECSuccess) { + *(cache->ticketKeysValid) = 1; + } } - - rv = PR_TRUE; - -loser: UnlockSidCacheLock(cache->keyCacheLock); - if (rv && !keysGenerated) - rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey); return rv; } @@ -1868,47 +2076,45 @@ loser: * This is all done while holding the locks/mutexes necessary to make * the operation atomic. */ -PRBool +SECStatus ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk) { cacheDesc *cache = &globalCache; - PRBool rv = PR_FALSE; - SSLAuthType authType = wswk->authType; - /* type of keys used to wrap SymWrapKey*/ - PRInt32 symWrapMechIndex = wswk->symWrapMechIndex; + PRBool rv = SECFailure; PRUint32 ndx; - PRUint32 now = 0; + PRUint32 now; SSLWrappedSymWrappingKey myWswk; if (!cache->cacheMem) { /* cache is uninitialized */ PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED); - return 0; + return SECFailure; } - PORT_Assert((unsigned)authType < ssl_auth_size); - if ((unsigned)authType >= ssl_auth_size) - return 0; - - PORT_Assert((unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS); - if ((unsigned)symWrapMechIndex >= SSL_NUM_WRAP_MECHS) - return 0; + PORT_Assert(wswk->wrapMechIndex < SSL_NUM_WRAP_MECHS); + PORT_Assert(wswk->wrapKeyIndex < SSL_NUM_WRAP_KEYS); + if (wswk->wrapMechIndex >= SSL_NUM_WRAP_MECHS || + wswk->wrapKeyIndex >= SSL_NUM_WRAP_KEYS) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } - ndx = (authType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex; + ndx = (wswk->wrapKeyIndex * SSL_NUM_WRAP_MECHS) + wswk->wrapMechIndex; PORT_Memset(&myWswk, 0, sizeof myWswk); /* eliminate UMRs. */ - now = LockSidCacheLock(cache->keyCacheLock, now); - if (now) { - rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->authType, - &myWswk, cache, now); - if (rv) { - /* we found it on disk, copy it out to the caller. */ - PORT_Memcpy(wswk, &myWswk, sizeof *wswk); - } else { - /* Wasn't on disk, and we're still holding the lock, so write it. */ - cache->keyCacheData[ndx] = *wswk; - } - UnlockSidCacheLock(cache->keyCacheLock); + now = LockSidCacheLock(cache->keyCacheLock, 0); + if (!now) { + return SECFailure; + } + rv = getSvrWrappingKey(wswk->wrapMechIndex, wswk->wrapKeyIndex, + &myWswk, cache, now); + if (rv == SECSuccess) { + /* we found it on disk, copy it out to the caller. */ + PORT_Memcpy(wswk, &myWswk, sizeof *wswk); + } else { + /* Wasn't on disk, and we're still holding the lock, so write it. */ + cache->keyCacheData[ndx] = *wswk; } + UnlockSidCacheLock(cache->keyCacheLock); return rv; } @@ -1946,14 +2152,13 @@ SSL_InheritMPServerSIDCache(const char *envString) return SECFailure; } -PRBool -ssl_GetWrappingKey(PRInt32 symWrapMechIndex, - SSLAuthType authType, +SECStatus +ssl_GetWrappingKey(unsigned int wrapMechIndex, + unsigned int wrapKeyIndex, SSLWrappedSymWrappingKey *wswk) { - PRBool rv = PR_FALSE; PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrappingKey)"); - return rv; + return SECFailure; } /* This is a kind of test-and-set. The caller passes in the new value it wants @@ -1965,12 +2170,11 @@ ssl_GetWrappingKey(PRInt32 symWrapMechIndex, * This is all done while holding the locks/mutexes necessary to make * the operation atomic. */ -PRBool +SECStatus ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk) { - PRBool rv = PR_FALSE; PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrappingKey)"); - return rv; + return SECFailure; } PRUint32 diff --git a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c index 626f4a9..99828c8 100644 --- a/nss/lib/ssl/sslsock.c +++ b/nss/lib/ssl/sslsock.c @@ -330,6 +330,10 @@ ssl_DupSocket(sslSocket *os) ss->getClientAuthDataArg = os->getClientAuthDataArg; ss->sniSocketConfig = os->sniSocketConfig; ss->sniSocketConfigArg = os->sniSocketConfigArg; + ss->alertReceivedCallback = os->alertReceivedCallback; + ss->alertReceivedCallbackArg = os->alertReceivedCallbackArg; + ss->alertSentCallback = os->alertSentCallback; + ss->alertSentCallbackArg = os->alertSentCallbackArg; ss->handleBadCert = os->handleBadCert; ss->badCertArg = os->badCertArg; ss->handshakeCallback = os->handshakeCallback; @@ -2148,6 +2152,14 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) ss->sniSocketConfig = sm->sniSocketConfig; if (sm->sniSocketConfigArg) ss->sniSocketConfigArg = sm->sniSocketConfigArg; + if (sm->alertReceivedCallback) { + ss->alertReceivedCallback = sm->alertReceivedCallback; + ss->alertReceivedCallbackArg = sm->alertReceivedCallbackArg; + } + if (sm->alertSentCallback) { + ss->alertSentCallback = sm->alertSentCallback; + ss->alertSentCallbackArg = sm->alertSentCallbackArg; + } if (sm->handleBadCert) ss->handleBadCert = sm->handleBadCert; if (sm->badCertArg) @@ -2161,61 +2173,82 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) return fd; } -/* - * Get the user supplied range - */ -static SECStatus -ssl3_GetRangePolicy(SSLProtocolVariant protocolVariant, SSLVersionRange *prange) +SECStatus +ssl3_GetEffectiveVersionPolicy(SSLProtocolVariant variant, + SSLVersionRange *effectivePolicy) { SECStatus rv; - PRUint32 policy; - PRInt32 option; + PRUint32 policyFlag; + PRInt32 minPolicy, maxPolicy; - /* only use policy constraints if we've set the apply ssl policy bit */ - rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policy); - if ((rv != SECSuccess) || !(policy & NSS_USE_POLICY_IN_SSL)) { - return SECFailure; + if (variant == ssl_variant_stream) { + effectivePolicy->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM; + effectivePolicy->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED; + } else { + effectivePolicy->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM; + effectivePolicy->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED; } - rv = NSS_OptionGet(VERSIONS_POLICY_MIN(protocolVariant), &option); + + rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policyFlag); + if ((rv != SECSuccess) || !(policyFlag & NSS_USE_POLICY_IN_SSL)) { + /* Policy is not active, report library extents. */ + return SECSuccess; + } + + rv = NSS_OptionGet(VERSIONS_POLICY_MIN(variant), &minPolicy); if (rv != SECSuccess) { - return rv; + return SECFailure; } - prange->min = (PRUint16)option; - rv = NSS_OptionGet(VERSIONS_POLICY_MAX(protocolVariant), &option); + rv = NSS_OptionGet(VERSIONS_POLICY_MAX(variant), &maxPolicy); if (rv != SECSuccess) { - return rv; + return SECFailure; } - prange->max = (PRUint16)option; - if (prange->max < prange->min) { - return SECFailure; /* don't accept an invalid policy */ + + if (minPolicy > effectivePolicy->max || + maxPolicy < effectivePolicy->min || + minPolicy > maxPolicy) { + return SECFailure; } + effectivePolicy->min = PR_MAX(effectivePolicy->min, minPolicy); + effectivePolicy->max = PR_MIN(effectivePolicy->max, maxPolicy); return SECSuccess; } -/* - * Constrain a single protocol variant's range based on the user policy +/* + * Assumes that rangeParam values are within the supported boundaries, + * but should contain all potentially allowed versions, even if they contain + * conflicting versions. + * Will return the overlap, or a NONE range if system policy is invalid. */ static SECStatus -ssl3_ConstrainVariantRangeByPolicy(SSLProtocolVariant protocolVariant) +ssl3_CreateOverlapWithPolicy(SSLProtocolVariant protocolVariant, + SSLVersionRange *input, + SSLVersionRange *overlap) { - SSLVersionRange vrange; - SSLVersionRange pvrange; SECStatus rv; + SSLVersionRange effectivePolicyBoundary; + SSLVersionRange vrange; - vrange = *VERSIONS_DEFAULTS(protocolVariant); - rv = ssl3_GetRangePolicy(protocolVariant, &pvrange); - if (rv != SECSuccess) { - return SECSuccess; /* we don't have any policy */ + PORT_Assert(input != NULL); + + rv = ssl3_GetEffectiveVersionPolicy(protocolVariant, + &effectivePolicyBoundary); + if (rv == SECFailure) { + /* SECFailure means internal failure or invalid configuration. */ + overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE; + return SECFailure; } - vrange.min = PR_MAX(vrange.min, pvrange.min); - vrange.max = PR_MIN(vrange.max, pvrange.max); - if (vrange.max >= vrange.min) { - *VERSIONS_DEFAULTS(protocolVariant) = vrange; - } else { + + vrange.min = PR_MAX(input->min, effectivePolicyBoundary.min); + vrange.max = PR_MIN(input->max, effectivePolicyBoundary.max); + + if (vrange.max < vrange.min) { /* there was no overlap, turn off range altogether */ - pvrange.min = pvrange.max = SSL_LIBRARY_VERSION_NONE; - *VERSIONS_DEFAULTS(protocolVariant) = pvrange; + overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE; + return SECFailure; } + + *overlap = vrange; return SECSuccess; } @@ -2223,16 +2256,17 @@ static PRBool ssl_VersionIsSupportedByPolicy(SSLProtocolVariant protocolVariant, SSL3ProtocolVersion version) { - SSLVersionRange pvrange; SECStatus rv; + SSLVersionRange effectivePolicyBoundary; - rv = ssl3_GetRangePolicy(protocolVariant, &pvrange); - if (rv == SECSuccess) { - if ((version > pvrange.max) || (version < pvrange.min)) { - return PR_FALSE; /* disallowed by policy */ - } + rv = ssl3_GetEffectiveVersionPolicy(protocolVariant, + &effectivePolicyBoundary); + if (rv == SECFailure) { + /* SECFailure means internal failure or invalid configuration. */ + return PR_FALSE; } - return PR_TRUE; + return version >= effectivePolicyBoundary.min && + version <= effectivePolicyBoundary.max; } /* @@ -2242,52 +2276,44 @@ ssl_VersionIsSupportedByPolicy(SSLProtocolVariant protocolVariant, SECStatus ssl3_ConstrainRangeByPolicy(void) { - SECStatus rv; - rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_stream); - if (rv != SECSuccess) { - return rv; - } - rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_datagram); - if (rv != SECSuccess) { - return rv; - } + /* We ignore failures in ssl3_CreateOverlapWithPolicy. Although an empty + * overlap disables all connectivity, it's an allowed state. + */ + ssl3_CreateOverlapWithPolicy(ssl_variant_stream, + VERSIONS_DEFAULTS(ssl_variant_stream), + VERSIONS_DEFAULTS(ssl_variant_stream)); + ssl3_CreateOverlapWithPolicy(ssl_variant_datagram, + VERSIONS_DEFAULTS(ssl_variant_datagram), + VERSIONS_DEFAULTS(ssl_variant_datagram)); return SECSuccess; } PRBool -ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant, - SSL3ProtocolVersion version) +ssl3_VersionIsSupportedByCode(SSLProtocolVariant protocolVariant, + SSL3ProtocolVersion version) { - if (!ssl_VersionIsSupportedByPolicy(protocolVariant, version)) { - return PR_FALSE; - } switch (protocolVariant) { case ssl_variant_stream: - return (version >= SSL_LIBRARY_VERSION_3_0 && + return (version >= SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM && version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED); case ssl_variant_datagram: - return (version >= SSL_LIBRARY_VERSION_TLS_1_1 && + return (version >= SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM && version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED); - default: - /* Can't get here */ - PORT_Assert(PR_FALSE); - return PR_FALSE; } + + /* Can't get here */ + PORT_Assert(PR_FALSE); + return PR_FALSE; } -/* Returns PR_TRUE if the given version range is valid and -** fully supported; otherwise, returns PR_FALSE. -*/ -static PRBool -ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant, - const SSLVersionRange *vrange) +PRBool +ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant, + SSL3ProtocolVersion version) { - return vrange && - vrange->min <= vrange->max && - ssl3_VersionIsSupported(protocolVariant, vrange->min) && - ssl3_VersionIsSupported(protocolVariant, vrange->max) && - (vrange->min > SSL_LIBRARY_VERSION_3_0 || - vrange->max < SSL_LIBRARY_VERSION_TLS_1_3); + if (!ssl_VersionIsSupportedByPolicy(protocolVariant, version)) { + return PR_FALSE; + } + return ssl3_VersionIsSupportedByCode(protocolVariant, version); } const SECItem * @@ -2313,6 +2339,8 @@ SECStatus SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant, SSLVersionRange *vrange) { + SECStatus rv; + if (!vrange) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; @@ -2320,15 +2348,15 @@ SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant, switch (protocolVariant) { case ssl_variant_stream: - vrange->min = SSL_LIBRARY_VERSION_3_0; + vrange->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM; vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED; - // We don't allow SSLv3 and TLSv1.3 together. - if (vrange->max == SSL_LIBRARY_VERSION_TLS_1_3) { - vrange->min = SSL_LIBRARY_VERSION_TLS_1_0; - } + /* We don't allow SSLv3 and TLSv1.3 together. + * However, don't check yet, apply the policy first. + * Because if the effective supported range doesn't use TLS 1.3, + * then we don't need to increase the minimum. */ break; case ssl_variant_datagram: - vrange->min = SSL_LIBRARY_VERSION_TLS_1_1; + vrange->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM; vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED; break; default: @@ -2336,6 +2364,17 @@ SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant, return SECFailure; } + rv = ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange); + if (rv != SECSuccess) { + /* Library default and policy don't overlap. */ + return rv; + } + + /* We don't allow SSLv3 and TLSv1.3 together */ + if (vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3) { + vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0); + } + return SECSuccess; } @@ -2351,6 +2390,43 @@ SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant, } *vrange = *VERSIONS_DEFAULTS(protocolVariant); + return ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange); +} + +static PRBool +ssl3_HasConflictingSSLVersions(const SSLVersionRange *vrange) +{ + return (vrange->min <= SSL_LIBRARY_VERSION_3_0 && + vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3); +} + +static SECStatus +ssl3_CheckRangeValidAndConstrainByPolicy(SSLProtocolVariant protocolVariant, + SSLVersionRange *vrange) +{ + SECStatus rv; + + if (vrange->min > vrange->max || + !ssl3_VersionIsSupportedByCode(protocolVariant, vrange->min) || + !ssl3_VersionIsSupportedByCode(protocolVariant, vrange->max) || + ssl3_HasConflictingSSLVersions(vrange)) { + PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE); + return SECFailure; + } + + /* Try to adjust the received range using our policy. + * If there's overlap, we'll use the (possibly reduced) range. + * If there isn't overlap, it's failure. */ + + rv = ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange); + if (rv != SECSuccess) { + return rv; + } + + /* We don't allow SSLv3 and TLSv1.3 together */ + if (vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3) { + vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0); + } return SECSuccess; } @@ -2359,13 +2435,21 @@ SECStatus SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant, const SSLVersionRange *vrange) { - if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) { - PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE); + SSLVersionRange constrainedRange; + SECStatus rv; + + if (!vrange) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - *VERSIONS_DEFAULTS(protocolVariant) = *vrange; + constrainedRange = *vrange; + rv = ssl3_CheckRangeValidAndConstrainByPolicy(protocolVariant, + &constrainedRange); + if (rv != SECSuccess) + return rv; + *VERSIONS_DEFAULTS(protocolVariant) = constrainedRange; return SECSuccess; } @@ -2393,24 +2477,33 @@ SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange) ssl_ReleaseSSL3HandshakeLock(ss); ssl_Release1stHandshakeLock(ss); - return SECSuccess; + return ssl3_CreateOverlapWithPolicy(ss->protocolVariant, vrange, vrange); } SECStatus SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange) { - sslSocket *ss = ssl_FindSocket(fd); + SSLVersionRange constrainedRange; + sslSocket *ss; + SECStatus rv; + if (!vrange) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + ss = ssl_FindSocket(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in SSL_VersionRangeSet", SSL_GETPID(), fd)); return SECFailure; } - if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) { - PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE); - return SECFailure; - } + constrainedRange = *vrange; + rv = ssl3_CheckRangeValidAndConstrainByPolicy(ss->protocolVariant, + &constrainedRange); + if (rv != SECSuccess) + return rv; ssl_Get1stHandshakeLock(ss); ssl_GetSSL3HandshakeLock(ss); @@ -2423,7 +2516,7 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange) return SECFailure; } - ss->vrange = *vrange; + ss->vrange = constrainedRange; ssl_ReleaseSSL3HandshakeLock(ss); ssl_Release1stHandshakeLock(ss); @@ -3672,7 +3765,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) ss->opt.noLocks = !makeLocks; ss->vrange = *VERSIONS_DEFAULTS(protocolVariant); ss->protocolVariant = protocolVariant; - + /* Ignore overlap failures, because returning NULL would trigger assertion + * failures elsewhere. We don't want this scenario to be fatal, it's just + * a state where no SSL connectivity is possible. */ + ssl3_CreateOverlapWithPolicy(ss->protocolVariant, &ss->vrange, &ss->vrange); ss->peerID = NULL; ss->rTimeout = PR_INTERVAL_NO_TIMEOUT; ss->wTimeout = PR_INTERVAL_NO_TIMEOUT; @@ -3690,6 +3786,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) ss->sniSocketConfig = NULL; ss->sniSocketConfigArg = NULL; ss->getClientAuthData = NULL; + ss->alertReceivedCallback = NULL; + ss->alertReceivedCallbackArg = NULL; + ss->alertSentCallback = NULL; + ss->alertSentCallbackArg = NULL; ss->handleBadCert = NULL; ss->badCertArg = NULL; ss->pkcs11PinArg = NULL; @@ -3704,6 +3804,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight); PR_INIT_CLIST(&ss->ssl3.hs.cipherSpecs); PR_INIT_CLIST(&ss->ssl3.hs.bufferedEarlyData); + ssl3_InitExtensionData(&ss->xtnData); if (makeLocks) { rv = ssl_MakeLocks(ss); if (rv != SECSuccess) @@ -3715,7 +3816,6 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant) rv = ssl3_InitGather(&ss->gs); if (rv != SECSuccess) goto loser; - ssl3_InitExtensionData(&ss->xtnData); return ss; loser: diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h index 506b78d..bd9a2ae 100644 --- a/nss/lib/ssl/sslt.h +++ b/nss/lib/ssl/sslt.h @@ -298,6 +298,21 @@ typedef struct SSLPreliminaryChannelInfoStr { /* Cipher suite: test (valuesSet & ssl_preinfo_cipher_suite) */ PRUint16 cipherSuite; + /* The following fields were added in NSS 3.29. */ + /* |canSendEarlyData| is true when a 0-RTT is enabled. This can only be + * true after sending the ClientHello and before the handshake completes. + */ + PRBool canSendEarlyData; + + /* The following fields were added in NSS 3.31. */ + /* The number of early data octets that a client is permitted to send on + * this connection. The value will be zero if the connection was not + * resumed or early data is not permitted. For a client, this value only + * has meaning if |canSendEarlyData| is true. For a server, this indicates + * the value that was advertised in the session ticket that was used to + * resume this session. */ + PRUint32 maxEarlyDataSize; + /* When adding new fields to this structure, please document the * NSS version in which they were added. */ } SSLPreliminaryChannelInfo; @@ -395,11 +410,10 @@ typedef enum { /* This is the old name for the supported_groups extensions. */ #define ssl_elliptic_curves_xtn ssl_supported_groups_xtn -/* SSL_MAX_EXTENSIONS doesn't include ssl_padding_xtn. It includes the maximum - * number of extensions that are supported for any single message type. That - * is, a ClientHello; ServerHello and TLS 1.3 NewSessionTicket and - * HelloRetryRequest extensions are smaller. */ -#define SSL_MAX_EXTENSIONS 19 +/* SSL_MAX_EXTENSIONS includes the maximum number of extensions that are + * supported for any single message type. That is, a ClientHello; ServerHello + * and TLS 1.3 NewSessionTicket and HelloRetryRequest extensions have fewer. */ +#define SSL_MAX_EXTENSIONS 20 /* Deprecated */ typedef enum { diff --git a/nss/lib/ssl/tls13con.c b/nss/lib/ssl/tls13con.c index 68a2a2c..37b7e81 100644 --- a/nss/lib/ssl/tls13con.c +++ b/nss/lib/ssl/tls13con.c @@ -22,9 +22,10 @@ #include "tls13exthandle.h" typedef enum { - TrafficKeyEarlyApplicationData, - TrafficKeyHandshake, - TrafficKeyApplicationData + TrafficKeyClearText = 0, + TrafficKeyEarlyApplicationData = 1, + TrafficKeyHandshake = 2, + TrafficKeyApplicationData = 3 } TrafficKeyType; typedef enum { @@ -76,7 +77,6 @@ tls13_DeriveSecret(sslSocket *ss, PK11SymKey *key, const char *suffix, const SSL3Hashes *hashes, PK11SymKey **dest); -static void tls13_SetNullCipherSpec(sslSocket *ss, ssl3CipherSpec **specp); static SECStatus tls13_SendEndOfEarlyData(sslSocket *ss); static SECStatus tls13_SendFinished(sslSocket *ss, PK11SymKey *baseKey); static SECStatus tls13_ComputePskBinderHash(sslSocket *ss, @@ -132,7 +132,7 @@ const SSL3ProtocolVersion kDtlsRecordVersion = SSL_LIBRARY_VERSION_TLS_1_1; PR_STATIC_ASSERT(SSL_LIBRARY_VERSION_MAX_SUPPORTED <= SSL_LIBRARY_VERSION_TLS_1_3); -/* Use this instead of FATAL_ERROR when an alert isn't possible. */ +/* Use this instead of FATAL_ERROR when no alert shall be sent. */ #define LOG_ERROR(ss, prError) \ do { \ SSL_TRC(3, ("%d: TLS13[%d]: fatal error %d in %s (%s:%d)", \ @@ -163,15 +163,21 @@ static char * tls13_HandshakeState(SSL3WaitState st) { switch (st) { + STATE_CASE(idle_handshake); STATE_CASE(wait_client_hello); STATE_CASE(wait_client_cert); + STATE_CASE(wait_client_key); STATE_CASE(wait_cert_verify); + STATE_CASE(wait_change_cipher); STATE_CASE(wait_finished); STATE_CASE(wait_server_hello); + STATE_CASE(wait_certificate_status); STATE_CASE(wait_server_cert); + STATE_CASE(wait_server_key); STATE_CASE(wait_cert_request); + STATE_CASE(wait_hello_done); + STATE_CASE(wait_new_session_ticket); STATE_CASE(wait_encrypted_extensions); - STATE_CASE(idle_handshake); default: break; } @@ -426,10 +432,7 @@ tls13_SetupClientHello(sslSocket *ss) session_ticket = &sid->u.ssl3.locked.sessionTicket; PORT_Assert(session_ticket && session_ticket->ticket.data); - if (session_ticket->ticket_lifetime_hint == 0 || - (session_ticket->ticket_lifetime_hint + - session_ticket->received_timestamp > - ssl_Time())) { + if (ssl_TicketTimeValid(session_ticket)) { ss->statelessResume = PR_TRUE; } @@ -625,13 +628,9 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid) hashType = tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite); /* If we are the server, we compute the wrapping key, but if we - * are the client, it's coordinates are stored with the ticket. */ + * are the client, its coordinates are stored with the ticket. */ if (ss->sec.isServer) { - const sslServerCert *serverCert; - - serverCert = ssl_FindServerCert(ss, &sid->certType); - PORT_Assert(serverCert); - wrapKey = ssl3_GetWrappingKey(ss, NULL, serverCert, + wrapKey = ssl3_GetWrappingKey(ss, NULL, sid->u.ssl3.masterWrapMech, ss->pkcs11PinArg); } else { @@ -934,7 +933,7 @@ tls13_CanResume(sslSocket *ss, const sslSessionID *sid) * do remember the type of certificate we originally used, so we can locate * it again, provided that the current ssl socket has had its server certs * configured the same as the previous one. */ - sc = ssl_FindServerCert(ss, &sid->certType); + sc = ssl_FindServerCert(ss, sid->authType, sid->namedCurve); if (!sc || !sc->serverCert) { return PR_FALSE; } @@ -943,27 +942,6 @@ tls13_CanResume(sslSocket *ss, const sslSessionID *sid) } static PRBool -tls13_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag) -{ - const unsigned char *data = ss->opt.nextProtoNego.data; - unsigned int length = ss->opt.nextProtoNego.len; - unsigned int offset = 0; - - if (!tag->len) - return PR_TRUE; - - while (offset < length) { - unsigned int taglen = (unsigned int)data[offset]; - if ((taglen == tag->len) && - !PORT_Memcmp(data + offset + 1, tag->data, tag->len)) - return PR_TRUE; - offset += 1 + taglen; - } - - return PR_FALSE; -} - -static PRBool tls13_CanNegotiateZeroRtt(sslSocket *ss, const sslSessionID *sid) { PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent); @@ -1158,6 +1136,30 @@ tls13_NegotiateKeyExchange(sslSocket *ss, TLS13KeyShareEntry **clientShare) return SECSuccess; } +SSLAuthType +ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme) +{ + switch (scheme) { + case ssl_sig_rsa_pkcs1_sha1: + case ssl_sig_rsa_pkcs1_sha256: + case ssl_sig_rsa_pkcs1_sha384: + case ssl_sig_rsa_pkcs1_sha512: + /* We report PSS signatures as being just RSA signatures. */ + case ssl_sig_rsa_pss_sha256: + case ssl_sig_rsa_pss_sha384: + case ssl_sig_rsa_pss_sha512: + return ssl_auth_rsa_sign; + case ssl_sig_ecdsa_secp256r1_sha256: + case ssl_sig_ecdsa_secp384r1_sha384: + case ssl_sig_ecdsa_secp521r1_sha512: + case ssl_sig_ecdsa_sha1: + return ssl_auth_ecdsa; + default: + PORT_Assert(0); + } + return ssl_auth_null; +} + SECStatus tls13_SelectServerCert(sslSocket *ss) { @@ -1181,8 +1183,7 @@ tls13_SelectServerCert(sslSocket *ss) cursor = PR_NEXT_LINK(cursor)) { sslServerCert *cert = (sslServerCert *)cursor; - if (cert->certType.authType == ssl_auth_rsa_pss || - cert->certType.authType == ssl_auth_rsa_decrypt) { + if (SSL_CERT_IS_ONLY(cert, ssl_auth_rsa_decrypt)) { continue; } @@ -1195,8 +1196,8 @@ tls13_SelectServerCert(sslSocket *ss) if (rv == SECSuccess) { /* Found one. */ ss->sec.serverCert = cert; - ss->sec.authType = cert->certType.authType; - ss->ssl3.hs.kea_def_mutable.authKeyType = cert->certType.authType; + ss->sec.authType = ss->ssl3.hs.kea_def_mutable.authKeyType = + ssl_SignatureSchemeToAuthType(ss->ssl3.hs.signatureScheme); ss->sec.authKeyBits = cert->serverKeyBits; return SECSuccess; } @@ -1227,8 +1228,6 @@ tls13_NegotiateAuthentication(sslSocket *ss) if (rv != SECSuccess) { return SECFailure; } - ss->ssl3.hs.kea_def_mutable.authKeyType = - ss->sec.serverCert->certType.authType; return SECSuccess; } @@ -1248,16 +1247,6 @@ tls13_HandleClientHelloPart2(sslSocket *ss, if (ssl3_ExtensionNegotiated(ss, ssl_tls13_early_data_xtn)) { ss->ssl3.hs.zeroRttState = ssl_0rtt_sent; - - if (IS_DTLS(ss)) { - /* Save the null spec, which we should be currently reading. We will - * use this when 0-RTT sending is over. */ - ssl_GetSpecReadLock(ss); - ss->ssl3.hs.nullSpec = ss->ssl3.crSpec; - tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec); - PORT_Assert(ss->ssl3.hs.nullSpec->cipher_def->cipher == cipher_null); - ssl_ReleaseSpecReadLock(ss); - } } #ifndef PARANOID @@ -1340,6 +1329,10 @@ tls13_HandleClientHelloPart2(sslSocket *ss, goto loser; } + ss->sec.serverCert = ssl_FindServerCert(ss, sid->authType, + sid->namedCurve); + PORT_Assert(ss->sec.serverCert); + rv = tls13_RecoverWrappedSharedSecret(ss, sid); if (rv != SECSuccess) { SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok); @@ -1348,12 +1341,11 @@ tls13_HandleClientHelloPart2(sslSocket *ss, } tls13_RestoreCipherInfo(ss, sid); - ss->sec.serverCert = ssl_FindServerCert(ss, &sid->certType); - PORT_Assert(ss->sec.serverCert); ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert); if (sid->peerCert != NULL) { ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); } + ssl3_RegisterExtensionSender( ss, &ss->xtnData, ssl_tls13_pre_shared_key_xtn, tls13_ServerSendPreSharedKeyXtn); @@ -1614,9 +1606,9 @@ static SECStatus tls13_SendCertificateRequest(sslSocket *ss) { SECStatus rv; - int calen; + unsigned int calen; SECItem *names; - int nnames; + unsigned int nnames; SECItem *name; int i; PRUint8 sigSchemes[MAX_SIGNATURE_SCHEMES * 2]; @@ -1632,7 +1624,10 @@ tls13_SendCertificateRequest(sslSocket *ss) return rv; } - ssl3_GetCertificateRequestCAs(ss, &calen, &names, &nnames); + rv = ssl_GetCertificateRequestCAs(ss, &calen, &names, &nnames); + if (rv != SECSuccess) { + return rv; + } length = 1 + 0 /* length byte for empty request context */ + 2 + sigSchemesLength + 2 + calen + 2; @@ -1670,7 +1665,7 @@ SECStatus tls13_HandleHelloRetryRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { SECStatus rv; - PRInt32 tmp; + PRUint32 tmp; SSL3ProtocolVersion version; SSL_TRC(3, ("%d: TLS13[%d]: handle hello retry request", @@ -1700,9 +1695,13 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) { - /* Oh well, back to the start. */ - tls13_SetNullCipherSpec(ss, &ss->ssl3.cwSpec); ss->ssl3.hs.zeroRttState = ssl_0rtt_ignored; + /* Restore the null cipher spec for writing. */ + ssl_GetSpecWriteLock(ss); + tls13_CipherSpecRelease(ss->ssl3.cwSpec); + ss->ssl3.cwSpec = ss->ssl3.crSpec; + PORT_Assert(ss->ssl3.cwSpec->cipher_def->cipher == cipher_null); + ssl_ReleaseSpecWriteLock(ss); } else { PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none); } @@ -1719,8 +1718,8 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } /* Extensions. */ - tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); - if (tmp < 0) { + rv = ssl3_ConsumeHandshakeNumber(ss, &tmp, 2, &b, &length); + if (rv != SECSuccess) { return SECFailure; /* error code already set */ } /* Extensions must be non-empty and use the remainder of the message. @@ -1758,7 +1757,7 @@ tls13_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) TLS13CertificateRequest *certRequest = NULL; SECItem context = { siBuffer, NULL, 0 }; PLArenaPool *arena; - PRInt32 extensionsLength; + SECItem extensionsData = { siBuffer, NULL, 0 }; SSL_TRC(3, ("%d: TLS13[%d]: handle certificate_request sequence", SSL_GETPID(), ss->fd)); @@ -1805,7 +1804,7 @@ tls13_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) &certRequest->signatureSchemes, &certRequest->signatureSchemeCount, &b, &length); - if (rv != SECSuccess) { + if (rv != SECSuccess || certRequest->signatureSchemeCount == 0) { FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, decode_error); goto loser; @@ -1816,14 +1815,16 @@ tls13_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (rv != SECSuccess) goto loser; /* alert already sent */ - /* Verify that the extensions length is correct. */ - extensionsLength = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); - if (extensionsLength < 0) { - goto loser; /* alert already sent */ + /* Verify that the extensions are sane. */ + rv = ssl3_ConsumeHandshakeVariable(ss, &extensionsData, 2, &b, &length); + if (rv != SECSuccess) { + goto loser; } - if (extensionsLength != length) { - FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_REQUEST, - illegal_parameter); + + /* Process all the extensions (note: currently a no-op). */ + rv = ssl3_HandleExtensions(ss, &extensionsData.data, &extensionsData.len, + certificate_request); + if (rv != SECSuccess) { goto loser; } @@ -2758,7 +2759,7 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type, if ((*specp)->epoch == PR_UINT16_MAX) { return SECFailure; } - spec->epoch = (*specp)->epoch + 1; + spec->epoch = (PRUint16)type; if (!IS_DTLS(ss)) { spec->read_seq_num = spec->write_seq_num = 0; @@ -2770,6 +2771,11 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type, dtls_InitRecvdRecords(&spec->recvdRecords); } + if (type == TrafficKeyEarlyApplicationData) { + spec->earlyDataRemaining = + ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size; + } + /* Now that we've set almost everything up, finally cut over. */ ssl_GetSpecWriteLock(ss); tls13_CipherSpecRelease(*specp); /* May delete old cipher. */ @@ -2781,6 +2787,10 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type, spec->phase, spec->epoch, direction == CipherSpecRead ? "read" : "write")); + if (ss->ssl3.changedCipherSpecFunc) { + ss->ssl3.changedCipherSpecFunc(ss->ssl3.changedCipherSpecArg, + direction == CipherSpecWrite, spec); + } return SECSuccess; } @@ -2853,6 +2863,9 @@ tls13_DestroyKeyShares(PRCList *list) { PRCList *cur_p; + /* The list must be initialized. */ + PORT_Assert(PR_LIST_HEAD(list)); + while (!PR_CLIST_IS_EMPTY(list)) { cur_p = PR_LIST_TAIL(list); PR_REMOVE_LINK(cur_p); @@ -2926,6 +2939,7 @@ tls13_WriteNonce(ssl3KeyMaterial *keys, for (i = 0; i < 8; ++i) { nonce[4 + i] ^= seqNumBuf[i]; } + PRINT_BUF(50, (NULL, "Nonce", nonce, nonceLen)); } /* Implement the SSLAEADCipher interface defined in sslimpl.h. @@ -3015,7 +3029,7 @@ static SECStatus tls13_HandleEncryptedExtensions(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { SECStatus rv; - PRInt32 innerLength; + PRUint32 innerLength; SECItem oldNpn = { siBuffer, NULL, 0 }; PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss)); @@ -3030,8 +3044,8 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, SSL3Opaque *b, PRUint32 length) return SECFailure; } - innerLength = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); - if (innerLength < 0) { + rv = ssl3_ConsumeHandshakeNumber(ss, &innerLength, 2, &b, &length); + if (rv != SECSuccess) { return SECFailure; /* Alert already sent. */ } if (innerLength != length) { @@ -3283,16 +3297,7 @@ tls13_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, /* Set the auth type. */ if (!ss->sec.isServer) { - switch (ssl_SignatureSchemeToKeyType(sigScheme)) { - case rsaKey: - ss->sec.authType = ssl_auth_rsa_sign; - break; - case ecKey: - ss->sec.authType = ssl_auth_ecdsa; - break; - default: - PORT_Assert(PR_FALSE); - } + ss->sec.authType = ssl_SignatureSchemeToAuthType(sigScheme); } /* Request a client certificate now if one was requested. */ @@ -3712,17 +3717,10 @@ tls13_SendClientSecondRound(sslSocket *ss) return SECWouldBlock; } - if (ss->ssl3.hs.zeroRttState != ssl_0rtt_none) { - if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { - rv = tls13_SendEndOfEarlyData(ss); - if (rv != SECSuccess) { - return SECFailure; /* Error code already set. */ - } - } - if (IS_DTLS(ss) && !ss->ssl3.hs.helloRetry) { - /* Reset the counters so that the next epoch isn't set - * incorrectly. */ - tls13_SetNullCipherSpec(ss, &ss->ssl3.cwSpec); + if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { + rv = tls13_SendEndOfEarlyData(ss); + if (rv != SECSuccess) { + return SECFailure; /* Error code already set. */ } } @@ -3784,7 +3782,7 @@ tls13_SendClientSecondRound(sslSocket *ss) * } NewSessionTicket; */ -#define MAX_EARLY_DATA_SIZE (2 << 16) /* Arbitrary limit. */ +PRUint32 ssl_max_early_data_size = (2 << 16); /* Arbitrary limit. */ SECStatus tls13_SendNewSessionTicket(sslSocket *ss) @@ -3799,7 +3797,7 @@ tls13_SendNewSessionTicket(sslSocket *ss) ticket.flags |= ticket_allow_early_data; max_early_data_size_len = 8; /* type + len + value. */ } - ticket.ticket_lifetime_hint = TLS_EX_SESS_TICKET_LIFETIME_HINT; + ticket.ticket_lifetime_hint = ssl_ticket_lifetime; rv = ssl3_EncodeSessionTicket(ss, &ticket, &ticket_data); if (rv != SECSuccess) @@ -3818,7 +3816,7 @@ tls13_SendNewSessionTicket(sslSocket *ss) goto loser; /* This is a fixed value. */ - rv = ssl3_AppendHandshakeNumber(ss, TLS_EX_SESS_TICKET_LIFETIME_HINT, 4); + rv = ssl3_AppendHandshakeNumber(ss, ssl_ticket_lifetime, 4); if (rv != SECSuccess) goto loser; @@ -3854,7 +3852,7 @@ tls13_SendNewSessionTicket(sslSocket *ss) if (rv != SECSuccess) goto loser; - rv = ssl3_AppendHandshakeNumber(ss, MAX_EARLY_DATA_SIZE, 4); + rv = ssl3_AppendHandshakeNumber(ss, ssl_max_early_data_size, 4); if (rv != SECSuccess) goto loser; } @@ -3873,7 +3871,6 @@ static SECStatus tls13_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { SECStatus rv; - PRInt32 tmp; PRUint32 utmp; NewSessionTicket ticket = { 0 }; SECItem data; @@ -3893,14 +3890,14 @@ tls13_HandleNewSessionTicket(sslSocket *ss, SSL3Opaque *b, PRUint32 length) return SECFailure; } - ticket.received_timestamp = ssl_Time(); - tmp = ssl3_ConsumeHandshakeNumber(ss, 4, &b, &length); - if (tmp < 0) { + ticket.received_timestamp = PR_Now(); + rv = ssl3_ConsumeHandshakeNumber(ss, &ticket.ticket_lifetime_hint, 4, &b, + &length); + if (rv != SECSuccess) { FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, decode_error); return SECFailure; } - ticket.ticket_lifetime_hint = (PRUint32)tmp; ticket.ticket.type = siBuffer; rv = ssl3_ConsumeHandshake(ss, &utmp, sizeof(utmp), @@ -4039,7 +4036,8 @@ tls13_ExtensionAllowed(PRUint16 extension, SSL3HandshakeType message) (message == hello_retry_request) || (message == encrypted_extensions) || (message == new_session_ticket) || - (message == certificate)); + (message == certificate) || + (message == certificate_request)); for (i = 0; i < PR_ARRAY_SIZE(KnownExtensions); i++) { if (KnownExtensions[i].ex_value == extension) @@ -4099,6 +4097,28 @@ tls13_FormatAdditionalData(PRUint8 *aad, unsigned int length, PORT_Assert((ptr - aad) == length); } +PRInt32 +tls13_LimitEarlyData(sslSocket *ss, SSL3ContentType type, PRInt32 toSend) +{ + PRInt32 reduced; + + PORT_Assert(type == content_application_data); + PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3); + PORT_Assert(!ss->firstHsDone); + if (ss->ssl3.cwSpec->epoch != TrafficKeyEarlyApplicationData) { + return toSend; + } + + if (IS_DTLS(ss) && toSend > ss->ssl3.cwSpec->earlyDataRemaining) { + /* Don't split application data records in DTLS. */ + return 0; + } + + reduced = PR_MIN(toSend, ss->ssl3.cwSpec->earlyDataRemaining); + ss->ssl3.cwSpec->earlyDataRemaining -= reduced; + return reduced; +} + SECStatus tls13_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, @@ -4250,6 +4270,17 @@ tls13_UnprotectRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *plaintext cText->type = plaintext->buf[plaintext->len - 1]; --plaintext->len; + /* Check that we haven't received too much 0-RTT data. */ + if (crSpec->epoch == TrafficKeyEarlyApplicationData && + cText->type == content_application_data) { + if (plaintext->len > crSpec->earlyDataRemaining) { + *alert = unexpected_message; + PORT_SetError(SSL_ERROR_TOO_MUCH_EARLY_DATA); + return SECFailure; + } + crSpec->earlyDataRemaining -= plaintext->len; + } + SSL_TRC(10, ("%d: TLS13[%d]: %s received record of length=%d type=%d", SSL_GETPID(), ss->fd, SSL_ROLE(ss), @@ -4285,7 +4316,7 @@ tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid) return PR_FALSE; if ((sid->u.ssl3.locked.sessionTicket.flags & ticket_allow_early_data) == 0) return PR_FALSE; - return tls13_AlpnTagAllowed(ss, &sid->u.ssl3.alpnSelection); + return ssl_AlpnTagAllowed(ss, &sid->u.ssl3.alpnSelection); } SECStatus @@ -4314,15 +4345,8 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss) return rv; } - /* Null spec... */ - ssl_GetSpecReadLock(ss); - ss->ssl3.hs.nullSpec = ss->ssl3.cwSpec; - tls13_CipherSpecAddRef(ss->ssl3.hs.nullSpec); - ssl_ReleaseSpecReadLock(ss); - /* Cipher suite already set in tls13_SetupClientHello. */ - ss->ssl3.hs.preliminaryInfo = 0; /* TODO(ekr@rtfm.com) Fill this in. - * bug 1281255. */ + ss->ssl3.hs.preliminaryInfo = 0; rv = tls13_DeriveSecret(ss, ss->ssl3.hs.currentSecret, kHkdfLabelClient, @@ -4363,21 +4387,6 @@ tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len) return len; } -/* 0-RTT data will be followed by a different cipher spec; this resets the - * current spec to the null spec so that the following state can be set as - * though 0-RTT didn't happen. TODO: work out if this is the best plan. */ -static void -tls13_SetNullCipherSpec(sslSocket *ss, ssl3CipherSpec **specp) -{ - PORT_Assert(ss->ssl3.hs.nullSpec); - - ssl_GetSpecWriteLock(ss); - tls13_CipherSpecRelease(*specp); - *specp = ss->ssl3.hs.nullSpec; - ssl_ReleaseSpecWriteLock(ss); - ss->ssl3.hs.nullSpec = NULL; -} - static SECStatus tls13_SendEndOfEarlyData(sslSocket *ss) { @@ -4410,11 +4419,6 @@ tls13_HandleEndOfEarlyData(sslSocket *ss) PORT_Assert(TLS13_IN_HS_STATE(ss, ss->opt.requestCertificate ? wait_client_cert : wait_finished)); - if (IS_DTLS(ss)) { - /* Reset the cipher spec so that the epoch counter is properly reset. */ - tls13_SetNullCipherSpec(ss, &ss->ssl3.crSpec); - } - rv = tls13_SetCipherSpec(ss, TrafficKeyHandshake, CipherSpecRead, PR_FALSE); if (rv != SECSuccess) { diff --git a/nss/lib/ssl/tls13con.h b/nss/lib/ssl/tls13con.h index c39c62a..189da0a 100644 --- a/nss/lib/ssl/tls13con.h +++ b/nss/lib/ssl/tls13con.h @@ -45,6 +45,7 @@ void tls13_FatalError(sslSocket *ss, PRErrorCode prError, SSL3AlertDescription desc); SECStatus tls13_SetupClientHello(sslSocket *ss); SECStatus tls13_MaybeDo0RTTHandshake(sslSocket *ss); +PRInt32 tls13_LimitEarlyData(sslSocket *ss, SSL3ContentType type, PRInt32 toSend); PRBool tls13_AllowPskCipher(const sslSocket *ss, const ssl3CipherSuiteDef *cipher_def); PRBool tls13_PskSuiteEnabled(sslSocket *ss); diff --git a/nss/lib/ssl/tls13exthandle.c b/nss/lib/ssl/tls13exthandle.c index be93b97..c2ce390 100644 --- a/nss/lib/ssl/tls13exthandle.c +++ b/nss/lib/ssl/tls13exthandle.c @@ -208,13 +208,13 @@ static SECStatus tls13_HandleKeyShareEntry(const sslSocket *ss, TLSExtensionData *xtnData, SECItem *data) { SECStatus rv; - PRInt32 group; + PRUint32 group; const sslNamedGroupDef *groupDef; TLS13KeyShareEntry *ks = NULL; SECItem share = { siBuffer, NULL, 0 }; - group = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (group < 0) { + rv = ssl3_ExtConsumeHandshakeNumber(ss, &group, 2, &data->data, &data->len); + if (rv != SECSuccess) { PORT_SetError(SSL_ERROR_RX_MALFORMED_KEY_SHARE); goto loser; } @@ -256,11 +256,10 @@ tls13_ClientHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PR PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares)); PORT_Assert(!ss->sec.isServer); + + /* The server must not send this extension when negotiating < TLS 1.3. */ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - /* This can't happen because the extension processing - * code filters out TLS 1.3 extensions when not in - * TLS 1.3 mode. */ - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION); return SECFailure; } @@ -285,7 +284,7 @@ SECStatus tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; - PRInt32 tmp; + PRUint32 tmp; const sslNamedGroupDef *group; PORT_Assert(!ss->sec.isServer); @@ -294,8 +293,8 @@ tls13_ClientHandleKeyShareXtnHrr(const sslSocket *ss, TLSExtensionData *xtnData, SSL_TRC(3, ("%d: SSL3[%d]: handle key_share extension in HRR", SSL_GETPID(), ss->fd)); - tmp = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (tmp < 0) { + rv = ssl3_ExtConsumeHandshakeNumber(ss, &tmp, 2, &data->data, &data->len); + if (rv != SECSuccess) { return SECFailure; /* error code already set */ } if (data->len) { @@ -335,7 +334,7 @@ SECStatus tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { SECStatus rv; - PRInt32 length; + PRUint32 length; PORT_Assert(ss->sec.isServer); PORT_Assert(PR_CLIST_IS_EMPTY(&xtnData->remoteKeyShares)); @@ -349,9 +348,9 @@ tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData, PR /* Redundant length because of TLS encoding (this vector consumes * the entire extension.) */ - length = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, - &data->len); - if (length < 0) + rv = ssl3_ExtConsumeHandshakeNumber(ss, &length, 2, &data->data, + &data->len); + if (rv != SECSuccess) goto loser; if (length != data->len) { /* Check for consistency */ @@ -487,7 +486,7 @@ tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, if (append) { SECStatus rv; - PRUint32 age; + PRTime age; unsigned int prefixLength; PRUint8 binder[TLS13_MAX_FINISHED_SIZE]; unsigned int binderLen; @@ -508,7 +507,8 @@ tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, goto loser; /* Obfuscated age. */ - age = ssl_Time() - session_ticket->received_timestamp; + age = PR_Now() - session_ticket->received_timestamp; + age /= PR_USEC_PER_MSEC; age += session_ticket->ticket_age_add; rv = ssl3_ExtAppendHandshakeNumber(ss, age, 4); if (rv != SECSuccess) @@ -684,18 +684,20 @@ SECStatus tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { - PRInt32 index; + PRUint32 index; + SECStatus rv; SSL_TRC(3, ("%d: SSL3[%d]: handle pre_shared_key extension", SSL_GETPID(), ss->fd)); - /* If we are doing < TLS 1.3, then ignore this. */ + /* The server must not send this extension when negotiating < TLS 1.3. */ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { - return SECSuccess; + PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION); + return SECFailure; } - index = ssl3_ExtConsumeHandshakeNumber(ss, 2, &data->data, &data->len); - if (index < 0) + rv = ssl3_ExtConsumeHandshakeNumber(ss, &index, 2, &data->data, &data->len); + if (rv != SECSuccess) return SECFailure; /* This should be the end of the extension. */ @@ -746,10 +748,10 @@ tls13_ClientSendEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, rv = ssl3_ExtAppendHandshakeNumber(ss, 0, 2); if (rv != SECSuccess) return -1; - } - xtnData->advertised[xtnData->numAdvertised++] = - ssl_tls13_early_data_xtn; + xtnData->advertised[xtnData->numAdvertised++] = + ssl_tls13_early_data_xtn; + } return extension_length; } @@ -766,6 +768,12 @@ tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, P return SECSuccess; } + if (ss->ssl3.hs.helloRetry) { + ssl3_ExtSendAlert(ss, alert_fatal, unsupported_extension); + PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); + return SECFailure; + } + if (data->len) { PORT_SetError(SSL_ERROR_MALFORMED_EARLY_DATA); return SECFailure; @@ -814,7 +822,7 @@ tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData, P SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension", SSL_GETPID(), ss->fd)); - /* If we are doing < TLS 1.3, then ignore this. */ + /* The server must not send this extension when negotiating < TLS 1.3. */ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION); return SECFailure; @@ -841,7 +849,7 @@ tls13_ClientHandleTicketEarlyDataInfoXtn(const sslSocket *ss, TLSExtensionData * SSL_TRC(3, ("%d: TLS13[%d]: handle early_data_info extension", SSL_GETPID(), ss->fd)); - /* If we are doing < TLS 1.3, then ignore this. */ + /* The server must not send this extension when negotiating < TLS 1.3. */ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { PORT_SetError(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION); return SECFailure; @@ -912,6 +920,9 @@ tls13_ClientSendSupportedVersionsXtn(const sslSocket *ss, TLSExtensionData *xtnD if (rv != SECSuccess) return -1; } + + xtnData->advertised[xtnData->numAdvertised++] = + ssl_tls13_supported_versions_xtn; } return extensions_len; @@ -1091,6 +1102,13 @@ tls13_SendShortHeaderXtn(const sslSocket *ss, return 0; } + /* Don't send this if TLS 1.3 isn't at least possible. */ + if (ss->vrange.max < SSL_LIBRARY_VERSION_TLS_1_3) { + /* This should only happen on the client. */ + PORT_Assert(!ss->sec.isServer); + return 0; + } + SSL_TRC(3, ("%d: TLS13[%d]: send short_header extension", SSL_GETPID(), ss->fd)); @@ -1122,10 +1140,10 @@ tls13_HandleShortHeaderXtn( const sslSocket *ss, TLSExtensionData *xtnData, PRUint16 ex_type, SECItem *data) { - SSL_TRC(3, ("%d: TLS13[%d]: handle early_data extension", + SSL_TRC(3, ("%d: TLS13[%d]: handle short_header extension", SSL_GETPID(), ss->fd)); - /* If we are doing < TLS 1.3, then ignore this. */ + /* The client might have asked for this, but we didn't negotiate TLS 1.3. */ if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) { return SECSuccess; } diff --git a/nss/lib/util/ciferfam.h b/nss/lib/util/ciferfam.h index 559e92f..68caa4f 100644 --- a/nss/lib/util/ciferfam.h +++ b/nss/lib/util/ciferfam.h @@ -52,6 +52,9 @@ #define PKCS12_RC4_128 (CIPHER_FAMILYID_PKCS12 | 0012) #define PKCS12_DES_56 (CIPHER_FAMILYID_PKCS12 | 0021) #define PKCS12_DES_EDE3_168 (CIPHER_FAMILYID_PKCS12 | 0022) +#define PKCS12_AES_CBC_128 (CIPHER_FAMILYID_PKCS12 | 0031) +#define PKCS12_AES_CBC_192 (CIPHER_FAMILYID_PKCS12 | 0032) +#define PKCS12_AES_CBC_256 (CIPHER_FAMILYID_PKCS12 | 0033) /* SMIME version numbers are negative, to avoid colliding with SSL versions */ #define SMIME_LIBRARY_VERSION_1_0 -0x0100 diff --git a/nss/lib/util/eccutil.h b/nss/lib/util/eccutil.h index 0d4caad..8c627e1 100644 --- a/nss/lib/util/eccutil.h +++ b/nss/lib/util/eccutil.h @@ -5,10 +5,11 @@ #ifndef _FREEBL_H_ #define _FREEBL_H_ -/* point encoding type */ +/* deprecated */ typedef enum { ECPoint_Uncompressed, - ECPoint_XOnly + ECPoint_XOnly, + ECPoint_Undefined } ECPointEncoding; #endif /* _FREEBL_H_ */ diff --git a/nss/lib/util/exports.gyp b/nss/lib/util/exports.gyp index eb220d2..9ed0c16 100644 --- a/nss/lib/util/exports.gyp +++ b/nss/lib/util/exports.gyp @@ -30,6 +30,7 @@ 'pkcs11p.h', 'pkcs11t.h', 'pkcs11u.h', + 'pkcs11uri.h', 'pkcs1sig.h', 'portreg.h', 'secasn1.h', diff --git a/nss/lib/util/manifest.mn b/nss/lib/util/manifest.mn index f0a9fd0..b33a204 100644 --- a/nss/lib/util/manifest.mn +++ b/nss/lib/util/manifest.mn @@ -41,6 +41,7 @@ EXPORTS = \ utilrename.h \ utilpars.h \ utilparst.h \ + pkcs11uri.h \ $(NULL) PRIVATE_EXPORTS = \ @@ -76,6 +77,7 @@ CSRCS = \ utf8.c \ utilmod.c \ utilpars.c \ + pkcs11uri.c \ $(NULL) MODULE = nss diff --git a/nss/lib/util/nssb64d.c b/nss/lib/util/nssb64d.c index 6544393..886ce21 100644 --- a/nss/lib/util/nssb64d.c +++ b/nss/lib/util/nssb64d.c @@ -370,7 +370,7 @@ pl_base64_decode_flush(PLBase64Decoder *data) static PRUint32 PL_Base64MaxDecodedLength(PRUint32 size) { - return ((size * 3) / 4); + return size * 0.75; } /* @@ -704,9 +704,8 @@ NSSBase64_DecodeBuffer(PLArenaPool *arenaOpt, SECItem *outItemOpt, { SECItem *out_item = NULL; PRUint32 max_out_len = 0; - PRUint32 out_len; void *mark = NULL; - unsigned char *dummy; + unsigned char *dummy = NULL; if ((outItemOpt != NULL && outItemOpt->data != NULL) || inLen == 0) { PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -717,33 +716,35 @@ NSSBase64_DecodeBuffer(PLArenaPool *arenaOpt, SECItem *outItemOpt, mark = PORT_ArenaMark(arenaOpt); max_out_len = PL_Base64MaxDecodedLength(inLen); + if (max_out_len == 0) { + goto loser; + } out_item = SECITEM_AllocItem(arenaOpt, outItemOpt, max_out_len); if (out_item == NULL) { - if (arenaOpt != NULL) - PORT_ArenaRelease(arenaOpt, mark); - return NULL; + goto loser; } dummy = PL_Base64DecodeBuffer(inStr, inLen, out_item->data, - max_out_len, &out_len); + max_out_len, &out_item->len); if (dummy == NULL) { - if (arenaOpt != NULL) { - PORT_ArenaRelease(arenaOpt, mark); - if (outItemOpt != NULL) { - outItemOpt->data = NULL; - outItemOpt->len = 0; - } - } else { - SECITEM_FreeItem(out_item, - (outItemOpt == NULL) ? PR_TRUE : PR_FALSE); - } - return NULL; + goto loser; } - - if (arenaOpt != NULL) + if (arenaOpt != NULL) { PORT_ArenaUnmark(arenaOpt, mark); - out_item->len = out_len; + } return out_item; + +loser: + if (arenaOpt != NULL) { + PORT_ArenaRelease(arenaOpt, mark); + if (outItemOpt != NULL) { + outItemOpt->data = NULL; + outItemOpt->len = 0; + } + } else if (dummy == NULL) { + SECITEM_FreeItem(out_item, (PRBool)(outItemOpt == NULL)); + } + return NULL; } /* diff --git a/nss/lib/util/nssb64e.c b/nss/lib/util/nssb64e.c index 50402c3..18b01dd 100644 --- a/nss/lib/util/nssb64e.c +++ b/nss/lib/util/nssb64e.c @@ -282,20 +282,28 @@ PL_Base64MaxEncodedLength(PRUint32 size, PRUint32 line_length) { PRUint32 tokens, tokens_per_line, full_lines, line_break_chars, remainder; + /* This is the maximum length we support. */ + if (size > 0x3fffffff) { + return 0; + } + tokens = (size + 2) / 3; - if (line_length == 0) + if (line_length == 0) { return tokens * 4; + } - if (line_length < 4) /* too small! */ + if (line_length < 4) { /* too small! */ line_length = 4; + } tokens_per_line = line_length / 4; full_lines = tokens / tokens_per_line; remainder = (tokens - (full_lines * tokens_per_line)) * 4; line_break_chars = full_lines * 2; - if (remainder == 0) + if (remainder == 0) { line_break_chars -= 2; + } return (full_lines * tokens_per_line * 4) + line_break_chars + remainder; } @@ -447,13 +455,18 @@ PL_Base64EncodeBuffer(const unsigned char *src, PRUint32 srclen, PRStatus status; PR_ASSERT(srclen > 0); - if (srclen == 0) + if (srclen == 0) { return dest; + } /* * How much space could we possibly need for encoding this input? */ need_length = PL_Base64MaxEncodedLength(srclen, line_length); + if (need_length == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } /* * Make sure we have at least that much, if output buffer provided. @@ -631,6 +644,10 @@ NSSBase64_EncodeItem(PLArenaPool *arenaOpt, char *outStrOpt, } max_out_len = PL_Base64MaxEncodedLength(inItem->len, 64); + if (max_out_len == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } if (arenaOpt != NULL) mark = PORT_ArenaMark(arenaOpt); diff --git a/nss/lib/util/nssutil.def b/nss/lib/util/nssutil.def index e4a6572..f4b9ef7 100644 --- a/nss/lib/util/nssutil.def +++ b/nss/lib/util/nssutil.def @@ -290,3 +290,20 @@ PORT_DestroyCheapArena; ;+ local: ;+ *; ;+}; +;+NSSUTIL_3.25 { # NSS Utilities 3.25 release +;+ global: +SEC_ASN1DecoderSetMaximumElementSize; +;+ local: +;+ *; +;+}; +;+NSSUTIL_3.31 { # NSS Utilities 3.31 release +;+ global: +PK11URI_CreateURI; +PK11URI_ParseURI; +PK11URI_FormatURI; +PK11URI_DestroyURI; +PK11URI_GetPathAttribute; +PK11URI_GetQueryAttribute; +;+ local: +;+ *; +;+}; diff --git a/nss/lib/util/nssutil.h b/nss/lib/util/nssutil.h index 53b96a0..bdde3dd 100644 --- a/nss/lib/util/nssutil.h +++ b/nss/lib/util/nssutil.h @@ -19,10 +19,10 @@ * The format of the version string should be * "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]" */ -#define NSSUTIL_VERSION "3.28.1" +#define NSSUTIL_VERSION "3.31" #define NSSUTIL_VMAJOR 3 -#define NSSUTIL_VMINOR 28 -#define NSSUTIL_VPATCH 1 +#define NSSUTIL_VMINOR 31 +#define NSSUTIL_VPATCH 0 #define NSSUTIL_VBUILD 0 #define NSSUTIL_BETA PR_FALSE diff --git a/nss/lib/util/pkcs11n.h b/nss/lib/util/pkcs11n.h index ebb8122..399d656 100644 --- a/nss/lib/util/pkcs11n.h +++ b/nss/lib/util/pkcs11n.h @@ -93,6 +93,8 @@ #define CKA_NSS_JPAKE_X2 (CKA_NSS + 32) #define CKA_NSS_JPAKE_X2S (CKA_NSS + 33) +#define CKA_NSS_MOZILLA_CA_POLICY (CKA_NSS + 34) + /* * Trust attributes: * @@ -222,6 +224,12 @@ #define CKM_NSS_CHACHA20_KEY_GEN (CKM_NSS + 27) #define CKM_NSS_CHACHA20_POLY1305 (CKM_NSS + 28) +/* Additional PKCS #12 PBE algorithms defined in v1.1 */ +#define CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN (CKM_NSS + 29) +#define CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN (CKM_NSS + 30) +#define CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN (CKM_NSS + 31) +#define CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN (CKM_NSS + 32) + /* * HISTORICAL: * Do not attempt to use these. They are only used by NETSCAPE's internal diff --git a/nss/lib/util/pkcs11uri.c b/nss/lib/util/pkcs11uri.c new file mode 100644 index 0000000..4534402 --- /dev/null +++ b/nss/lib/util/pkcs11uri.c @@ -0,0 +1,833 @@ +/* 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 "pkcs11.h" +#include "pkcs11uri.h" +#include "plarena.h" +#include "prprf.h" +#include "secport.h" + +/* Character sets used in the ABNF rules in RFC7512. */ +#define PK11URI_DIGIT "0123456789" +#define PK11URI_ALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define PK11URI_HEXDIG PK11URI_DIGIT "abcdefABCDEF" +#define PK11URI_UNRESERVED PK11URI_ALPHA PK11URI_DIGIT "-._~" +#define PK11URI_RES_AVAIL ":[]@!$'()*+,=" +#define PK11URI_PATH_RES_AVAIL PK11URI_RES_AVAIL "&" +#define PK11URI_QUERY_RES_AVAIL PK11URI_RES_AVAIL "/?|" +#define PK11URI_ATTR_NM_CHAR PK11URI_ALPHA PK11URI_DIGIT "-_" +#define PK11URI_PCHAR PK11URI_UNRESERVED PK11URI_PATH_RES_AVAIL +#define PK11URI_QCHAR PK11URI_UNRESERVED PK11URI_QUERY_RES_AVAIL + +/* Path attributes defined in RFC7512. */ +static const char *pattr_names[] = { + PK11URI_PATTR_TOKEN, + PK11URI_PATTR_MANUFACTURER, + PK11URI_PATTR_SERIAL, + PK11URI_PATTR_MODEL, + PK11URI_PATTR_LIBRARY_MANUFACTURER, + PK11URI_PATTR_LIBRARY_DESCRIPTION, + PK11URI_PATTR_LIBRARY_VERSION, + PK11URI_PATTR_OBJECT, + PK11URI_PATTR_TYPE, + PK11URI_PATTR_ID, + PK11URI_PATTR_SLOT_MANUFACTURER, + PK11URI_PATTR_SLOT_DESCRIPTION, + PK11URI_PATTR_SLOT_ID +}; + +/* Query attributes defined in RFC7512. */ +static const char *qattr_names[] = { + PK11URI_QATTR_PIN_SOURCE, + PK11URI_QATTR_PIN_VALUE, + PK11URI_QATTR_MODULE_NAME, + PK11URI_QATTR_MODULE_PATH +}; + +struct PK11URIBufferStr { + PLArenaPool *arena; + char *data; + size_t size; + size_t allocated; +}; +typedef struct PK11URIBufferStr PK11URIBuffer; + +struct PK11URIAttributeListEntryStr { + char *name; + char *value; +}; +typedef struct PK11URIAttributeListEntryStr PK11URIAttributeListEntry; + +struct PK11URIAttributeListStr { + PLArenaPool *arena; + PK11URIAttributeListEntry *attrs; + size_t num_attrs; +}; +typedef struct PK11URIAttributeListStr PK11URIAttributeList; + +struct PK11URIStr { + PLArenaPool *arena; + + PK11URIAttributeList pattrs; + PK11URIAttributeList vpattrs; + + PK11URIAttributeList qattrs; + PK11URIAttributeList vqattrs; +}; + +#define PK11URI_ARENA_SIZE 1024 + +typedef int (*PK11URIAttributeCompareNameFunc)(const char *a, const char *b); + +/* This belongs in secport.h */ +#define PORT_ArenaGrowArray(poolp, oldptr, type, oldnum, newnum) \ + (type *)PORT_ArenaGrow((poolp), (oldptr), \ + (oldnum) * sizeof(type), (newnum) * sizeof(type)) +#define PORT_ReallocArray(oldptr, type, newnum) \ + (type *)PORT_Realloc((oldptr), (newnum) * sizeof(type)) + +/* Functions for resizable buffer. */ +static SECStatus +pk11uri_AppendBuffer(PK11URIBuffer *buffer, const unsigned char *data, + size_t size) +{ + /* Check overflow. */ + if (buffer->size + size < buffer->size) + return SECFailure; + + if (buffer->size + size > buffer->allocated) { + size_t allocated = buffer->allocated * 2 + size; + if (allocated < buffer->allocated) + return SECFailure; + if (buffer->arena) + buffer->data = PORT_ArenaGrow(buffer->arena, buffer->data, + buffer->allocated, allocated); + else + buffer->data = PORT_Realloc(buffer->data, allocated); + if (buffer->data == NULL) + return SECFailure; + buffer->allocated = allocated; + } + + memcpy(&buffer->data[buffer->size], data, size); + buffer->size += size; + + return SECSuccess; +} + +static void +pk11uri_InitBuffer(PK11URIBuffer *buffer, PLArenaPool *arena) +{ + memset(buffer, 0, sizeof(PK11URIBuffer)); + buffer->arena = arena; +} + +static void +pk11uri_DestroyBuffer(PK11URIBuffer *buffer) +{ + if (buffer->arena == NULL) { + PORT_Free(buffer->data); + } +} + +/* URI encoding functions. */ +static char * +pk11uri_Escape(PLArenaPool *arena, const char *value, size_t length, + const char *available) +{ + PK11URIBuffer buffer; + const char *p; + unsigned char buf[4]; + char *result = NULL; + SECStatus ret; + + pk11uri_InitBuffer(&buffer, arena); + + for (p = value; p < value + length; p++) { + if (strchr(available, *p) == NULL) { + if (PR_snprintf((char *)buf, sizeof(buf), "%%%02X", *p) == (PRUint32)-1) { + goto fail; + } + ret = pk11uri_AppendBuffer(&buffer, buf, 3); + if (ret != SECSuccess) { + goto fail; + } + } else { + ret = pk11uri_AppendBuffer(&buffer, (const unsigned char *)p, 1); + if (ret != SECSuccess) { + goto fail; + } + } + } + buf[0] = '\0'; + ret = pk11uri_AppendBuffer(&buffer, buf, 1); + if (ret != SECSuccess) { + goto fail; + } + + /* Steal the memory allocated in buffer. */ + result = buffer.data; + buffer.data = NULL; + +fail: + pk11uri_DestroyBuffer(&buffer); + + return result; +} + +static char * +pk11uri_Unescape(PLArenaPool *arena, const char *value, size_t length) +{ + PK11URIBuffer buffer; + const char *p; + unsigned char buf[1]; + char *result = NULL; + SECStatus ret; + + pk11uri_InitBuffer(&buffer, arena); + + for (p = value; p < value + length; p++) { + if (*p == '%') { + int c; + size_t i; + + p++; + for (c = 0, i = 0; i < 2; i++) { + int h = *(p + i); + if ('0' <= h && h <= '9') { + c = (c << 4) | (h - '0'); + } else if ('a' <= h && h <= 'f') { + c = (c << 4) | (h - 'a' + 10); + } else if ('A' <= h && h <= 'F') { + c = (c << 4) | (h - 'A' + 10); + } else { + break; + } + } + if (i != 2) { + goto fail; + } + p++; + buf[0] = c; + } else { + buf[0] = *p; + } + ret = pk11uri_AppendBuffer(&buffer, buf, 1); + if (ret != SECSuccess) { + goto fail; + } + } + buf[0] = '\0'; + ret = pk11uri_AppendBuffer(&buffer, buf, 1); + if (ret != SECSuccess) { + goto fail; + } + + result = buffer.data; + buffer.data = NULL; + +fail: + pk11uri_DestroyBuffer(&buffer); + + return result; +} + +/* Functions for manipulating attributes array. */ + +/* Compare two attribute names by the array index in attr_names. Both + * attribute names must be present in attr_names, otherwise it is a + * programming error. */ +static int +pk11uri_CompareByPosition(const char *a, const char *b, + const char **attr_names, size_t num_attr_names) +{ + int i, j; + + for (i = 0; i < num_attr_names; i++) { + if (strcmp(a, attr_names[i]) == 0) { + break; + } + } + PR_ASSERT(i < num_attr_names); + + for (j = 0; j < num_attr_names; j++) { + if (strcmp(b, attr_names[j]) == 0) { + break; + } + } + PR_ASSERT(j < num_attr_names); + + return i - j; +} + +/* Those pk11uri_Compare{Path,Query}AttributeName functions are used + * to reorder attributes when inserting. */ +static int +pk11uri_ComparePathAttributeName(const char *a, const char *b) +{ + return pk11uri_CompareByPosition(a, b, pattr_names, PR_ARRAY_SIZE(pattr_names)); +} + +static int +pk11uri_CompareQueryAttributeName(const char *a, const char *b) +{ + return pk11uri_CompareByPosition(a, b, qattr_names, PR_ARRAY_SIZE(qattr_names)); +} + +static SECStatus +pk11uri_InsertToAttributeList(PK11URIAttributeList *attrs, + char *name, char *value, + PK11URIAttributeCompareNameFunc compare_name, + PRBool allow_duplicate) +{ + size_t i; + + if (attrs->arena) { + attrs->attrs = PORT_ArenaGrowArray(attrs->arena, attrs->attrs, + PK11URIAttributeListEntry, + attrs->num_attrs, + attrs->num_attrs + 1); + } else { + attrs->attrs = PORT_ReallocArray(attrs->attrs, + PK11URIAttributeListEntry, + attrs->num_attrs + 1); + } + if (attrs->attrs == NULL) { + return SECFailure; + } + + for (i = 0; i < attrs->num_attrs; i++) { + if (!allow_duplicate && strcmp(name, attrs->attrs[i].name) == 0) { + return SECFailure; + } + if (compare_name(name, attrs->attrs[i].name) < 0) { + memmove(&attrs->attrs[i + 1], &attrs->attrs[i], + sizeof(PK11URIAttributeListEntry) * (attrs->num_attrs - i)); + break; + } + } + + attrs->attrs[i].name = name; + attrs->attrs[i].value = value; + + attrs->num_attrs++; + + return SECSuccess; +} + +static SECStatus +pk11uri_InsertToAttributeListEscaped(PK11URIAttributeList *attrs, + const char *name, size_t name_size, + const char *value, size_t value_size, + PK11URIAttributeCompareNameFunc compare_name, + PRBool allow_duplicate) +{ + char *name_copy = NULL, *value_copy = NULL; + SECStatus ret; + + if (attrs->arena) { + name_copy = PORT_ArenaNewArray(attrs->arena, char, name_size + 1); + } else { + name_copy = PORT_Alloc(name_size + 1); + } + if (name_copy == NULL) { + goto fail; + } + memcpy(name_copy, name, name_size); + name_copy[name_size] = '\0'; + + value_copy = pk11uri_Unescape(attrs->arena, value, value_size); + if (value_copy == NULL) { + goto fail; + } + + ret = pk11uri_InsertToAttributeList(attrs, name_copy, value_copy, compare_name, + allow_duplicate); + if (ret != SECSuccess) { + goto fail; + } + + return ret; + +fail: + if (attrs->arena == NULL) { + PORT_Free(name_copy); + PORT_Free(value_copy); + } + + return SECFailure; +} + +static void +pk11uri_InitAttributeList(PK11URIAttributeList *attrs, PLArenaPool *arena) +{ + memset(attrs, 0, sizeof(PK11URIAttributeList)); + attrs->arena = arena; +} + +static void +pk11uri_DestroyAttributeList(PK11URIAttributeList *attrs) +{ + if (attrs->arena == NULL) { + size_t i; + + for (i = 0; i < attrs->num_attrs; i++) { + PORT_Free(attrs->attrs[i].name); + PORT_Free(attrs->attrs[i].value); + } + PORT_Free(attrs->attrs); + } +} + +static SECStatus +pk11uri_AppendAttributeListToBuffer(PK11URIBuffer *buffer, + PK11URIAttributeList *attrs, + int separator, + const char *unescaped) +{ + size_t i; + SECStatus ret; + + for (i = 0; i < attrs->num_attrs; i++) { + unsigned char sep[1]; + char *escaped; + PK11URIAttributeListEntry *attr = &attrs->attrs[i]; + + if (i > 0) { + sep[0] = separator; + ret = pk11uri_AppendBuffer(buffer, sep, 1); + if (ret != SECSuccess) { + return ret; + } + } + + ret = pk11uri_AppendBuffer(buffer, (unsigned char *)attr->name, + strlen(attr->name)); + if (ret != SECSuccess) { + return ret; + } + + sep[0] = '='; + ret = pk11uri_AppendBuffer(buffer, sep, 1); + if (ret != SECSuccess) { + return ret; + } + + escaped = pk11uri_Escape(buffer->arena, attr->value, strlen(attr->value), + unescaped); + if (escaped == NULL) { + return ret; + } + ret = pk11uri_AppendBuffer(buffer, (unsigned char *)escaped, + strlen(escaped)); + if (buffer->arena == NULL) { + PORT_Free(escaped); + } + if (ret != SECSuccess) { + return ret; + } + } + + return SECSuccess; +} + +/* Creation of PK11URI object. */ +static PK11URI * +pk11uri_AllocURI(void) +{ + PLArenaPool *arena; + PK11URI *result; + + arena = PORT_NewArena(PK11URI_ARENA_SIZE); + if (arena == NULL) { + return NULL; + } + + result = PORT_ArenaZAlloc(arena, sizeof(PK11URI)); + if (result == NULL) { + PORT_FreeArena(arena, PR_FALSE); + return NULL; + } + + result->arena = arena; + pk11uri_InitAttributeList(&result->pattrs, arena); + pk11uri_InitAttributeList(&result->vpattrs, arena); + pk11uri_InitAttributeList(&result->qattrs, arena); + pk11uri_InitAttributeList(&result->vqattrs, arena); + + return result; +} + +static SECStatus +pk11uri_InsertAttributes(PK11URIAttributeList *dest_attrs, + PK11URIAttributeList *dest_vattrs, + const PK11URIAttribute *attrs, + size_t num_attrs, + const char **attr_names, + size_t num_attr_names, + PK11URIAttributeCompareNameFunc compare_name, + PRBool allow_duplicate, + PRBool vendor_allow_duplicate) +{ + SECStatus ret; + size_t i; + + for (i = 0; i < num_attrs; i++) { + char *name, *value; + const char *p; + size_t j; + + p = attrs[i].name; + + /* The attribute must not be empty. */ + if (*p == '\0') { + return SECFailure; + } + + /* Check that the name doesn't contain invalid character. */ + for (; *p != '\0'; p++) { + if (strchr(PK11URI_ATTR_NM_CHAR, *p) == NULL) { + return SECFailure; + } + } + + name = PORT_ArenaStrdup(dest_attrs->arena, attrs[i].name); + if (name == NULL) { + return SECFailure; + } + + value = PORT_ArenaStrdup(dest_attrs->arena, attrs[i].value); + if (value == NULL) { + return SECFailure; + } + + for (j = 0; j < num_attr_names; j++) { + if (strcmp(name, attr_names[j]) == 0) { + break; + } + } + if (j < num_attr_names) { + /* Named attribute. */ + ret = pk11uri_InsertToAttributeList(dest_attrs, + name, value, + compare_name, + allow_duplicate); + if (ret != SECSuccess) { + return ret; + } + } else { + /* Vendor attribute. */ + ret = pk11uri_InsertToAttributeList(dest_vattrs, + name, value, + strcmp, + vendor_allow_duplicate); + if (ret != SECSuccess) { + return ret; + } + } + } + + return SECSuccess; +} + +PK11URI * +PK11URI_CreateURI(const PK11URIAttribute *pattrs, + size_t num_pattrs, + const PK11URIAttribute *qattrs, + size_t num_qattrs) +{ + PK11URI *result; + SECStatus ret; + + result = pk11uri_AllocURI(); + + ret = pk11uri_InsertAttributes(&result->pattrs, &result->vpattrs, + pattrs, num_pattrs, + pattr_names, PR_ARRAY_SIZE(pattr_names), + pk11uri_ComparePathAttributeName, + PR_FALSE, PR_FALSE); + if (ret != SECSuccess) { + goto fail; + } + + ret = pk11uri_InsertAttributes(&result->qattrs, &result->vqattrs, + qattrs, num_qattrs, + qattr_names, PR_ARRAY_SIZE(qattr_names), + pk11uri_CompareQueryAttributeName, + PR_FALSE, PR_TRUE); + if (ret != SECSuccess) { + goto fail; + } + + return result; + +fail: + PK11URI_DestroyURI(result); + + return NULL; +} + +/* Parsing. */ +static SECStatus +pk11uri_ParseAttributes(const char **string, + const char *stop_chars, + int separator, + const char *accept_chars, + const char **attr_names, size_t num_attr_names, + PK11URIAttributeList *attrs, + PK11URIAttributeList *vattrs, + PK11URIAttributeCompareNameFunc compare_name, + PRBool allow_duplicate, + PRBool vendor_allow_duplicate) +{ + const char *p = *string; + + for (; *p != '\0'; p++) { + const char *name_start, *name_end, *value_start, *value_end; + size_t name_length, value_length, i; + SECStatus ret; + + if (strchr(stop_chars, *p) != NULL) { + break; + } + for (name_start = p; *p != '=' && *p != '\0'; p++) { + if (strchr(PK11URI_ATTR_NM_CHAR, *p) != NULL) + continue; + + return SECFailure; + } + if (*p == '\0') { + return SECFailure; + } + name_end = p++; + + /* The attribute name must not be empty. */ + if (name_end == name_start) { + return SECFailure; + } + + for (value_start = p; *p != separator && *p != '\0'; p++) { + if (strchr(stop_chars, *p) != NULL) { + break; + } + if (strchr(accept_chars, *p) != NULL) { + continue; + } + if (*p == '%') { + const char ch2 = *++p; + if (strchr(PK11URI_HEXDIG, ch2) != NULL) { + const char ch3 = *++p; + if (strchr(PK11URI_HEXDIG, ch3) != NULL) + continue; + } + } + + return SECFailure; + } + value_end = p; + + name_length = name_end - name_start; + value_length = value_end - value_start; + + for (i = 0; i < num_attr_names; i++) { + if (name_length == strlen(attr_names[i]) && + memcmp(name_start, attr_names[i], name_length) == 0) { + break; + } + } + if (i < num_attr_names) { + /* Named attribute. */ + ret = pk11uri_InsertToAttributeListEscaped(attrs, + name_start, name_length, + value_start, value_length, + compare_name, + allow_duplicate); + if (ret != SECSuccess) { + return ret; + } + } else { + /* Vendor attribute. */ + ret = pk11uri_InsertToAttributeListEscaped(vattrs, + name_start, name_length, + value_start, value_length, + strcmp, + vendor_allow_duplicate); + if (ret != SECSuccess) { + return ret; + } + } + + if (*p == '?' || *p == '\0') { + break; + } + } + + *string = p; + return SECSuccess; +} + +PK11URI * +PK11URI_ParseURI(const char *string) +{ + PK11URI *result; + const char *p = string; + SECStatus ret; + + if (strncmp("pkcs11:", p, 7) != 0) { + return NULL; + } + p += 7; + + result = pk11uri_AllocURI(); + if (result == NULL) { + return NULL; + } + + /* Parse the path component and its attributes. */ + ret = pk11uri_ParseAttributes(&p, "?", ';', PK11URI_PCHAR, + pattr_names, PR_ARRAY_SIZE(pattr_names), + &result->pattrs, &result->vpattrs, + pk11uri_ComparePathAttributeName, + PR_FALSE, PR_FALSE); + if (ret != SECSuccess) { + goto fail; + } + + /* Parse the query component and its attributes. */ + if (*p == '?') { + p++; + ret = pk11uri_ParseAttributes(&p, "", '&', PK11URI_QCHAR, + qattr_names, PR_ARRAY_SIZE(qattr_names), + &result->qattrs, &result->vqattrs, + pk11uri_CompareQueryAttributeName, + PR_FALSE, PR_TRUE); + if (ret != SECSuccess) { + goto fail; + } + } + + return result; + +fail: + PK11URI_DestroyURI(result); + + return NULL; +} + +/* Formatting. */ +char * +PK11URI_FormatURI(PLArenaPool *arena, PK11URI *uri) +{ + PK11URIBuffer buffer; + SECStatus ret; + char *result = NULL; + + pk11uri_InitBuffer(&buffer, arena); + + ret = pk11uri_AppendBuffer(&buffer, (unsigned char *)"pkcs11:", 7); + if (ret != SECSuccess) + goto fail; + + ret = pk11uri_AppendAttributeListToBuffer(&buffer, &uri->pattrs, ';', PK11URI_PCHAR); + if (ret != SECSuccess) { + goto fail; + } + + if (uri->pattrs.num_attrs > 0 && uri->vpattrs.num_attrs > 0) { + ret = pk11uri_AppendBuffer(&buffer, (unsigned char *)";", 1); + if (ret != SECSuccess) { + goto fail; + } + } + + ret = pk11uri_AppendAttributeListToBuffer(&buffer, &uri->vpattrs, ';', + PK11URI_PCHAR); + if (ret != SECSuccess) { + goto fail; + } + + if (uri->qattrs.num_attrs > 0 || uri->vqattrs.num_attrs > 0) { + ret = pk11uri_AppendBuffer(&buffer, (unsigned char *)"?", 1); + if (ret != SECSuccess) { + goto fail; + } + } + + ret = pk11uri_AppendAttributeListToBuffer(&buffer, &uri->qattrs, '&', PK11URI_QCHAR); + if (ret != SECSuccess) { + goto fail; + } + + if (uri->qattrs.num_attrs > 0 && uri->vqattrs.num_attrs > 0) { + ret = pk11uri_AppendBuffer(&buffer, (unsigned char *)"&", 1); + if (ret != SECSuccess) { + goto fail; + } + } + + ret = pk11uri_AppendAttributeListToBuffer(&buffer, &uri->vqattrs, '&', + PK11URI_QCHAR); + if (ret != SECSuccess) { + goto fail; + } + + ret = pk11uri_AppendBuffer(&buffer, (unsigned char *)"\0", 1); + if (ret != SECSuccess) { + goto fail; + } + + result = buffer.data; + buffer.data = NULL; + +fail: + pk11uri_DestroyBuffer(&buffer); + + return result; +} + +/* Deallocating. */ +void +PK11URI_DestroyURI(PK11URI *uri) +{ + pk11uri_DestroyAttributeList(&uri->pattrs); + pk11uri_DestroyAttributeList(&uri->vpattrs); + pk11uri_DestroyAttributeList(&uri->qattrs); + pk11uri_DestroyAttributeList(&uri->vqattrs); + PORT_FreeArena(uri->arena, PR_FALSE); +} + +/* Accessors. */ +static const char * +pk11uri_GetAttribute(PK11URIAttributeList *attrs, + PK11URIAttributeList *vattrs, + const char *name) +{ + size_t i; + + for (i = 0; i < attrs->num_attrs; i++) { + if (strcmp(name, attrs->attrs[i].name) == 0) { + return attrs->attrs[i].value; + } + } + + for (i = 0; i < vattrs->num_attrs; i++) { + if (strcmp(name, vattrs->attrs[i].name) == 0) { + return vattrs->attrs[i].value; + } + } + + return NULL; +} + +const char * +PK11URI_GetPathAttribute(PK11URI *uri, const char *name) +{ + return pk11uri_GetAttribute(&uri->pattrs, &uri->vpattrs, name); +} + +const char * +PK11URI_GetQueryAttribute(PK11URI *uri, const char *name) +{ + return pk11uri_GetAttribute(&uri->qattrs, &uri->vqattrs, name); +} diff --git a/nss/lib/util/pkcs11uri.h b/nss/lib/util/pkcs11uri.h new file mode 100644 index 0000000..662c854 --- /dev/null +++ b/nss/lib/util/pkcs11uri.h @@ -0,0 +1,67 @@ +/* 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 _PKCS11URI_H_ +#define _PKCS11URI_H_ 1 + +#include "seccomon.h" + +/* Path attributes defined in RFC7512. */ +#define PK11URI_PATTR_TOKEN "token" +#define PK11URI_PATTR_MANUFACTURER "manufacturer" +#define PK11URI_PATTR_SERIAL "serial" +#define PK11URI_PATTR_MODEL "model" +#define PK11URI_PATTR_LIBRARY_MANUFACTURER "library-manufacturer" +#define PK11URI_PATTR_LIBRARY_DESCRIPTION "library-description" +#define PK11URI_PATTR_LIBRARY_VERSION "library-version" +#define PK11URI_PATTR_OBJECT "object" +#define PK11URI_PATTR_TYPE "type" +#define PK11URI_PATTR_ID "id" +#define PK11URI_PATTR_SLOT_MANUFACTURER "slot-manufacturer" +#define PK11URI_PATTR_SLOT_DESCRIPTION "slot-description" +#define PK11URI_PATTR_SLOT_ID "slot-id" + +/* Query attributes defined in RFC7512. */ +#define PK11URI_QATTR_PIN_SOURCE "pin-source" +#define PK11URI_QATTR_PIN_VALUE "pin-value" +#define PK11URI_QATTR_MODULE_NAME "module-name" +#define PK11URI_QATTR_MODULE_PATH "module-path" + +SEC_BEGIN_PROTOS + +/* A PK11URI object is an immutable structure that holds path and + * query attributes of a PKCS#11 URI. */ +struct PK11URIStr; +typedef struct PK11URIStr PK11URI; + +struct PK11URIAttributeStr { + const char *name; + const char *value; +}; +typedef struct PK11URIAttributeStr PK11URIAttribute; + +/* Create a new PK11URI object from a set of attributes. */ +extern PK11URI *PK11URI_CreateURI(const PK11URIAttribute *pattrs, + size_t num_pattrs, + const PK11URIAttribute *qattrs, + size_t num_qattrs); + +/* Parse PKCS#11 URI and return a new PK11URI object. */ +extern PK11URI *PK11URI_ParseURI(const char *string); + +/* Format a PK11URI object to a string. */ +extern char *PK11URI_FormatURI(PLArenaPool *arena, PK11URI *uri); + +/* Destroy a PK11URI object. */ +extern void PK11URI_DestroyURI(PK11URI *uri); + +/* Retrieve a path attribute with the given name. */ +extern const char *PK11URI_GetPathAttribute(PK11URI *uri, const char *name); + +/* Retrieve a query attribute with the given name. */ +extern const char *PK11URI_GetQueryAttribute(PK11URI *uri, const char *name); + +SEC_END_PROTOS + +#endif /* _PKCS11URI_H_ */ diff --git a/nss/lib/util/secasn1.h b/nss/lib/util/secasn1.h index b6292cd..78cab0a 100644 --- a/nss/lib/util/secasn1.h +++ b/nss/lib/util/secasn1.h @@ -54,6 +54,18 @@ extern void SEC_ASN1DecoderSetNotifyProc(SEC_ASN1DecoderContext *cx, extern void SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx); +/* Sets the maximum size that should be allocated for a single ASN.1 + * element. Set to 0 to indicate there is no limit. + * + * Note: This does not set the maximum size overall that may be allocated + * while parsing, nor does it guarantee that the decoder won't allocate + * more than |max_size| while parsing an individual element; rather, it + * merely guarantees that any individual allocation for returned data + * should not exceed |max_size|. +*/ +extern void SEC_ASN1DecoderSetMaximumElementSize(SEC_ASN1DecoderContext *cx, + unsigned long max_size); + extern SECStatus SEC_ASN1Decode(PLArenaPool *pool, void *dest, const SEC_ASN1Template *t, const char *buf, long len); diff --git a/nss/lib/util/secasn1d.c b/nss/lib/util/secasn1d.c index 797640d..e6abb5f 100644 --- a/nss/lib/util/secasn1d.c +++ b/nss/lib/util/secasn1d.c @@ -292,6 +292,17 @@ struct sec_DecoderContext_struct { sec_asn1d_state *current; sec_asn1d_parse_status status; + /* The maximum size the caller is willing to allow a single element + * to be before returning an error. + * + * In the case of an indefinite length element, this is the sum total + * of all child elements. + * + * In the case of a definite length element, this represents the maximum + * size of the top-level element. + */ + unsigned long max_element_size; + SEC_ASN1NotifyProc notify_proc; /* call before/after handling field */ void *notify_arg; /* argument to notify_proc */ PRBool during_notify; /* true during call to notify_proc */ @@ -1288,6 +1299,13 @@ sec_asn1d_prepare_for_contents(sec_asn1d_state *state) alloc_len += subitem->len; } + if (state->top->max_element_size > 0 && + alloc_len > state->top->max_element_size) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + state->top->status = decodeError; + return; + } + item->data = (unsigned char *)sec_asn1d_zalloc(poolp, alloc_len); if (item->data == NULL) { state->top->status = decodeError; @@ -1396,6 +1414,13 @@ sec_asn1d_prepare_for_contents(sec_asn1d_state *state) if (state->dest != NULL) { item = (SECItem *)(state->dest); item->len = 0; + if (state->top->max_element_size > 0 && + state->contents_length > state->top->max_element_size) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + state->top->status = decodeError; + return; + } + if (state->top->filter_only) { item->data = NULL; } else { @@ -2223,6 +2248,13 @@ sec_asn1d_concat_substrings(sec_asn1d_state *state) alloc_len = item_len; } + if (state->top->max_element_size > 0 && + alloc_len > state->top->max_element_size) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); + state->top->status = decodeError; + return; + } + item = (SECItem *)(state->dest); PORT_Assert(item != NULL); PORT_Assert(item->data == NULL); @@ -2726,7 +2758,7 @@ SEC_ASN1DecoderUpdate(SEC_ASN1DecoderContext *cx, #ifdef DEBUG_ASN1D_STATES printf("\nPLACE = %s, next byte = 0x%02x, %08x[%d]\n", (state->place >= 0 && state->place <= notInUse) ? place_names[state->place] : "(undefined)", - (unsigned int)((unsigned char *)buf)[consumed], + len ? (unsigned int)((unsigned char *)buf)[consumed] : 0, buf, consumed); dump_states(cx); #endif /* DEBUG_ASN1D_STATES */ @@ -3042,6 +3074,13 @@ SEC_ASN1DecoderClearNotifyProc(SEC_ASN1DecoderContext *cx) } void +SEC_ASN1DecoderSetMaximumElementSize(SEC_ASN1DecoderContext *cx, + unsigned long max_size) +{ + cx->max_element_size = max_size; +} + +void SEC_ASN1DecoderAbort(SEC_ASN1DecoderContext *cx, int error) { PORT_Assert(cx); @@ -3061,6 +3100,10 @@ SEC_ASN1Decode(PLArenaPool *poolp, void *dest, if (dcx == NULL) return SECFailure; + /* In one-shot mode, there's no possibility of streaming data beyond the + * length of len */ + SEC_ASN1DecoderSetMaximumElementSize(dcx, len); + urv = SEC_ASN1DecoderUpdate(dcx, buf, len); frv = SEC_ASN1DecoderFinish(dcx); diff --git a/nss/lib/util/secport.h b/nss/lib/util/secport.h index 0f4b08f..fb9ff4e 100644 --- a/nss/lib/util/secport.h +++ b/nss/lib/util/secport.h @@ -72,8 +72,8 @@ * and does not use a lock to protect accesses. This makes it cheaper but * less general. It is best used for arena pools that (a) are hot, (b) have * lifetimes bounded within a single function, and (c) don't need locking. - * Use PORT_InitArena() and PORT_DestroyArena() to initialize and finalize - * PORTCheapArenaPools. + * Use PORT_InitCheapArena() and PORT_DestroyCheapArena() to initialize and + * finalize PORTCheapArenaPools. * * All the other PORT_Arena* functions will operate safely with either * subclass. diff --git a/nss/lib/util/util.gyp b/nss/lib/util/util.gyp index 9f3a74b..74eaef4 100644 --- a/nss/lib/util/util.gyp +++ b/nss/lib/util/util.gyp @@ -21,6 +21,7 @@ 'nssrwlk.c', 'oidstring.c', 'pkcs1sig.c', + 'pkcs11uri.c', 'portreg.c', 'quickder.c', 'secalgid.c', diff --git a/nss/lib/util/utilmod.c b/nss/lib/util/utilmod.c index e056806..971b6c1 100644 --- a/nss/lib/util/utilmod.c +++ b/nss/lib/util/utilmod.c @@ -232,10 +232,15 @@ nssutil_ReadSecmodDB(const char *appName, internal = PR_FALSE; /* is this an internal module */ skipParams = PR_FALSE; /* did we find an override parameter block*/ paramsValue = NULL; /* the current parameter block value */ - while (fgets(line, sizeof(line), fd) != NULL) { - int len = PORT_Strlen(line); + do { + int len; + + if (fgets(line, sizeof(line), fd) == NULL) { + goto endloop; + } /* remove the ending newline */ + len = PORT_Strlen(line); if (len && line[len - 1] == '\n') { len--; line[len] = 0; @@ -344,6 +349,7 @@ nssutil_ReadSecmodDB(const char *appName, continue; } + endloop: /* * if we are here, we have found a complete stanza. Now write out * any param section we may have found. @@ -379,7 +385,7 @@ nssutil_ReadSecmodDB(const char *appName, moduleString = NULL; internal = PR_FALSE; skipParams = PR_FALSE; - } + } while (!feof(fd)); if (moduleString) { PORT_Free(moduleString); |