diff options
Diffstat (limited to 'nss/lib/certdb')
-rw-r--r-- | nss/lib/certdb/alg1485.c | 21 | ||||
-rw-r--r-- | nss/lib/certdb/cert.h | 21 | ||||
-rw-r--r-- | nss/lib/certdb/certdb.c | 56 | ||||
-rw-r--r-- | nss/lib/certdb/certi.h | 23 | ||||
-rw-r--r-- | nss/lib/certdb/genname.c | 37 | ||||
-rw-r--r-- | nss/lib/certdb/stanpcertdb.c | 67 |
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. */ |