summaryrefslogtreecommitdiff
path: root/nss/lib
diff options
context:
space:
mode:
Diffstat (limited to 'nss/lib')
-rw-r--r--nss/lib/base/error.c3
-rw-r--r--nss/lib/certdb/alg1485.c21
-rw-r--r--nss/lib/certdb/cert.h21
-rw-r--r--nss/lib/certdb/certdb.c56
-rw-r--r--nss/lib/certdb/certi.h23
-rw-r--r--nss/lib/certdb/genname.c37
-rw-r--r--nss/lib/certdb/stanpcertdb.c67
-rw-r--r--nss/lib/certhigh/certhigh.c18
-rw-r--r--nss/lib/certhigh/certhtml.c25
-rw-r--r--nss/lib/certhigh/ocsp.c4
-rw-r--r--nss/lib/ckfw/builtins/builtins.gyp12
-rwxr-xr-xnss/lib/ckfw/builtins/certdata.py18
-rw-r--r--nss/lib/ckfw/builtins/certdata.txt1137
-rw-r--r--nss/lib/ckfw/builtins/nssckbi.h39
-rw-r--r--nss/lib/cryptohi/dsautil.c11
-rw-r--r--nss/lib/cryptohi/keyi.h7
-rw-r--r--nss/lib/cryptohi/keythi.h8
-rw-r--r--nss/lib/cryptohi/seckey.c77
-rw-r--r--nss/lib/cryptohi/secsign.c15
-rw-r--r--nss/lib/dev/dev.h9
-rw-r--r--nss/lib/dev/devslot.c27
-rw-r--r--nss/lib/dev/devtoken.c93
-rw-r--r--nss/lib/freebl/Makefile17
-rw-r--r--nss/lib/freebl/blapi.h15
-rw-r--r--nss/lib/freebl/blapii.h9
-rw-r--r--nss/lib/freebl/blapit.h1
-rw-r--r--nss/lib/freebl/blinit.c119
-rw-r--r--nss/lib/freebl/det_rng.c82
-rw-r--r--nss/lib/freebl/dh.c13
-rw-r--r--nss/lib/freebl/drbg.c47
-rw-r--r--nss/lib/freebl/ec.c39
-rw-r--r--nss/lib/freebl/ecdecode.c125
-rw-r--r--nss/lib/freebl/ecl/README104
-rw-r--r--nss/lib/freebl/ecl/curve25519_64.c2
-rw-r--r--nss/lib/freebl/ecl/ecl-curve.h218
-rw-r--r--nss/lib/freebl/ecl/ecl-priv.h7
-rw-r--r--nss/lib/freebl/ecl/ecl.c127
-rw-r--r--nss/lib/freebl/ecl/ecl.h13
-rw-r--r--nss/lib/freebl/ecl/ecl_curve.c93
-rw-r--r--nss/lib/freebl/ecl/eclt.h30
-rw-r--r--nss/lib/freebl/ecl/ecp_25519.c3
-rw-r--r--nss/lib/freebl/ecl/ecp_jm.c11
-rw-r--r--nss/lib/freebl/ecl/tests/ec_naft.c121
-rw-r--r--nss/lib/freebl/ecl/tests/ecp_test.c409
-rw-r--r--nss/lib/freebl/ecl/uint128.c5
-rw-r--r--nss/lib/freebl/exports.gyp1
-rw-r--r--nss/lib/freebl/freebl.gyp268
-rw-r--r--nss/lib/freebl/freebl_base.gypi201
-rw-r--r--nss/lib/freebl/ldvector.c6
-rw-r--r--nss/lib/freebl/loader.c8
-rw-r--r--nss/lib/freebl/loader.h6
-rw-r--r--nss/lib/freebl/manifest.mn4
-rw-r--r--nss/lib/freebl/mpi/README3
-rw-r--r--nss/lib/freebl/mpi/mpi-config.h4
-rw-r--r--nss/lib/freebl/mpi/mpi.c52
-rw-r--r--nss/lib/freebl/mpi/mpi.h2
-rw-r--r--nss/lib/freebl/mpi/mpprime.c5
-rw-r--r--nss/lib/freebl/mpi/mpprime.h7
-rw-r--r--nss/lib/freebl/os2_rand.c334
-rw-r--r--nss/lib/freebl/rijndael.c67
-rw-r--r--nss/lib/freebl/rsa.c19
-rw-r--r--nss/lib/freebl/rsapkcs.c221
-rw-r--r--nss/lib/freebl/sysrand.c37
-rw-r--r--nss/lib/freebl/unix_rand.c276
-rw-r--r--nss/lib/freebl/unix_urandom.c50
-rw-r--r--nss/lib/jar/jar.gyp43
-rw-r--r--nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c4
-rw-r--r--nss/lib/nss/nss.def18
-rw-r--r--nss/lib/nss/nss.h6
-rw-r--r--nss/lib/pk11wrap/dev3hack.c4
-rw-r--r--nss/lib/pk11wrap/pk11akey.c8
-rw-r--r--nss/lib/pk11wrap/pk11cert.c387
-rw-r--r--nss/lib/pk11wrap/pk11load.c26
-rw-r--r--nss/lib/pk11wrap/pk11mech.c4
-rw-r--r--nss/lib/pk11wrap/pk11obj.c12
-rw-r--r--nss/lib/pk11wrap/pk11pbe.c58
-rw-r--r--nss/lib/pk11wrap/pk11pk12.c121
-rw-r--r--nss/lib/pk11wrap/pk11priv.h13
-rw-r--r--nss/lib/pk11wrap/pk11pub.h8
-rw-r--r--nss/lib/pk11wrap/pk11skey.c48
-rw-r--r--nss/lib/pk11wrap/pk11slot.c172
-rw-r--r--nss/lib/pk11wrap/pk11util.c53
-rw-r--r--nss/lib/pk11wrap/pk11wrap.gyp73
-rw-r--r--nss/lib/pk11wrap/secmodti.h2
-rw-r--r--nss/lib/pkcs12/p12d.c46
-rw-r--r--nss/lib/pkcs12/p12e.c23
-rw-r--r--nss/lib/pkcs12/p12local.c67
-rw-r--r--nss/lib/pkcs12/p12local.h11
-rw-r--r--nss/lib/pkcs12/p12plcy.c3
-rw-r--r--nss/lib/pkcs7/p7create.c53
-rw-r--r--nss/lib/pkcs7/p7encode.c2
-rw-r--r--nss/lib/pkcs7/secpkcs7.h20
-rw-r--r--nss/lib/pki/cryptocontext.c57
-rw-r--r--nss/lib/pki/nsspki.h12
-rw-r--r--nss/lib/pki/pki3hack.c2
-rw-r--r--nss/lib/pki/trustdomain.c36
-rw-r--r--nss/lib/softoken/legacydb/dbmshim.c79
-rw-r--r--nss/lib/softoken/legacydb/legacydb.gyp2
-rw-r--r--nss/lib/softoken/legacydb/pcertdb.c11
-rw-r--r--nss/lib/softoken/lowpbe.c11
-rw-r--r--nss/lib/softoken/pkcs11.c22
-rw-r--r--nss/lib/softoken/pkcs11c.c38
-rw-r--r--nss/lib/softoken/pkcs11u.c6
-rw-r--r--nss/lib/softoken/sdb.c4
-rw-r--r--nss/lib/softoken/softkver.h6
-rw-r--r--nss/lib/softoken/softoken.gyp72
-rw-r--r--nss/lib/softoken/softoken.h2
-rw-r--r--nss/lib/ssl/SSLerrs.h8
-rw-r--r--nss/lib/ssl/config.mk4
-rw-r--r--nss/lib/ssl/dtlscon.c58
-rw-r--r--nss/lib/ssl/ssl.def13
-rw-r--r--nss/lib/ssl/ssl.gyp4
-rw-r--r--nss/lib/ssl/ssl.h43
-rw-r--r--nss/lib/ssl/ssl3con.c721
-rw-r--r--nss/lib/ssl/ssl3ecc.c45
-rw-r--r--nss/lib/ssl/ssl3ext.c34
-rw-r--r--nss/lib/ssl/ssl3ext.h17
-rw-r--r--nss/lib/ssl/ssl3exthandle.c1126
-rw-r--r--nss/lib/ssl/ssl3exthandle.h3
-rw-r--r--nss/lib/ssl/ssl3gthr.c31
-rw-r--r--nss/lib/ssl/ssl3prot.h13
-rw-r--r--nss/lib/ssl/sslcert.c785
-rw-r--r--nss/lib/ssl/sslcert.h41
-rw-r--r--nss/lib/ssl/ssldef.c2
-rw-r--r--nss/lib/ssl/sslerr.h2
-rw-r--r--nss/lib/ssl/sslimpl.h114
-rw-r--r--nss/lib/ssl/sslinfo.c27
-rw-r--r--nss/lib/ssl/sslmutex.c3
-rw-r--r--nss/lib/ssl/sslmutex.h3
-rw-r--r--nss/lib/ssl/sslnonce.c16
-rw-r--r--nss/lib/ssl/sslsecur.c77
-rw-r--r--nss/lib/ssl/sslsnce.c472
-rw-r--r--nss/lib/ssl/sslsock.c284
-rw-r--r--nss/lib/ssl/sslt.h24
-rw-r--r--nss/lib/ssl/tls13con.c278
-rw-r--r--nss/lib/ssl/tls13con.h1
-rw-r--r--nss/lib/ssl/tls13exthandle.c74
-rw-r--r--nss/lib/util/ciferfam.h3
-rw-r--r--nss/lib/util/eccutil.h5
-rw-r--r--nss/lib/util/exports.gyp1
-rw-r--r--nss/lib/util/manifest.mn2
-rw-r--r--nss/lib/util/nssb64d.c43
-rw-r--r--nss/lib/util/nssb64e.c25
-rw-r--r--nss/lib/util/nssutil.def17
-rw-r--r--nss/lib/util/nssutil.h6
-rw-r--r--nss/lib/util/pkcs11n.h8
-rw-r--r--nss/lib/util/pkcs11uri.c833
-rw-r--r--nss/lib/util/pkcs11uri.h67
-rw-r--r--nss/lib/util/secasn1.h12
-rw-r--r--nss/lib/util/secasn1d.c45
-rw-r--r--nss/lib/util/secport.h4
-rw-r--r--nss/lib/util/util.gyp1
-rw-r--r--nss/lib/util/utilmod.c12
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, &copyk->u.ec.DEREncodedParams,
- &pubk->u.ec.DEREncodedParams);
+ rv = seckey_HasCurveOID(pubk);
if (rv != SECSuccess) {
break;
}
- rv = seckey_SetPointEncoding(arena, copyk);
+ rv = SECITEM_CopyItem(arena, &copyk->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, &copyk->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, &params->fieldID.u.prime,
- curveParams->irr));
- } else {
- CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.poly,
- curveParams->irr));
+ if (field_type != ec_field_GFp && field_type != ec_field_plain) {
+ return SECFailure;
}
- CHECK_OK(hexString2SECItem(params->arena, &params->curve.a,
- curveParams->curvea));
- CHECK_OK(hexString2SECItem(params->arena, &params->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, &params->base, genenc));
- CHECK_OK(hexString2SECItem(params->arena, &params->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(&copy, &encryptedTicket->key_name,
SESS_TICKET_KEY_NAME_LEN) !=
SECSuccess)
return SECFailure;
- if (ssl3_ConsumeFromItem(data, &enc_session_ticket->iv,
+ if (ssl3_ConsumeFromItem(&copy, &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, &copy.data, &copy.len) !=
SECSuccess)
return SECFailure;
- if (ssl3_ConsumeFromItem(data, &enc_session_ticket->mac,
+ if (ssl3_ConsumeFromItem(&copy, &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);