summaryrefslogtreecommitdiff
path: root/nss/lib/certdb
diff options
context:
space:
mode:
Diffstat (limited to 'nss/lib/certdb')
-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
6 files changed, 178 insertions, 47 deletions
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.
*/