From c248efbb56e81d97dd959bcb95aeb7835a4979ef Mon Sep 17 00:00:00 2001 From: cvs2hg Date: Mon, 10 Jul 2000 20:38:42 +0000 Subject: fixup commit for tag 'CONRAD_DYN_PROFILE_TAG' --- security/nss/lib/certdb/.cvsignore | 1 - security/nss/lib/certdb/Makefile | 76 - security/nss/lib/certdb/alg1485.c | 953 ----- security/nss/lib/certdb/cdbhdl.h | 57 - security/nss/lib/certdb/cert.h | 1387 ------- security/nss/lib/certdb/certdb.c | 2271 ----------- security/nss/lib/certdb/certdb.h | 396 -- security/nss/lib/certdb/certinit.c | 399 -- security/nss/lib/certdb/certt.h | 804 ---- security/nss/lib/certdb/certv3.c | 406 -- security/nss/lib/certdb/certxutl.c | 482 --- security/nss/lib/certdb/certxutl.h | 79 - security/nss/lib/certdb/config.mk | 44 - security/nss/lib/certdb/crl.c | 387 -- security/nss/lib/certdb/genname.c | 1589 -------- security/nss/lib/certdb/genname.h | 125 - security/nss/lib/certdb/manifest.mn | 76 - security/nss/lib/certdb/pcertdb.c | 7340 ----------------------------------- security/nss/lib/certdb/polcyxtn.c | 541 --- security/nss/lib/certdb/secname.c | 625 --- security/nss/lib/certdb/xauthkid.c | 147 - security/nss/lib/certdb/xbsconst.c | 167 - security/nss/lib/certdb/xconst.c | 253 -- security/nss/lib/certdb/xconst.h | 85 - 24 files changed, 18690 deletions(-) delete mode 100644 security/nss/lib/certdb/.cvsignore delete mode 100644 security/nss/lib/certdb/Makefile delete mode 100644 security/nss/lib/certdb/alg1485.c delete mode 100644 security/nss/lib/certdb/cdbhdl.h delete mode 100644 security/nss/lib/certdb/cert.h delete mode 100644 security/nss/lib/certdb/certdb.c delete mode 100644 security/nss/lib/certdb/certdb.h delete mode 100644 security/nss/lib/certdb/certinit.c delete mode 100644 security/nss/lib/certdb/certt.h delete mode 100644 security/nss/lib/certdb/certv3.c delete mode 100644 security/nss/lib/certdb/certxutl.c delete mode 100644 security/nss/lib/certdb/certxutl.h delete mode 100644 security/nss/lib/certdb/config.mk delete mode 100644 security/nss/lib/certdb/crl.c delete mode 100644 security/nss/lib/certdb/genname.c delete mode 100644 security/nss/lib/certdb/genname.h delete mode 100644 security/nss/lib/certdb/manifest.mn delete mode 100644 security/nss/lib/certdb/pcertdb.c delete mode 100644 security/nss/lib/certdb/polcyxtn.c delete mode 100644 security/nss/lib/certdb/secname.c delete mode 100644 security/nss/lib/certdb/xauthkid.c delete mode 100644 security/nss/lib/certdb/xbsconst.c delete mode 100644 security/nss/lib/certdb/xconst.c delete mode 100644 security/nss/lib/certdb/xconst.h (limited to 'security/nss/lib/certdb') diff --git a/security/nss/lib/certdb/.cvsignore b/security/nss/lib/certdb/.cvsignore deleted file mode 100644 index ec60123e5..000000000 --- a/security/nss/lib/certdb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -nscertinit.c diff --git a/security/nss/lib/certdb/Makefile b/security/nss/lib/certdb/Makefile deleted file mode 100644 index 12eff17ab..000000000 --- a/security/nss/lib/certdb/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -####################################################################### -# (1) Include initial platform-independent assignments (MANDATORY). # -####################################################################### - -include manifest.mn - -####################################################################### -# (2) Include "global" configuration information. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/config.mk - -####################################################################### -# (3) Include "component" configuration information. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (4) Include "local" platform-dependent assignments (OPTIONAL). # -####################################################################### - -include config.mk - -####################################################################### -# (5) Execute "global" rules. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/rules.mk - -####################################################################### -# (6) Execute "component" rules. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (7) Execute "local" rules. (OPTIONAL). # -####################################################################### - -export:: private_export - diff --git a/security/nss/lib/certdb/alg1485.c b/security/nss/lib/certdb/alg1485.c deleted file mode 100644 index f9b2c7ae5..000000000 --- a/security/nss/lib/certdb/alg1485.c +++ /dev/null @@ -1,953 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "cert.h" -#include "xconst.h" -#include "genname.h" -#include "secitem.h" -#include "secerr.h" - -struct NameToKind { - char *name; - SECOidTag kind; -}; - -static struct NameToKind name2kinds[] = { - { "CN", SEC_OID_AVA_COMMON_NAME, }, - { "ST", SEC_OID_AVA_STATE_OR_PROVINCE, }, - { "OU", SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, }, - { "DC", SEC_OID_AVA_DC, }, - { "C", SEC_OID_AVA_COUNTRY_NAME, }, - { "O", SEC_OID_AVA_ORGANIZATION_NAME, }, - { "L", SEC_OID_AVA_LOCALITY, }, - { "dnQualifier", SEC_OID_AVA_DN_QUALIFIER, }, - { "E", SEC_OID_PKCS9_EMAIL_ADDRESS, }, - { "UID", SEC_OID_RFC1274_UID, }, - { "MAIL", SEC_OID_RFC1274_MAIL, }, - { 0, SEC_OID_UNKNOWN }, -}; - -#define C_DOUBLE_QUOTE '\042' - -#define C_BACKSLASH '\134' - -#define C_EQUAL '=' - -#define OPTIONAL_SPACE(c) \ - (((c) == ' ') || ((c) == '\r') || ((c) == '\n')) - -#define SPECIAL_CHAR(c) \ - (((c) == ',') || ((c) == '=') || ((c) == C_DOUBLE_QUOTE) || \ - ((c) == '\r') || ((c) == '\n') || ((c) == '+') || \ - ((c) == '<') || ((c) == '>') || ((c) == '#') || \ - ((c) == ';') || ((c) == C_BACKSLASH)) - - - - - - - -#if 0 -/* -** Find the start and end of a . Strings can be wrapped in double -** quotes to protect special characters. -*/ -static int BracketThing(char **startp, char *end, char *result) -{ - char *start = *startp; - char c; - - /* Skip leading white space */ - while (start < end) { - c = *start++; - if (!OPTIONAL_SPACE(c)) { - start--; - break; - } - } - if (start == end) return 0; - - switch (*start) { - case '#': - /* Process hex thing */ - start++; - *startp = start; - while (start < end) { - c = *start++; - if (((c >= '0') && (c <= '9')) || - ((c >= 'a') && (c <= 'f')) || - ((c >= 'A') && (c <= 'F'))) { - continue; - } - break; - } - rv = IS_HEX; - break; - - case C_DOUBLE_QUOTE: - start++; - *startp = start; - while (start < end) { - c = *start++; - if (c == C_DOUBLE_QUOTE) { - break; - } - *result++ = c; - } - rv = IS_STRING; - break; - - default: - while (start < end) { - c = *start++; - if (SPECIAL_CHAR(c)) { - start--; - break; - } - *result++ = c; - } - rv = IS_STRING; - break; - } - - /* Terminate result string */ - *result = 0; - return start; -} - -static char *BracketSomething(char **startp, char* end, int spacesOK) -{ - char *start = *startp; - char c; - int stopAtDQ; - - /* Skip leading white space */ - while (start < end) { - c = *start; - if (!OPTIONAL_SPACE(c)) { - break; - } - start++; - } - if (start == end) return 0; - stopAtDQ = 0; - if (*start == C_DOUBLE_QUOTE) { - stopAtDQ = 1; - } - - /* - ** Find the end of the something. The something is terminated most of - ** the time by a space. However, if spacesOK is true then it is - ** terminated by a special character only. - */ - *startp = start; - while (start < end) { - c = *start; - if (stopAtDQ) { - if (c == C_DOUBLE_QUOTE) { - *start = ' '; - break; - } - } else { - if (SPECIAL_CHAR(c)) { - break; - } - if (!spacesOK && OPTIONAL_SPACE(c)) { - break; - } - } - start++; - } - return start; -} -#endif - -#define IS_PRINTABLE(c) \ - ((((c) >= 'a') && ((c) <= 'z')) || \ - (((c) >= 'A') && ((c) <= 'Z')) || \ - (((c) >= '0') && ((c) <= '9')) || \ - ((c) == ' ') || \ - ((c) == '\'') || \ - ((c) == '\050') || /* ( */ \ - ((c) == '\051') || /* ) */ \ - (((c) >= '+') && ((c) <= '/')) || /* + , - . / */ \ - ((c) == ':') || \ - ((c) == '=') || \ - ((c) == '?')) - -static PRBool -IsPrintable(unsigned char *data, unsigned len) -{ - unsigned char ch, *end; - - end = data + len; - while (data < end) { - ch = *data++; - if (!IS_PRINTABLE(ch)) { - return PR_FALSE; - } - } - return PR_TRUE; -} - -static void -skipSpace(char **pbp, char *endptr) -{ - char *bp = *pbp; - while (bp < endptr && OPTIONAL_SPACE(*bp)) { - bp++; - } - *pbp = bp; -} - -static SECStatus -scanTag(char **pbp, char *endptr, char *tagBuf, int tagBufSize) -{ - char *bp, *tagBufp; - int taglen; - - PORT_Assert(tagBufSize > 0); - - /* skip optional leading space */ - skipSpace(pbp, endptr); - if (*pbp == endptr) { - /* nothing left */ - return SECFailure; - } - - /* fill tagBuf */ - taglen = 0; - bp = *pbp; - tagBufp = tagBuf; - while (bp < endptr && !OPTIONAL_SPACE(*bp) && (*bp != C_EQUAL)) { - if (++taglen >= tagBufSize) { - *pbp = bp; - return SECFailure; - } - *tagBufp++ = *bp++; - } - /* null-terminate tagBuf -- guaranteed at least one space left */ - *tagBufp++ = 0; - *pbp = bp; - - /* skip trailing spaces till we hit something - should be an equal sign */ - skipSpace(pbp, endptr); - if (*pbp == endptr) { - /* nothing left */ - return SECFailure; - } - if (**pbp != C_EQUAL) { - /* should be an equal sign */ - return SECFailure; - } - /* skip over the equal sign */ - (*pbp)++; - - return SECSuccess; -} - -static SECStatus -scanVal(char **pbp, char *endptr, char *valBuf, int valBufSize) -{ - char *bp, *valBufp; - int vallen; - PRBool isQuoted; - - PORT_Assert(valBufSize > 0); - - /* skip optional leading space */ - skipSpace(pbp, endptr); - if(*pbp == endptr) { - /* nothing left */ - return SECFailure; - } - - bp = *pbp; - - /* quoted? */ - if (*bp == C_DOUBLE_QUOTE) { - isQuoted = PR_TRUE; - /* skip over it */ - bp++; - } else { - isQuoted = PR_FALSE; - } - - valBufp = valBuf; - vallen = 0; - while (bp < endptr) { - char c = *bp; - if (c == C_BACKSLASH) { - /* escape character */ - bp++; - if (bp >= endptr) { - /* escape charater must appear with paired char */ - *pbp = bp; - return SECFailure; - } - } else if (!isQuoted && SPECIAL_CHAR(c)) { - /* unescaped special and not within quoted value */ - break; - } else if (c == C_DOUBLE_QUOTE) { - /* reached unescaped double quote */ - break; - } - /* append character */ - vallen++; - if (vallen >= valBufSize) { - *pbp = bp; - return SECFailure; - } - *valBufp++ = *bp++; - } - - /* stip trailing spaces from unquoted values */ - if (!isQuoted) { - if (valBufp > valBuf) { - valBufp--; - while ((valBufp > valBuf) && OPTIONAL_SPACE(*valBufp)) { - valBufp--; - } - valBufp++; - } - } - - if (isQuoted) { - /* insist that we stopped on a double quote */ - if (*bp != C_DOUBLE_QUOTE) { - *pbp = bp; - return SECFailure; - } - /* skip over the quote and skip optional space */ - bp++; - skipSpace(&bp, endptr); - } - - *pbp = bp; - - if (valBufp == valBuf) { - /* empty value -- not allowed */ - return SECFailure; - } - - /* null-terminate valBuf -- guaranteed at least one space left */ - *valBufp++ = 0; - - return SECSuccess; -} - -CERTAVA * -CERT_ParseRFC1485AVA(PRArenaPool *arena, char **pbp, char *endptr, - PRBool singleAVA) -{ - CERTAVA *a; - struct NameToKind *n2k; - int vt; - int valLen; - char *bp; - - char tagBuf[32]; - char valBuf[384]; - - if (scanTag(pbp, endptr, tagBuf, sizeof(tagBuf)) == SECFailure || - scanVal(pbp, endptr, valBuf, sizeof(valBuf)) == SECFailure) { - PORT_SetError(SEC_ERROR_INVALID_AVA); - return 0; - } - - /* insist that if we haven't finished we've stopped on a separator */ - bp = *pbp; - if (bp < endptr) { - if (singleAVA || (*bp != ',' && *bp != ';')) { - PORT_SetError(SEC_ERROR_INVALID_AVA); - *pbp = bp; - return 0; - } - /* ok, skip over separator */ - bp++; - } - *pbp = bp; - - for (n2k = name2kinds; n2k->name; n2k++) { - if (PORT_Strcasecmp(n2k->name, tagBuf) == 0) { - valLen = PORT_Strlen(valBuf); - if (n2k->kind == SEC_OID_AVA_COUNTRY_NAME) { - vt = SEC_ASN1_PRINTABLE_STRING; - if (valLen != 2) { - PORT_SetError(SEC_ERROR_INVALID_AVA); - return 0; - } - if (!IsPrintable((unsigned char*) valBuf, 2)) { - PORT_SetError(SEC_ERROR_INVALID_AVA); - return 0; - } - } else if ((n2k->kind == SEC_OID_PKCS9_EMAIL_ADDRESS) || - (n2k->kind == SEC_OID_RFC1274_MAIL)) { - vt = SEC_ASN1_IA5_STRING; - } else { - /* Hack -- for rationale see X.520 DirectoryString defn */ - if (IsPrintable((unsigned char*)valBuf, valLen)) { - vt = SEC_ASN1_PRINTABLE_STRING; - } else { - vt = SEC_ASN1_UNIVERSAL_STRING; - } - } - a = CERT_CreateAVA(arena, n2k->kind, vt, (char *) valBuf); - return a; - } - } - /* matched no kind -- invalid tag */ - PORT_SetError(SEC_ERROR_INVALID_AVA); - return 0; -} - -static CERTName * -ParseRFC1485Name(char *buf, int len) -{ - SECStatus rv; - CERTName *name; - char *bp, *e; - CERTAVA *ava; - CERTRDN *rdn; - - name = CERT_CreateName(NULL); - if (name == NULL) { - return NULL; - } - - e = buf + len; - bp = buf; - while (bp < e) { - ava = CERT_ParseRFC1485AVA(name->arena, &bp, e, PR_FALSE); - if (ava == 0) goto loser; - rdn = CERT_CreateRDN(name->arena, ava, 0); - if (rdn == 0) goto loser; - rv = CERT_AddRDN(name, rdn); - if (rv) goto loser; - skipSpace(&bp, e); - } - - if (name->rdns[0] == 0) { - /* empty name -- illegal */ - goto loser; - } - - /* Reverse order of RDNS to comply with RFC */ - { - CERTRDN **firstRdn; - CERTRDN **lastRdn; - CERTRDN *tmp; - - /* get first one */ - firstRdn = name->rdns; - - /* find last one */ - lastRdn = name->rdns; - while (*lastRdn) lastRdn++; - lastRdn--; - - /* reverse list */ - for ( ; firstRdn < lastRdn; firstRdn++, lastRdn--) { - tmp = *firstRdn; - *firstRdn = *lastRdn; - *lastRdn = tmp; - } - } - - /* return result */ - return name; - - loser: - CERT_DestroyName(name); - return NULL; -} - -CERTName * -CERT_AsciiToName(char *string) -{ - CERTName *name; - name = ParseRFC1485Name(string, PORT_Strlen(string)); - return name; -} - -/************************************************************************/ - -static SECStatus -AppendStr(char **bufp, unsigned *buflenp, char *str) -{ - char *buf; - unsigned bufLen, bufSize, len; - - /* Figure out how much to grow buf by (add in the '\0') */ - buf = *bufp; - bufLen = *buflenp; - len = PORT_Strlen(str); - bufSize = bufLen + len; - if (buf) { - buf = (char*) PORT_Realloc(buf, bufSize); - } else { - bufSize++; - buf = (char*) PORT_Alloc(bufSize); - } - if (!buf) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - *bufp = buf; - *buflenp = bufSize; - - /* Concatenate str onto buf */ - buf = buf + bufLen; - if (bufLen) buf--; /* stomp on old '\0' */ - PORT_Memcpy(buf, str, len+1); /* put in new null */ - return SECSuccess; -} - -SECStatus -CERT_RFC1485_EscapeAndQuote(char *dst, int dstlen, char *src, int srclen) -{ - int i, reqLen=0; - char *d = dst; - PRBool needsQuoting = PR_FALSE; - - /* need to make an initial pass to determine if quoting is needed */ - for (i = 0; i < srclen; i++) { - char c = src[i]; - reqLen++; - if (SPECIAL_CHAR(c)) { - /* entirety will need quoting */ - needsQuoting = PR_TRUE; - } - if (c == C_DOUBLE_QUOTE || c == C_BACKSLASH) { - /* this char will need escaping */ - reqLen++; - } - } - /* if it begins or ends in optional space it needs quoting */ - if (srclen > 0 && - (OPTIONAL_SPACE(src[srclen-1]) || OPTIONAL_SPACE(src[0]))) { - needsQuoting = PR_TRUE; - } - - if (needsQuoting) reqLen += 2; - - /* space for terminal null */ - reqLen++; - - if (reqLen > dstlen) { - PORT_SetError(SEC_ERROR_OUTPUT_LEN); - return SECFailure; - } - - d = dst; - if (needsQuoting) *d++ = C_DOUBLE_QUOTE; - for (i = 0; i < srclen; i++) { - char c = src[i]; - if (c == C_DOUBLE_QUOTE || c == C_BACKSLASH) { - /* escape it */ - *d++ = C_BACKSLASH; - } - *d++ = c; - } - if (needsQuoting) *d++ = C_DOUBLE_QUOTE; - *d++ = 0; - return SECSuccess; -} - -static SECStatus -AppendAVA(char **bufp, unsigned *buflenp, CERTAVA *ava) -{ - char *tagName; - char tmpBuf[384]; - unsigned len, maxLen; - int lenLen; - int tag; - SECStatus rv; - SECItem *avaValue = NULL; - - tag = CERT_GetAVATag(ava); - switch (tag) { - case SEC_OID_AVA_COUNTRY_NAME: - tagName = "C"; - maxLen = 2; - break; - case SEC_OID_AVA_ORGANIZATION_NAME: - tagName = "O"; - maxLen = 64; - break; - case SEC_OID_AVA_COMMON_NAME: - tagName = "CN"; - maxLen = 64; - break; - case SEC_OID_AVA_LOCALITY: - tagName = "L"; - maxLen = 128; - break; - case SEC_OID_AVA_STATE_OR_PROVINCE: - tagName = "ST"; - maxLen = 128; - break; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - tagName = "OU"; - maxLen = 64; - break; - case SEC_OID_AVA_DC: - tagName = "DC"; - maxLen = 128; - break; - case SEC_OID_AVA_DN_QUALIFIER: - tagName = "dnQualifier"; - maxLen = 0x7fff; - break; - case SEC_OID_PKCS9_EMAIL_ADDRESS: - tagName = "E"; - maxLen = 128; - break; - case SEC_OID_RFC1274_UID: - tagName = "UID"; - maxLen = 256; - break; - case SEC_OID_RFC1274_MAIL: - tagName = "MAIL"; - maxLen = 256; - break; - default: -#if 0 - PORT_SetError(SEC_ERROR_INVALID_AVA); - return SECFailure; -#else - rv = AppendStr(bufp, buflenp, "ERR=Unknown AVA"); - return rv; -#endif - } - - avaValue = CERT_DecodeAVAValue(&ava->value); - if(!avaValue) { - return SECFailure; - } - - /* Check value length */ - if ((avaValue->len < 2) || (avaValue->len > maxLen)) { - PORT_SetError(SEC_ERROR_INVALID_AVA); - return SECFailure; - } - - len = PORT_Strlen(tagName); - PORT_Memcpy(tmpBuf, tagName, len); - tmpBuf[len++] = '='; - - /* escape and quote as necessary */ - rv = CERT_RFC1485_EscapeAndQuote(tmpBuf+len, sizeof(tmpBuf)-len, - (char *)avaValue->data, avaValue->len); - SECITEM_FreeItem(avaValue, PR_TRUE); - if (rv) return SECFailure; - - rv = AppendStr(bufp, buflenp, tmpBuf); - return rv; -} - -char * -CERT_NameToAscii(CERTName *name) -{ - SECStatus rv; - CERTRDN** rdns; - CERTRDN** lastRdn; - CERTRDN** rdn; - CERTAVA** avas; - CERTAVA* ava; - PRBool first = PR_TRUE; - char *buf = NULL; - unsigned buflen = 0; - - rdns = name->rdns; - if (rdns == NULL) { - return NULL; - } - - /* find last RDN */ - lastRdn = rdns; - while (*lastRdn) lastRdn++; - lastRdn--; - - /* - * Loop over name contents in _reverse_ RDN order appending to string - */ - for (rdn = lastRdn; rdn >= rdns; rdn--) { - avas = (*rdn)->avas; - while ((ava = *avas++) != NULL) { - /* Put in comma separator */ - if (!first) { - rv = AppendStr(&buf, &buflen, ", "); - if (rv) goto loser; - } else { - first = PR_FALSE; - } - - /* Add in tag type plus value into buf */ - rv = AppendAVA(&buf, &buflen, ava); - if (rv) goto loser; - } - } - return buf; - loser: - PORT_Free(buf); - return NULL; -} - -/* - * Return the string representation of a DER encoded distinguished name - * "dername" - The DER encoded name to convert - */ -char * -CERT_DerNameToAscii(SECItem *dername) -{ - int rv; - PRArenaPool *arena = NULL; - CERTName name; - char *retstr = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( arena == NULL) { - goto loser; - } - - rv = SEC_ASN1DecodeItem(arena, &name, CERT_NameTemplate, dername); - - if ( rv != SECSuccess ) { - goto loser; - } - - retstr = CERT_NameToAscii(&name); - -loser: - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(retstr); -} - -static char * -CERT_GetNameElement(CERTName *name, int wantedTag) -{ - CERTRDN** rdns; - CERTRDN *rdn; - CERTAVA** avas; - CERTAVA* ava; - char *buf = 0; - int tag; - SECItem *decodeItem = NULL; - - rdns = name->rdns; - while ((rdn = *rdns++) != 0) { - avas = rdn->avas; - while ((ava = *avas++) != 0) { - tag = CERT_GetAVATag(ava); - if ( tag == wantedTag ) { - decodeItem = CERT_DecodeAVAValue(&ava->value); - if(!decodeItem) { - return NULL; - } - buf = (char *)PORT_ZAlloc(decodeItem->len + 1); - if ( buf ) { - PORT_Memcpy(buf, decodeItem->data, decodeItem->len); - buf[decodeItem->len] = 0; - } - SECITEM_FreeItem(decodeItem, PR_TRUE); - goto done; - } - } - } - - done: - return buf; -} - -char * -CERT_GetCertificateEmailAddress(CERTCertificate *cert) -{ - char *rawEmailAddr = NULL; - char *emailAddr = NULL; - SECItem subAltName; - SECStatus rv; - CERTGeneralName *nameList = NULL; - CERTGeneralName *current; - PRArenaPool *arena = NULL; - int i; - - subAltName.data = NULL; - - rawEmailAddr = CERT_GetNameElement(&(cert->subject), SEC_OID_PKCS9_EMAIL_ADDRESS); - if ( rawEmailAddr == NULL ) { - rawEmailAddr = CERT_GetNameElement(&(cert->subject), SEC_OID_RFC1274_MAIL); - } - if ( rawEmailAddr == NULL) { - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, &subAltName); - if (rv != SECSuccess) { - goto finish; - } - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) { - goto finish; - } - nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName); - if (!nameList ) { - goto finish; - } - if (nameList != NULL) { - do { - if (current->type == certDirectoryName) { - rawEmailAddr = CERT_GetNameElement(&(current->name.directoryName), - SEC_OID_PKCS9_EMAIL_ADDRESS); - if ( rawEmailAddr == NULL ) { - rawEmailAddr = CERT_GetNameElement(&(current->name.directoryName), - SEC_OID_RFC1274_MAIL); - } - } else if (current->type == certRFC822Name) { - rawEmailAddr = (char*)PORT_ZAlloc(current->name.other.len + 1); - if (!rawEmailAddr) { - goto finish; - } - PORT_Memcpy(rawEmailAddr, current->name.other.data, - current->name.other.len); - rawEmailAddr[current->name.other.len] = '\0'; - } - if (rawEmailAddr) { - break; - } - current = cert_get_next_general_name(current); - } while (current != nameList); - } - } - if (rawEmailAddr) { - emailAddr = (char*)PORT_ArenaZAlloc(cert->arena, PORT_Strlen(rawEmailAddr) + 1); - for (i = 0; i <= PORT_Strlen(rawEmailAddr); i++) { - emailAddr[i] = tolower(rawEmailAddr[i]); - } - } else { - emailAddr = NULL; - } - -finish: - if ( rawEmailAddr ) { - PORT_Free(rawEmailAddr); - } - - /* Don't free nameList, it's part of the arena. */ - - if (arena) { - PORT_FreeArena(arena, PR_FALSE); - } - - if ( subAltName.data ) { - SECITEM_FreeItem(&subAltName, PR_FALSE); - } - - return(emailAddr); -} - -char * -CERT_GetCertEmailAddress(CERTName *name) -{ - char *rawEmailAddr; - char *emailAddr; - - - rawEmailAddr = CERT_GetNameElement(name, SEC_OID_PKCS9_EMAIL_ADDRESS); - if ( rawEmailAddr == NULL ) { - rawEmailAddr = CERT_GetNameElement(name, SEC_OID_RFC1274_MAIL); - } - emailAddr = CERT_FixupEmailAddr(rawEmailAddr); - if ( rawEmailAddr ) { - PORT_Free(rawEmailAddr); - } - return(emailAddr); -} - -char * -CERT_GetCommonName(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_COMMON_NAME)); -} - -char * -CERT_GetCountryName(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_COUNTRY_NAME)); -} - -char * -CERT_GetLocalityName(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_LOCALITY)); -} - -char * -CERT_GetStateName(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_STATE_OR_PROVINCE)); -} - -char * -CERT_GetOrgName(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_ORGANIZATION_NAME)); -} - -char * -CERT_GetDomainComponentName(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_DC)); -} - -char * -CERT_GetOrgUnitName(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME)); -} - -char * -CERT_GetDnQualifier(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_AVA_DN_QUALIFIER)); -} - -char * -CERT_GetCertUid(CERTName *name) -{ - return(CERT_GetNameElement(name, SEC_OID_RFC1274_UID)); -} - diff --git a/security/nss/lib/certdb/cdbhdl.h b/security/nss/lib/certdb/cdbhdl.h deleted file mode 100644 index 916f8035d..000000000 --- a/security/nss/lib/certdb/cdbhdl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ -/* - * cdbhdl.h - certificate database handle - * private to the certdb module - * - * $Id$ - */ -#ifndef _CDBHDL_H_ -#define _CDBHDL_H_ - -#include "nspr.h" -#include "mcom_db.h" -#include "certt.h" - -/* - * Handle structure for open certificate databases - */ -struct CERTCertDBHandleStr { - DB *permCertDB; - DB *tempCertDB; - void *spkDigestInfo; - CERTStatusConfig *statusConfig; - PRMonitor *dbMon; -}; - -#endif diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h deleted file mode 100644 index c12b77489..000000000 --- a/security/nss/lib/certdb/cert.h +++ /dev/null @@ -1,1387 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * cert.h - public data structures and prototypes for the certificate library - * - * $Id$ - */ - -#ifndef _CERT_H_ -#define _CERT_H_ - -#include "plarena.h" -#include "plhash.h" -#include "prlong.h" -#include "prlog.h" - -#include "seccomon.h" -#include "secdert.h" -#include "secoidt.h" -#include "keyt.h" -#include "certt.h" - -SEC_BEGIN_PROTOS - -/**************************************************************************** - * - * RFC1485 ascii to/from X.? RelativeDistinguishedName (aka CERTName) - * - ****************************************************************************/ - -/* -** Convert an ascii RFC1485 encoded name into its CERTName equivalent. -*/ -extern CERTName *CERT_AsciiToName(char *string); - -/* -** Convert an CERTName into its RFC1485 encoded equivalent. -*/ -extern char *CERT_NameToAscii(CERTName *name); - -extern CERTAVA *CERT_CopyAVA(PRArenaPool *arena, CERTAVA *src); - -/* -** Examine an AVA and return the tag that refers to it. The AVA tags are -** defined as SEC_OID_AVA*. -*/ -extern SECOidTag CERT_GetAVATag(CERTAVA *ava); - -/* -** Compare two AVA's, returning the difference between them. -*/ -extern SECComparison CERT_CompareAVA(CERTAVA *a, CERTAVA *b); - -/* -** Create an RDN (relative-distinguished-name). The argument list is a -** NULL terminated list of AVA's. -*/ -extern CERTRDN *CERT_CreateRDN(PRArenaPool *arena, CERTAVA *avas, ...); - -/* -** Make a copy of "src" storing it in "dest". -*/ -extern SECStatus CERT_CopyRDN(PRArenaPool *arena, CERTRDN *dest, CERTRDN *src); - -/* -** Destory an RDN object. -** "rdn" the RDN to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void CERT_DestroyRDN(CERTRDN *rdn, PRBool freeit); - -/* -** Add an AVA to an RDN. -** "rdn" the RDN to add to -** "ava" the AVA to add -*/ -extern SECStatus CERT_AddAVA(PRArenaPool *arena, CERTRDN *rdn, CERTAVA *ava); - -/* -** Compare two RDN's, returning the difference between them. -*/ -extern SECComparison CERT_CompareRDN(CERTRDN *a, CERTRDN *b); - -/* -** Create an X.500 style name using a NULL terminated list of RDN's. -*/ -extern CERTName *CERT_CreateName(CERTRDN *rdn, ...); - -/* -** Make a copy of "src" storing it in "dest". Memory is allocated in -** "dest" for each of the appropriate sub objects. Memory is not freed in -** "dest" before allocation is done (use CERT_DestroyName(dest, PR_FALSE) to -** do that). -*/ -extern SECStatus CERT_CopyName(PRArenaPool *arena, CERTName *dest, CERTName *src); - -/* -** Destroy a Name object. -** "name" the CERTName to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void CERT_DestroyName(CERTName *name); - -/* -** Add an RDN to a name. -** "name" the name to add the RDN to -** "rdn" the RDN to add to name -*/ -extern SECStatus CERT_AddRDN(CERTName *name, CERTRDN *rdn); - -/* -** Compare two names, returning the difference between them. -*/ -extern SECComparison CERT_CompareName(CERTName *a, CERTName *b); - -/* -** Convert a CERTName into something readable -*/ -extern char *CERT_FormatName (CERTName *name); - -/* -** Convert a der-encoded integer to a hex printable string form. -** Perhaps this should be a SEC function but it's only used for certs. -*/ -extern char *CERT_Hexify (SECItem *i, int do_colon); - -/************************************************************************************** - * - * Certificate handling operations - * - **************************************************************************************/ - -/* -** Create a new validity object given two unix time values. -** "notBefore" the time before which the validity is not valid -** "notAfter" the time after which the validity is not valid -*/ -extern CERTValidity *CERT_CreateValidity(int64 notBefore, int64 notAfter); - -/* -** Destroy a validity object. -** "v" the validity to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void CERT_DestroyValidity(CERTValidity *v); - -/* -** Copy the "src" object to "dest". Memory is allocated in "dest" for -** each of the appropriate sub-objects. Memory in "dest" is not freed -** before memory is allocated (use CERT_DestroyValidity(v, PR_FALSE) to do -** that). -*/ -extern SECStatus CERT_CopyValidity - (PRArenaPool *arena, CERTValidity *dest, CERTValidity *src); - -/* -** Create a new certificate object. The result must be wrapped with an -** CERTSignedData to create a signed certificate. -** "serialNumber" the serial number -** "issuer" the name of the certificate issuer -** "validity" the validity period of the certificate -** "req" the certificate request that prompted the certificate issuance -*/ -extern CERTCertificate * -CERT_CreateCertificate (unsigned long serialNumber, CERTName *issuer, - CERTValidity *validity, CERTCertificateRequest *req); - -/* -** Destroy a certificate object -** "cert" the certificate to destroy -** NOTE: certificate's are reference counted. This call decrements the -** reference count, and if the result is zero, then the object is destroyed -** and optionally freed. -*/ -extern void CERT_DestroyCertificate(CERTCertificate *cert); - -/* -** Make a shallow copy of a certificate "c". Just increments the -** reference count on "c". -*/ -extern CERTCertificate *CERT_DupCertificate(CERTCertificate *c); - -/* -** Create a new certificate request. This result must be wrapped with an -** CERTSignedData to create a signed certificate request. -** "name" the subject name (who the certificate request is from) -** "spki" describes/defines the public key the certificate is for -** "attributes" if non-zero, some optional attribute data -*/ -extern CERTCertificateRequest * -CERT_CreateCertificateRequest (CERTName *name, CERTSubjectPublicKeyInfo *spki, - SECItem **attributes); - -/* -** Destroy a certificate-request object -** "r" the certificate-request to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void CERT_DestroyCertificateRequest(CERTCertificateRequest *r); - -/* -** Extract a public key object from a SubjectPublicKeyInfo -*/ -extern SECKEYPublicKey *CERT_ExtractPublicKey(CERTCertificate *cert); - -/* - * used to get a public key with Key Material ID. Only used for fortezza V1 - * certificates. - */ -extern SECKEYPublicKey *CERT_KMIDPublicKey(CERTCertificate *cert); - - -/* -** Retrieve the Key Type associated with the cert we're dealing with -*/ - -extern KeyType CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki); - -/* -** Initialize the certificate database. This is called to create -** the initial list of certificates in the database. -*/ -extern SECStatus CERT_InitCertDB(CERTCertDBHandle *handle); - -/* -** Default certificate database routines -*/ -extern void CERT_SetDefaultCertDB(CERTCertDBHandle *handle); - -extern CERTCertDBHandle *CERT_GetDefaultCertDB(void); - -extern CERTCertList *CERT_GetCertChainFromCert(CERTCertificate *cert, - int64 time, - SECCertUsage usage); - -/************************************************************************************ - * - * X.500 Name handling operations - * - ************************************************************************************/ - -/* -** Create an AVA (attribute-value-assertion) -** "arena" the memory arena to alloc from -** "kind" is one of SEC_OID_AVA_* -** "valueType" is one of DER_PRINTABLE_STRING, DER_IA5_STRING, or -** DER_T61_STRING -** "value" is the null terminated string containing the value -*/ -extern CERTAVA *CERT_CreateAVA - (PRArenaPool *arena, SECOidTag kind, int valueType, char *value); - -/* -** Extract the Distinguished Name from a DER encoded certificate -** "derCert" is the DER encoded certificate -** "derName" is the SECItem that the name is returned in -*/ -extern SECStatus CERT_NameFromDERCert(SECItem *derCert, SECItem *derName); - -/* -** Extract the Issuers Distinguished Name from a DER encoded certificate -** "derCert" is the DER encoded certificate -** "derName" is the SECItem that the name is returned in -*/ -extern SECStatus CERT_IssuerNameFromDERCert(SECItem *derCert, - SECItem *derName); - - - -/* -** Generate a database search key for a certificate, based on the -** issuer and serial number. -** "arena" the memory arena to alloc from -** "derCert" the DER encoded certificate -** "key" the returned key -*/ -extern SECStatus CERT_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key); - -extern SECStatus CERT_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, - SECItem *sn, SECItem *key); - -/* -** Generate a database search key for a crl, based on the -** issuer. -** "arena" the memory arena to alloc from -** "derCrl" the DER encoded crl -** "key" the returned key -*/ -extern SECStatus CERT_KeyFromDERCrl(PRArenaPool *arena, SECItem *derCrl, SECItem *key); - -/* -** Open the certificate database. Use callback to get name of database. -*/ -extern SECStatus CERT_OpenCertDB(CERTCertDBHandle *handle, PRBool readOnly, - CERTDBNameFunc namecb, void *cbarg); - -/* Open the certificate database. Use given filename for database. */ -extern SECStatus CERT_OpenCertDBFilename(CERTCertDBHandle *handle, - char *certdbname, PRBool readOnly); - -/* -** Open and initialize a cert database that is entirely in memory. This -** can be used when the permanent database can not be opened or created. -*/ -extern SECStatus CERT_OpenVolatileCertDB(CERTCertDBHandle *handle); - -/* -** Check the hostname to make sure that it matches the shexp that -** is given in the common name of the certificate. -*/ -extern SECStatus CERT_VerifyCertName(CERTCertificate *cert, const char *hostname); - -/* -** Add a domain name to the list of names that the user has explicitly -** allowed (despite cert name mismatches) for use with a server cert. -*/ -extern SECStatus CERT_AddOKDomainName(CERTCertificate *cert, const char *hostname); - -/* -** Decode a DER encoded certificate into an CERTCertificate structure -** "derSignedCert" is the DER encoded signed certificate -** "copyDER" is true if the DER should be copied, false if the -** existing copy should be referenced -** "nickname" is the nickname to use in the database. If it is NULL -** then a temporary nickname is generated. -*/ -extern CERTCertificate * -CERT_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nickname); -/* -** Decode a DER encoded CRL/KRL into an CERTSignedCrl structure -** "derSignedCrl" is the DER encoded signed crl/krl. -** "type" is this a CRL or KRL. -*/ -#define SEC_CRL_TYPE 1 -#define SEC_KRL_TYPE 0 - -extern CERTSignedCrl * -CERT_DecodeDERCrl (PRArenaPool *arena, SECItem *derSignedCrl,int type); - -/* Validate CRL then import it to the dbase. If there is already a CRL with the - * same CA in the dbase, it will be replaced if derCRL is more up to date. - * If the process successes, a CRL will be returned. Otherwise, a NULL will - * be returned. The caller should call PORT_GetError() for the exactly error - * code. - */ -extern CERTSignedCrl * -CERT_ImportCRL (CERTCertDBHandle *handle, SECItem *derCRL, char *url, - int type, void * wincx); - -extern void CERT_DestroyCrl (CERTSignedCrl *crl); - -/* -** Decode a certificate and put it into the temporary certificate database -*/ -extern CERTCertificate * -CERT_NewTempCertificate (CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER); - -/* -** Add a certificate to the temporary database. -** "dbCert" is the certificate from the perm database. -** "isperm" indicates if the cert is in the permanent database. -*/ -extern CERTCertificate * -CERT_AddTempCertificate (CERTCertDBHandle *handle, certDBEntryCert *entry, - PRBool isperm); - -/* -** Add a temporary certificate to the permanent database. -** "cert" is the temporary cert -** "nickname" is the permanent nickname to use -** "trust" is the certificate trust parameters to assign to the cert -*/ -extern SECStatus -CERT_AddTempCertToPerm (CERTCertificate *cert, char *nickname, CERTCertTrust *trust); - -/* -** Find a certificate in the database -** "key" is the database key to look for -*/ -extern CERTCertificate *CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *key); - -/* - * Lookup a certificate in the databases without locking - * "certKey" is the database key to look for - * - * XXX - this should be internal, but pkcs 11 needs to call it during a - * traversal. - */ -CERTCertificate * -CERT_FindCertByKeyNoLocking(CERTCertDBHandle *handle, SECItem *certKey); - -/* -** Find a certificate in the database by name -** "name" is the distinguished name to look up -*/ -extern CERTCertificate * -CERT_FindCertByName (CERTCertDBHandle *handle, SECItem *name); - -/* -** Find a certificate in the database by name -** "name" is the distinguished name to look up (in ascii) -*/ -extern CERTCertificate * -CERT_FindCertByNameString (CERTCertDBHandle *handle, char *name); - -/* -** Find a certificate in the database by name and keyid -** "name" is the distinguished name to look up -** "keyID" is the value of the subjectKeyID to match -*/ -extern CERTCertificate * -CERT_FindCertByKeyID (CERTCertDBHandle *handle, SECItem *name, SECItem *keyID); - -/* -** Generate a certificate key from the issuer and serialnumber, then look it -** up in the database. Return the cert if found. -** "issuerAndSN" is the issuer and serial number to look for -*/ -extern CERTCertificate * -CERT_FindCertByIssuerAndSN (CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN); - -/* -** Find a certificate in the database by a nickname -** "nickname" is the ascii string nickname to look for -*/ -extern CERTCertificate * -CERT_FindCertByNickname (CERTCertDBHandle *handle, char *nickname); -/* -** Find a certificate in the database by a DER encoded certificate -** "derCert" is the DER encoded certificate -*/ -extern CERTCertificate * -CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert); - -/* -** Find a certificate in the database by a email address -** "emailAddr" is the email address to look up -*/ -CERTCertificate * -CERT_FindCertByEmailAddr(CERTCertDBHandle *handle, char *emailAddr); - -/* -** Find a certificate in the database by a email address or nickname -** "name" is the email address or nickname to look up -*/ -CERTCertificate * -CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, char *name); - -/* -** Find a certificate in the database by a digest of a subject public key -** "spkDigest" is the digest to look up -*/ -extern CERTCertificate * -CERT_FindCertBySPKDigest(CERTCertDBHandle *handle, SECItem *spkDigest); - -/* - * Find the issuer of a cert - */ -CERTCertificate * -CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage); - -/* -** Delete a certificate from the temporary database -** "cert" is the certificate to be deleted -*/ -extern SECStatus CERT_DeleteTempCertificate(CERTCertificate *cert); - -/* -** Flush and close the permanent database. -*/ -extern void CERT_ClosePermCertDB(CERTCertDBHandle *handle); - -/* -** Check the validity times of a certificate vs. time 't', allowing -** some slop for broken clocks and stuff. -** "cert" is the certificate to be checked -** "t" is the time to check against -** "allowOverride" if true then check to see if the invalidity has -** been overridden by the user. -*/ -extern SECCertTimeValidity CERT_CheckCertValidTimes(CERTCertificate *cert, - int64 t, - PRBool allowOverride); - -/* -** WARNING - this function is depricated, and will either go away or have -** a new API in the near future. -** -** Check the validity times of a certificate vs. the current time, allowing -** some slop for broken clocks and stuff. -** "cert" is the certificate to be checked -*/ -extern SECStatus CERT_CertTimesValid(CERTCertificate *cert); - -/* -** Extract the validity times from a certificate -** "c" is the certificate -** "notBefore" is the start of the validity period -** "notAfter" is the end of the validity period -*/ -extern SECStatus -CERT_GetCertTimes (CERTCertificate *c, int64 *notBefore, int64 *notAfter); - -/* -** Extract the issuer and serial number from a certificate -*/ -extern CERTIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *, - CERTCertificate *); - -/* -** verify the signature of a signed data object with a given certificate -** "sd" the signed data object to be verified -** "cert" the certificate to use to check the signature -*/ -extern SECStatus CERT_VerifySignedData(CERTSignedData *sd, - CERTCertificate *cert, - int64 t, - void *wincx); - -/* -** verify a certificate by checking validity times against a certain time, -** that we trust the issuer, and that the signature on the certificate is -** valid. -** "cert" the certificate to verify -** "checkSig" only check signatures if true -*/ -extern SECStatus -CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, int64 t, - void *wincx, CERTVerifyLog *log); - -/* same as above, but uses current time */ -extern SECStatus -CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, void *wincx); - -/* -** This must only be called on a cert that is known to have an issuer -** with an invalid time -*/ -extern CERTCertificate * -CERT_FindExpiredIssuer (CERTCertDBHandle *handle, CERTCertificate *cert); - -/* -** Read a base64 ascii encoded DER certificate and convert it to our -** internal format. -** "certstr" is a null-terminated string containing the certificate -*/ -extern CERTCertificate *CERT_ConvertAndDecodeCertificate(char *certstr); - -/* -** Read a certificate in some foreign format, and convert it to our -** internal format. -** "certbuf" is the buffer containing the certificate -** "certlen" is the length of the buffer -** NOTE - currently supports netscape base64 ascii encoded raw certs -** and netscape binary DER typed files. -*/ -extern CERTCertificate *CERT_DecodeCertFromPackage(char *certbuf, int certlen); - -extern SECStatus -CERT_ImportCAChain (SECItem *certs, int numcerts, SECCertUsage certUsage); - -/* -** Read a certificate chain in some foreign format, and pass it to a -** callback function. -** "certbuf" is the buffer containing the certificate -** "certlen" is the length of the buffer -** "f" is the callback function -** "arg" is the callback argument -*/ -typedef SECStatus (*CERTImportCertificateFunc) - (void *arg, SECItem **certs, int numcerts); - -extern SECStatus -CERT_DecodeCertPackage(char *certbuf, int certlen, CERTImportCertificateFunc f, - void *arg); - -/* -** Pretty print a certificate in HTML -** "cert" is the certificate to print -** "showImages" controls whether or not to use about:security URLs -** for subject and issuer images. This should only be true -** in the browser. -*/ -extern char *CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, - PRBool showIssuer); - -/* -** Returns the value of an AVA. This was a formerly static -** function that has been exposed due to the need to decode -** and convert unicode strings to UTF8. -** -** XXX This function resides in certhtml.c, should it be -** moved elsewhere? -*/ -extern SECItem *CERT_DecodeAVAValue(SECItem *derAVAValue); - - -/* -** extract various element strings from a distinguished name. -** "name" the distinguished name -*/ -extern char *CERT_GetCommonName(CERTName *name); - -extern char *CERT_GetCertificateEmailAddress(CERTCertificate *cert); - -extern char *CERT_GetCertEmailAddress(CERTName *name); - -extern char *CERT_GetCommonName(CERTName *name); - -extern char *CERT_GetCountryName(CERTName *name); - -extern char *CERT_GetLocalityName(CERTName *name); - -extern char *CERT_GetStateName(CERTName *name); - -extern char *CERT_GetOrgName(CERTName *name); - -extern char *CERT_GetOrgUnitName(CERTName *name); - -extern char *CERT_GetDomainComponentName(CERTName *name); - -extern char *CERT_GetCertUid(CERTName *name); - -/* manipulate the trust parameters of a certificate */ - -extern SECStatus CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust); - -extern SECStatus -CERT_ChangeCertTrust (CERTCertDBHandle *handle, CERTCertificate *cert, - CERTCertTrust *trust); - -extern SECStatus -CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb, CERTCertificate *cert, - SECCertUsage usage); - -/************************************************************************* - * - * manipulate the extensions of a certificate - * - ************************************************************************/ - -/* -** Set up a cert for adding X509v3 extensions. Returns an opaque handle -** used by the next two routines. -** "cert" is the certificate we are adding extensions to -*/ -extern void *CERT_StartCertExtensions(CERTCertificate *cert); - -/* -** Add an extension to a certificate. -** "exthandle" is the handle returned by the previous function -** "idtag" is the integer tag for the OID that should ID this extension -** "value" is the value of the extension -** "critical" is the critical extension flag -** "copyData" is a flag indicating whether the value data should be -** copied. -*/ -extern SECStatus CERT_AddExtension (void *exthandle, int idtag, - SECItem *value, PRBool critical, PRBool copyData); - -extern SECStatus CERT_AddExtensionByOID (void *exthandle, SECItem *oid, - SECItem *value, PRBool critical, PRBool copyData); - -extern SECStatus CERT_EncodeAndAddExtension - (void *exthandle, int idtag, void *value, PRBool critical, - const SEC_ASN1Template *atemplate); - -extern SECStatus CERT_EncodeAndAddBitStrExtension - (void *exthandle, int idtag, SECItem *value, PRBool critical); - -/* -** Finish adding cert extensions. Does final processing on extension -** data, putting it in the right format, and freeing any temporary -** storage. -** "exthandle" is the handle used to add extensions to a certificate -*/ -extern SECStatus CERT_FinishExtensions(void *exthandle); - - -/* If the extension is found, return its criticality and value. -** This allocate storage for the returning extension value. -*/ -extern SECStatus CERT_GetExtenCriticality - (CERTCertExtension **extensions, int tag, PRBool *isCritical); - -extern void -CERT_DestroyOidSequence(CERTOidSequence *oidSeq); - -/**************************************************************************** - * - * DER encode and decode extension values - * - ****************************************************************************/ - -/* Encode the value of the basicConstraint extension. -** arena - where to allocate memory for the encoded value. -** value - extension value to encode -** encodedValue - output encoded value -*/ -extern SECStatus CERT_EncodeBasicConstraintValue - (PRArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue); - -/* -** Encode the value of the authorityKeyIdentifier extension. -*/ -extern SECStatus CERT_EncodeAuthKeyID - (PRArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue); - -/* -** Encode the value of the crlDistributionPoints extension. -*/ -extern SECStatus CERT_EncodeCRLDistributionPoints - (PRArenaPool *arena, CERTCrlDistributionPoints *value,SECItem *derValue); - -/* -** Decodes a DER encoded basicConstaint extension value into a readable format -** value - decoded value -** encodedValue - value to decoded -*/ -extern SECStatus CERT_DecodeBasicConstraintValue - (CERTBasicConstraints *value, SECItem *encodedValue); - -/* Decodes a DER encoded authorityKeyIdentifier extension value into a -** readable format. -** arena - where to allocate memory for the decoded value -** encodedValue - value to be decoded -** Returns a CERTAuthKeyID structure which contains the decoded value -*/ -extern CERTAuthKeyID *CERT_DecodeAuthKeyID - (PRArenaPool *arena, SECItem *encodedValue); - - -/* Decodes a DER encoded crlDistributionPoints extension value into a -** readable format. -** arena - where to allocate memory for the decoded value -** der - value to be decoded -** Returns a CERTCrlDistributionPoints structure which contains the -** decoded value -*/ -extern CERTCrlDistributionPoints * CERT_DecodeCRLDistributionPoints - (PRArenaPool *arena, SECItem *der); - -/* Extract certain name type from a generalName */ -extern void *CERT_GetGeneralNameByType - (CERTGeneralName *genNames, CERTGeneralNameType type, PRBool derFormat); - - -extern CERTOidSequence * -CERT_DecodeOidSequence(SECItem *seqItem); - - - - -/**************************************************************************** - * - * Find extension values of a certificate - * - ***************************************************************************/ - -extern SECStatus CERT_FindCertExtension - (CERTCertificate *cert, int tag, SECItem *value); - -extern SECStatus CERT_FindNSCertTypeExtension - (CERTCertificate *cert, SECItem *value); - -extern char * CERT_FindNSStringExtension (CERTCertificate *cert, int oidtag); - -extern SECStatus CERT_FindIssuerCertExtension - (CERTCertificate *cert, int tag, SECItem *value); - -extern SECStatus CERT_FindCertExtensionByOID - (CERTCertificate *cert, SECItem *oid, SECItem *value); - -extern char *CERT_FindCertURLExtension (CERTCertificate *cert, int tag, - int catag); - -/* Returns the decoded value of the authKeyID extension. -** Note that this uses passed in the arena to allocate storage for the result -*/ -extern CERTAuthKeyID * CERT_FindAuthKeyIDExten (PRArenaPool *arena,CERTCertificate *cert); - -/* Returns the decoded value of the basicConstraint extension. - */ -extern SECStatus CERT_FindBasicConstraintExten - (CERTCertificate *cert, CERTBasicConstraints *value); - -/* Returns the decoded value of the crlDistributionPoints extension. -** Note that the arena in cert is used to allocate storage for the result -*/ -extern CERTCrlDistributionPoints * CERT_FindCRLDistributionPoints - (CERTCertificate *cert); - -/* Returns value of the keyUsage extension. This uses PR_Alloc to allocate -** buffer for the decoded value, The caller should free up the storage -** allocated in value->data. -*/ -extern SECStatus CERT_FindKeyUsageExtension (CERTCertificate *cert, - SECItem *value); - -/* Return the decoded value of the subjectKeyID extension. The caller should -** free up the storage allocated in retItem->data. -*/ -extern SECStatus CERT_FindSubjectKeyIDExten (CERTCertificate *cert, - SECItem *retItem); - -/* -** If cert is a v3 certificate, and a critical keyUsage extension is included, -** then check the usage against the extension value. If a non-critical -** keyUsage extension is included, this will return SECSuccess without -** checking, since the extension is an advisory field, not a restriction. -** If cert is not a v3 certificate, this will return SECSuccess. -** cert - certificate -** usage - one of the x.509 v3 the Key Usage Extension flags -*/ -extern SECStatus CERT_CheckCertUsage (CERTCertificate *cert, - unsigned char usage); - -/**************************************************************************** - * - * CRL v2 Extensions supported routines - * - ****************************************************************************/ - -extern SECStatus CERT_FindCRLExtensionByOID - (CERTCrl *crl, SECItem *oid, SECItem *value); - -extern SECStatus CERT_FindCRLExtension - (CERTCrl *crl, int tag, SECItem *value); - -extern SECStatus - CERT_FindInvalidDateExten (CERTCrl *crl, int64 *value); - -extern void *CERT_StartCRLExtensions (CERTCrl *crl); - -extern CERTCertNicknames *CERT_GetCertNicknames (CERTCertDBHandle *handle, - int what, void *wincx); - -/* -** Finds the crlNumber extension and decodes its value into 'value' -*/ -extern SECStatus CERT_FindCRLNumberExten (CERTCrl *crl, CERTCrlNumber *value); - -extern void CERT_FreeNicknames(CERTCertNicknames *nicknames); - -extern PRBool CERT_CompareCerts(CERTCertificate *c1, CERTCertificate *c2); - -extern PRBool CERT_CompareCertsForRedirection(CERTCertificate *c1, - CERTCertificate *c2); - -/* -** Generate an array of the Distinguished Names that the given cert database -** "trusts" -*/ -extern CERTDistNames *CERT_GetSSLCACerts(CERTCertDBHandle *handle); - -extern void CERT_FreeDistNames(CERTDistNames *names); - -/* -** Generate an array of Distinguished names from an array of nicknames -*/ -extern CERTDistNames *CERT_DistNamesFromNicknames - (CERTCertDBHandle *handle, char **nicknames, int nnames); - -/* -** Generate a certificate chain from a certificate. -*/ -extern CERTCertificateList * -CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, - PRBool includeRoot); - -extern CERTCertificateList * -CERT_CertListFromCert(CERTCertificate *cert); - -extern void CERT_DestroyCertificateList(CERTCertificateList *list); - -/* is cert a newer than cert b? */ -PRBool CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb); - -typedef SECStatus (* CERTCertCallback)(CERTCertificate *cert, void *arg); - -SECStatus -CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject, - CERTCertCallback cb, void *cbarg); -int -CERT_NumPermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject); - -SECStatus -CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname, - CERTCertCallback cb, void *cbarg); - -int -CERT_NumPermCertsForNickname(CERTCertDBHandle *handle, char *nickname); - -int -CERT_NumCertsForCertSubject(CERTCertificate *cert); - -int -CERT_NumPermCertsForCertSubject(CERTCertificate *cert); - -SECStatus -CERT_TraverseCertsForSubject(CERTCertDBHandle *handle, - CERTSubjectList *subjectList, - CERTCertCallback cb, void *cbarg); - -/* currently a stub for address book */ -PRBool -CERT_IsCertRevoked(CERTCertificate *cert); - -void -CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts); - -/* convert an email address to lower case */ -char *CERT_FixupEmailAddr(char *emailAddr); - -/* decode string representation of trust flags into trust struct */ -SECStatus -CERT_DecodeTrustString(CERTCertTrust *trust, char *trusts); - -/* encode trust struct into string representation of trust flags */ -char * -CERT_EncodeTrustString(CERTCertTrust *trust); - -/* find the next or prev cert in a subject list */ -CERTCertificate * -CERT_PrevSubjectCert(CERTCertificate *cert); -CERTCertificate * -CERT_NextSubjectCert(CERTCertificate *cert); - -/* - * import a collection of certs into the temporary or permanent cert - * database - */ -SECStatus -CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage, - unsigned int ncerts, SECItem **derCerts, - CERTCertificate ***retCerts, PRBool keepCerts, - PRBool caOnly, char *nickname); - -SECStatus -CERT_SaveImportedCert(CERTCertificate *cert, SECCertUsage usage, - PRBool caOnly, char *nickname); - -char * -CERT_MakeCANickname(CERTCertificate *cert); - -PRBool -CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype); - -SECStatus -CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, - SECItem *profileTime); - -/* - * find the smime symmetric capabilities profile for a given cert - */ -SECItem * -CERT_FindSMimeProfile(CERTCertificate *cert); - -int -CERT_GetDBContentVersion(CERTCertDBHandle *handle); - -void -CERT_SetDBContentVersion(int version, CERTCertDBHandle *handle); - -SECStatus -CERT_AddNewCerts(CERTCertDBHandle *handle); - -CERTPackageType -CERT_CertPackageType(SECItem *package, SECItem *certitem); - -CERTCertificatePolicies * -CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue); - -void -CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies); - -CERTUserNotice * -CERT_DecodeUserNotice(SECItem *noticeItem); - -void -CERT_DestroyUserNotice(CERTUserNotice *userNotice); - -typedef char * (* CERTPolicyStringCallback)(char *org, - unsigned long noticeNumber, - void *arg); -void -CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg); - -char * -CERT_GetCertCommentString(CERTCertificate *cert); - -PRBool -CERT_GovtApprovedBitSet(CERTCertificate *cert); - -SECStatus -CERT_AddPermNickname(CERTCertificate *cert, char *nickname); - -/* - * Given a cert, find the cert with the same subject name that - * has the given key usage. If the given cert has the correct keyUsage, then - * return it, otherwise search the list in order. - */ -CERTCertificate * -CERT_FindCertByUsage(CERTCertificate *basecert, unsigned int requiredKeyUsage); - - -CERTCertList * -CERT_MatchUserCert(CERTCertDBHandle *handle, - SECCertUsage usage, - int nCANames, char **caNames, - void *proto_win); - -CERTCertList * -CERT_NewCertList(void); - -void -CERT_DestroyCertList(CERTCertList *certs); - -/* remove the node and free the cert */ -void -CERT_RemoveCertListNode(CERTCertListNode *node); - -SECStatus -CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert); - -typedef PRBool (* CERTSortCallback)(CERTCertificate *certa, - CERTCertificate *certb, - void *arg); -SECStatus -CERT_AddCertToListSorted(CERTCertList *certs, CERTCertificate *cert, - CERTSortCallback f, void *arg); - -/* callback for CERT_AddCertToListSorted that sorts based on validity - * period and a given time. - */ -PRBool -CERT_SortCBValidity(CERTCertificate *certa, - CERTCertificate *certb, - void *arg); - -SECStatus -CERT_CheckForEvilCert(CERTCertificate *cert); - -CERTGeneralName * -CERT_GetCertificateNames(CERTCertificate *cert, PRArenaPool *arena); - -int -CERT_GetNamesLength(CERTGeneralName *names); - -CERTCertificate * -CERT_CompareNameSpace(CERTCertificate *cert, - CERTGeneralName *namesList, - SECItem *namesListIndex, - PRArenaPool *arena, - CERTCertDBHandle *handle); - -SECStatus -CERT_EncodeSubjectKeyID(PRArenaPool *arena, char *value, int len, SECItem *encodedValue); - -char * -CERT_GetNickName(CERTCertificate *cert, CERTCertDBHandle *handle, PRArenaPool *nicknameArena); - -/* - * Creates or adds to a list of all certs with a give subject name, sorted by - * validity time, newest first. Invalid certs are considered older than - * valid certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle, - SECItem *name, int64 sorttime, PRBool validOnly); - -/* - * Creates or adds to a list of all certs with a give nickname, sorted by - * validity time, newest first. Invalid certs are considered older than valid - * certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateNicknameCertList(CERTCertList *certList, CERTCertDBHandle *handle, - char *nickname, int64 sorttime, PRBool validOnly); - -/* - * Creates or adds to a list of all certs with a give email addr, sorted by - * validity time, newest first. Invalid certs are considered older than valid - * certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateEmailAddrCertList(CERTCertList *certList, CERTCertDBHandle *handle, - char *emailAddr, int64 sorttime, PRBool validOnly); - -/* - * remove certs from a list that don't have keyUsage and certType - * that match the given usage. - */ -SECStatus -CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage, - PRBool ca); - -/* - * check the key usage of a cert against a set of required values - */ -SECStatus -CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage); - -/* - * return required key usage and cert type based on cert usage - */ -SECStatus -CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, - PRBool ca, - unsigned int *retKeyUsage, - unsigned int *retCertType); -/* - * return required trust flags for various cert usages for CAs - */ -SECStatus -CERT_TrustFlagsForCACertUsage(SECCertUsage usage, - unsigned int *retFlags, - SECTrustType *retTrustType); - -/* - * Find all user certificates that match the given criteria. - * - * "handle" - database to search - * "usage" - certificate usage to match - * "oneCertPerName" - if set then only return the "best" cert per - * name - * "validOnly" - only return certs that are curently valid - * "proto_win" - window handle passed to pkcs11 - */ -CERTCertList * -CERT_FindUserCertsByUsage(CERTCertDBHandle *handle, - SECCertUsage usage, - PRBool oneCertPerName, - PRBool validOnly, - void *proto_win); - -/* - * Find a user certificate that matchs the given criteria. - * - * "handle" - database to search - * "nickname" - nickname to match - * "usage" - certificate usage to match - * "validOnly" - only return certs that are curently valid - * "proto_win" - window handle passed to pkcs11 - */ -CERTCertificate * -CERT_FindUserCertByUsage(CERTCertDBHandle *handle, - char *nickname, - SECCertUsage usage, - PRBool validOnly, - void *proto_win); - -/* - * Filter a list of certificates, removing those certs that do not have - * one of the named CA certs somewhere in their cert chain. - * - * "certList" - the list of certificates to filter - * "nCANames" - number of CA names - * "caNames" - array of CA names in string(rfc 1485) form - * "usage" - what use the certs are for, this is used when - * selecting CA certs - */ -SECStatus -CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, - char **caNames, SECCertUsage usage); - -/* - * Collect the nicknames from all certs in a CertList. If the cert is not - * valid, append a string to that nickname. - * - * "certList" - the list of certificates - * "expiredString" - the string to append to the nickname of any expired cert - * "notYetGoodString" - the string to append to the nickname of any cert - * that is not yet valid - */ -CERTCertNicknames * -CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, - char *notYetGoodString); - -/* - * Extract the nickname from a nickmake string that may have either - * expiredString or notYetGoodString appended. - * - * Args: - * "namestring" - the string containing the nickname, and possibly - * one of the validity label strings - * "expiredString" - the expired validity label string - * "notYetGoodString" - the not yet good validity label string - * - * Returns the raw nickname - */ -char * -CERT_ExtractNicknameString(char *namestring, char *expiredString, - char *notYetGoodString); - -/* - * Given a certificate, return a string containing the nickname, and possibly - * one of the validity strings, based on the current validity state of the - * certificate. - * - * "arena" - arena to allocate returned string from. If NULL, then heap - * is used. - * "cert" - the cert to get nickname from - * "expiredString" - the string to append to the nickname if the cert is - * expired. - * "notYetGoodString" - the string to append to the nickname if the cert is - * not yet good. - */ -char * -CERT_GetCertNicknameWithValidity(PRArenaPool *arena, CERTCertificate *cert, - char *expiredString, char *notYetGoodString); - -/* - * Return the string representation of a DER encoded distinguished name - * "dername" - The DER encoded name to convert - */ -char * -CERT_DerNameToAscii(SECItem *dername); - -/* - * Supported usage values and types: - * certUsageSSLClient - * certUsageSSLServer - * certUsageSSLServerWithStepUp - * certUsageEmailSigner - * certUsageEmailRecipient - * certUsageObjectSigner - */ - -CERTCertificate * -CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, - CERTCertOwner owner, SECCertUsage usage, - PRBool preferTrusted, int64 validTime, PRBool validOnly); - - -/*********************************************************************/ -/* A thread safe implementation of General Names */ -/*********************************************************************/ - -/* Destroy a Single CERTGeneralName */ -void -CERT_DestroyGeneralName(CERTGeneralName *name); - -/* Destroys a CERTGeneralNameList */ -void -CERT_DestroyGeneralNameList(CERTGeneralNameList *list); - -/* Creates a CERTGeneralNameList */ -CERTGeneralNameList * -CERT_CreateGeneralNameList(CERTGeneralName *name); - -/* Compares two CERTGeneralNameList */ -SECStatus -CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b); - -/* returns a copy of the first name of the type requested */ -void * -CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, - CERTGeneralNameType type, - PRArenaPool *arena); - -/* Adds a name to the tail of the list */ -void -CERT_AddGeneralNameToList(CERTGeneralNameList *list, - CERTGeneralNameType type, - void *data, SECItem *oid); - -/* returns a duplicate of the CERTGeneralNameList */ -CERTGeneralNameList * -CERT_DupGeneralNameList(CERTGeneralNameList *list); - -/* returns the length of a CERTGeneralName */ -int -CERT_GetNamesLength(CERTGeneralName *names); - -/* - * Acquire the global lock on the cert database. - * This lock is currently used for the following operations: - * adding or deleting a cert to either the temp or perm databases - * converting a temp to perm or perm to temp - * changing(maybe just adding?) the trust of a cert - * adjusting the reference count of a cert - */ -void -CERT_LockDB(CERTCertDBHandle *handle); - -/* - * Free the global cert database lock. - */ -void -CERT_UnlockDB(CERTCertDBHandle *handle); - -/* - * Get the certificate status checking configuratino data for - * the certificate database - */ -CERTStatusConfig * -CERT_GetStatusConfig(CERTCertDBHandle *handle); - -/* - * Set the certificate status checking information for the - * database. The input structure becomes part of the certificate - * database and will be freed by calling the 'Destroy' function in - * the configuration object. - */ -void -CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config); - -/* - * Acquire the cert reference count 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_LockCertRefCount(CERTCertificate *cert); - -/* - * Free 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(CERTCertificate *cert); - -/* - * Free the cert trust lock - */ -void -CERT_UnlockCertTrust(CERTCertificate *cert); - -/* - * Digest the cert's subject public key using the specified algorithm. - * The necessary storage for the digest data is allocated. If "fill" is - * non-null, the data is put there, otherwise a SECItem is allocated. - * Allocation from "arena" if it is non-null, heap otherwise. Any problem - * results in a NULL being returned (and an appropriate error set). - */ -extern SECItem * -CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert, - SECOidTag digestAlg, SECItem *fill); - - -SEC_END_PROTOS - -#endif /* _CERT_H_ */ diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c deleted file mode 100644 index 17f084f5b..000000000 --- a/security/nss/lib/certdb/certdb.c +++ /dev/null @@ -1,2271 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Certificate handling code - * - * $Id$ - */ - -#include "prlock.h" -#include "prmon.h" -#include "prtime.h" -#include "cert.h" -#include "secder.h" -#include "secoid.h" -#include "secasn1.h" -#include "blapi.h" /* for SHA1_HashBuf */ -#include "genname.h" -#include "keyhi.h" -#include "secitem.h" -#include "mcom_db.h" -#include "certdb.h" -#include "prprf.h" -#include "sechash.h" -#include "prlong.h" -#include "certxutl.h" -#include "portreg.h" -#include "secerr.h" -#include "sslerr.h" -#include "nsslocks.h" -#include "cdbhdl.h" - -/* - * Certificate database handling code - */ - - -const SEC_ASN1Template CERT_CertExtensionTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertExtension) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTCertExtension,id) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ - offsetof(CERTCertExtension,critical) }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTCertExtension,value) }, - { 0, } -}; - -const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, CERT_CertExtensionTemplate } -}; - -const SEC_ASN1Template CERT_CertificateTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertificate) }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 0, /* XXX DER_DEFAULT */ - offsetof(CERTCertificate,version), - SEC_IntegerTemplate }, - { SEC_ASN1_INTEGER, - offsetof(CERTCertificate,serialNumber) }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificate,signature), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_SAVE, - offsetof(CERTCertificate,derIssuer) }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificate,issuer), - CERT_NameTemplate }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificate,validity), - CERT_ValidityTemplate }, - { SEC_ASN1_SAVE, - offsetof(CERTCertificate,derSubject) }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificate,subject), - CERT_NameTemplate }, - { SEC_ASN1_SAVE, - offsetof(CERTCertificate,derPublicKey) }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificate,subjectPublicKeyInfo), - CERT_SubjectPublicKeyInfoTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTCertificate,issuerID), - SEC_ObjectIDTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(CERTCertificate,subjectID), - SEC_ObjectIDTemplate }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 3, - offsetof(CERTCertificate,extensions), - CERT_SequenceOfCertExtensionTemplate }, - { 0 } -}; - -const SEC_ASN1Template SEC_SignedCertificateTemplate[] = -{ - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertificate) }, - { SEC_ASN1_SAVE, - offsetof(CERTCertificate,signatureWrap.data) }, - { SEC_ASN1_INLINE, - 0, CERT_CertificateTemplate }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificate,signatureWrap.signatureAlgorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(CERTCertificate,signatureWrap.signature) }, - { 0 } -}; - -/* - * Find the subjectName in a DER encoded certificate - */ -const SEC_ASN1Template SEC_CertSubjectTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SECItem) }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 0, - 0, SEC_SkipTemplate }, /* version */ - { SEC_ASN1_SKIP }, /* serial number */ - { SEC_ASN1_SKIP }, /* signature algorithm */ - { SEC_ASN1_SKIP }, /* issuer */ - { SEC_ASN1_SKIP }, /* validity */ - { SEC_ASN1_ANY, 0, NULL }, /* subject */ - { SEC_ASN1_SKIP_REST }, - { 0 } -}; - -/* - * Find the issuerName in a DER encoded certificate - */ -const SEC_ASN1Template SEC_CertIssuerTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SECItem) }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 0, - 0, SEC_SkipTemplate }, /* version */ - { SEC_ASN1_SKIP }, /* serial number */ - { SEC_ASN1_SKIP }, /* signature algorithm */ - { SEC_ASN1_ANY, 0, NULL }, /* issuer */ - { SEC_ASN1_SKIP_REST }, - { 0 } -}; - -/* - * Find the issuer and serialNumber in a DER encoded certificate. - * This data is used as the database lookup key since its the unique - * identifier of a certificate. - */ -const SEC_ASN1Template CERT_CertKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertKey) }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 0, - 0, SEC_SkipTemplate }, /* version */ - { SEC_ASN1_INTEGER, - offsetof(CERTCertKey,serialNumber) }, - { SEC_ASN1_SKIP }, /* signature algorithm */ - { SEC_ASN1_ANY, - offsetof(CERTCertKey,derIssuer) }, - { SEC_ASN1_SKIP_REST }, - { 0 } -}; - - - -SECStatus -CERT_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn, - SECItem *key) -{ - key->len = sn->len + issuer->len; - - key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len); - if ( !key->data ) { - goto loser; - } - - /* copy the serialNumber */ - PORT_Memcpy(key->data, sn->data, sn->len); - - /* copy the issuer */ - PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len); - - return(SECSuccess); - -loser: - return(SECFailure); -} - - -/* - * Extract the subject name from a DER certificate - */ -SECStatus -CERT_NameFromDERCert(SECItem *derCert, SECItem *derName) -{ - int rv; - PRArenaPool *arena; - CERTSignedData sd; - void *tmpptr; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( ! arena ) { - return(SECFailure); - } - - PORT_Memset(&sd, 0, sizeof(CERTSignedData)); - rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); - - if ( rv ) { - goto loser; - } - - PORT_Memset(derName, 0, sizeof(SECItem)); - rv = SEC_ASN1DecodeItem(arena, derName, SEC_CertSubjectTemplate, &sd.data); - - if ( rv ) { - goto loser; - } - - tmpptr = derName->data; - derName->data = (unsigned char*)PORT_Alloc(derName->len); - if ( derName->data == NULL ) { - goto loser; - } - - PORT_Memcpy(derName->data, tmpptr, derName->len); - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(SECFailure); -} - -SECStatus -CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName) -{ - int rv; - PRArenaPool *arena; - CERTSignedData sd; - void *tmpptr; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( ! arena ) { - return(SECFailure); - } - - PORT_Memset(&sd, 0, sizeof(CERTSignedData)); - rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); - - if ( rv ) { - goto loser; - } - - PORT_Memset(derName, 0, sizeof(SECItem)); - rv = SEC_ASN1DecodeItem(arena, derName, SEC_CertIssuerTemplate, &sd.data); - - if ( rv ) { - goto loser; - } - - tmpptr = derName->data; - derName->data = (unsigned char*)PORT_Alloc(derName->len); - if ( derName->data == NULL ) { - goto loser; - } - - PORT_Memcpy(derName->data, tmpptr, derName->len); - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(SECFailure); -} - -/* - * Generate a database key, based on serial number and issuer, from a - * DER certificate. - */ -SECStatus -CERT_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key) -{ - int rv; - CERTSignedData sd; - CERTCertKey certkey; - - PORT_Memset(&sd, 0, sizeof(CERTSignedData)); - PORT_Memset(&certkey, 0, sizeof(CERTCertKey)); - - PORT_Memset(&sd, 0, sizeof(CERTSignedData)); - rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); - - if ( rv ) { - goto loser; - } - - PORT_Memset(&certkey, 0, sizeof(CERTCertKey)); - rv = SEC_ASN1DecodeItem(arena, &certkey, CERT_CertKeyTemplate, &sd.data); - - if ( rv ) { - goto loser; - } - - return(CERT_KeyFromIssuerAndSN(arena, &certkey.derIssuer, - &certkey.serialNumber, key)); -loser: - return(SECFailure); -} - -/* - * fill in keyUsage field of the cert based on the cert extension - * if the extension is not critical, then we allow all uses - */ -static SECStatus -GetKeyUsage(CERTCertificate *cert) -{ - SECStatus rv; - SECItem tmpitem; - - rv = CERT_FindKeyUsageExtension(cert, &tmpitem); - if ( rv == SECSuccess ) { - /* remember the actual value of the extension */ - cert->rawKeyUsage = tmpitem.data[0]; - cert->keyUsagePresent = PR_TRUE; - cert->keyUsage = tmpitem.data[0]; - - PORT_Free(tmpitem.data); - tmpitem.data = NULL; - - } else { - /* if the extension is not present, then we allow all uses */ - cert->keyUsage = KU_ALL; - cert->rawKeyUsage = KU_ALL; - cert->keyUsagePresent = PR_FALSE; - } - - if ( CERT_GovtApprovedBitSet(cert) ) { - cert->keyUsage |= KU_NS_GOVT_APPROVED; - cert->rawKeyUsage |= KU_NS_GOVT_APPROVED; - } - - return(SECSuccess); -} - - -/* - * determine if a fortezza V1 Cert is a CA or not. - */ -static PRBool -fortezzaIsCA( CERTCertificate *cert) { - PRBool isCA = PR_FALSE; - CERTSubjectPublicKeyInfo *spki = &cert->subjectPublicKeyInfo; - int tag; - - tag = SECOID_GetAlgorithmTag(&spki->algorithm); - if ((tag == SEC_OID_MISSI_KEA_DSS_OLD) || - (tag == SEC_OID_MISSI_KEA_DSS) || - (tag == SEC_OID_MISSI_DSS_OLD) || - (tag == SEC_OID_MISSI_DSS) ) { - SECItem rawkey; - unsigned char *rawptr; - unsigned char *end; - int len; - - rawkey = spki->subjectPublicKey; - DER_ConvertBitString(&rawkey); - rawptr = rawkey.data; - end = rawkey.data + rawkey.len; - - /* version */ - rawptr += sizeof(((SECKEYPublicKey*)0)->u.fortezza.KMID)+2; - - /* clearance (the string up to the first byte with the hi-bit on */ - while ((rawptr < end) && (*rawptr++ & 0x80)); - if (rawptr >= end) { return PR_FALSE; } - - /* KEAPrivilege (the string up to the first byte with the hi-bit on */ - while ((rawptr < end) && (*rawptr++ & 0x80)); - if (rawptr >= end) { return PR_FALSE; } - - /* skip the key */ - len = (*rawptr << 8) | rawptr[1]; - rawptr += 2 + len; - - /* shared key */ - if (rawptr >= end) { return PR_FALSE; } - /* DSS Version is next */ - rawptr += 2; - - /* DSSPrivilege (the string up to the first byte with the hi-bit on */ - if (*rawptr & 0x30) isCA = PR_TRUE; - - } - return isCA; -} - -static SECStatus -findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum) -{ - SECItem **oids; - SECItem *oid; - SECStatus rv = SECFailure; - - if (seq != NULL) { - oids = seq->oids; - while (oids != NULL && *oids != NULL) { - oid = *oids; - if (SECOID_FindOIDTag(oid) == tagnum) { - rv = SECSuccess; - break; - } - oids++; - } - } - return rv; -} - -/* - * fill in nsCertType field of the cert based on the cert extension - */ -SECStatus -CERT_GetCertType(CERTCertificate *cert) -{ - SECStatus rv; - SECItem tmpitem; - SECItem encodedExtKeyUsage; - CERTOidSequence *extKeyUsage = NULL; - PRBool basicConstraintPresent = PR_FALSE; - CERTBasicConstraints basicConstraint; - - tmpitem.data = NULL; - CERT_FindNSCertTypeExtension(cert, &tmpitem); - rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, - &encodedExtKeyUsage); - if (rv == SECSuccess) { - extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage); - } - rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); - if (rv == SECSuccess) { - basicConstraintPresent = PR_TRUE; - } - if (tmpitem.data != NULL || extKeyUsage != NULL) { - if (tmpitem.data == NULL) { - cert->nsCertType = 0; - } else { - cert->nsCertType = tmpitem.data[0]; - } - - /* free tmpitem data pointer to avoid memory leak */ - PORT_Free(tmpitem.data); - tmpitem.data = NULL; - - /* - * for this release, we will allow SSL certs with an email address - * to be used for email - */ - if ( ( cert->nsCertType & NS_CERT_TYPE_SSL_CLIENT ) && - cert->emailAddr ) { - cert->nsCertType |= NS_CERT_TYPE_EMAIL; - } - /* - * for this release, we will allow SSL intermediate CAs to be - * email intermediate CAs too. - */ - if ( cert->nsCertType & NS_CERT_TYPE_SSL_CA ) { - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } - /* - * allow a cert with the extended key usage of EMail Protect - * to be used for email or as an email CA, if basic constraints - * indicates that it is a CA. - */ - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) == - SECSuccess) { - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_EMAIL; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) == - SECSuccess){ - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_SSL_SERVER; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) == - SECSuccess){ - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_SSL_CLIENT; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_CODE_SIGN) == - SECSuccess) { - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_TIME_STAMP) == - SECSuccess) { - cert->nsCertType |= EXT_KEY_USAGE_TIME_STAMP; - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_OCSP_RESPONDER) == - SECSuccess) { - cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } - } else { - /* if no extension, then allow any ssl or email (no ca or object - * signing) - */ - cert->nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | - NS_CERT_TYPE_EMAIL; - - /* if the basic constraint extension says the cert is a CA, then - allow SSL CA and EMAIL CA and Status Responder */ - if ((basicConstraintPresent == PR_TRUE) - && (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } else if (CERT_IsCACert(cert, NULL) == PR_TRUE) { - cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } - - /* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */ - if (fortezzaIsCA(cert)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } - } - - if (extKeyUsage != NULL) { - PORT_Free(encodedExtKeyUsage.data); - CERT_DestroyOidSequence(extKeyUsage); - } - return(SECSuccess); -} - -/* - * cert_GetKeyID() - extract or generate the subjectKeyID from a certificate - */ -SECStatus -cert_GetKeyID(CERTCertificate *cert) -{ - SECItem tmpitem; - SECStatus rv; - SECKEYPublicKey *key; - - cert->subjectKeyID.len = 0; - - /* see of the cert has a key identifier extension */ - rv = CERT_FindSubjectKeyIDExten(cert, &tmpitem); - if ( rv == SECSuccess ) { - cert->subjectKeyID.data = (unsigned char*) PORT_ArenaAlloc(cert->arena, tmpitem.len); - if ( cert->subjectKeyID.data != NULL ) { - PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len); - cert->subjectKeyID.len = tmpitem.len; - cert->keyIDGenerated = PR_FALSE; - } - - PORT_Free(tmpitem.data); - } - - /* if the cert doesn't have a key identifier extension and the cert is - * a V1 fortezza certificate, use the cert's 8 byte KMID as the - * key identifier. */ - key = CERT_KMIDPublicKey(cert); - - if (key != NULL) { - - if (key->keyType == fortezzaKey) { - - cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, 8); - if ( cert->subjectKeyID.data != NULL ) { - PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8); - cert->subjectKeyID.len = 8; - cert->keyIDGenerated = PR_FALSE; - } - } - - SECKEY_DestroyPublicKey(key); - } - - /* if the cert doesn't have a key identifier extension, then generate one*/ - if ( cert->subjectKeyID.len == 0 ) { - /* - * pkix says that if the subjectKeyID is not present, then we should - * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert - */ - cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH); - if ( cert->subjectKeyID.data != NULL ) { - rv = SHA1_HashBuf(cert->subjectKeyID.data, - cert->derPublicKey.data, - cert->derPublicKey.len); - if ( rv == SECSuccess ) { - cert->subjectKeyID.len = SHA1_LENGTH; - } - } - } - - if ( cert->subjectKeyID.len == 0 ) { - return(SECFailure); - } - return(SECSuccess); - -} - -/* - * take a DER certificate and decode it into a certificate structure - */ -CERTCertificate * -CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, - char *nickname) -{ - CERTCertificate *cert; - PRArenaPool *arena; - void *data; - int rv; - int len; - char *tmpname; - - /* make a new arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - return 0; - } - - /* allocate the certificate structure */ - cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate)); - - if ( !cert ) { - goto loser; - } - - cert->arena = arena; - - if ( copyDER ) { - /* copy the DER data for the cert into this arena */ - data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len); - if ( !data ) { - goto loser; - } - cert->derCert.data = (unsigned char *)data; - cert->derCert.len = derSignedCert->len; - PORT_Memcpy(data, derSignedCert->data, derSignedCert->len); - } else { - /* point to passed in DER data */ - cert->derCert = *derSignedCert; - } - - /* decode the certificate info */ - rv = SEC_ASN1DecodeItem(arena, cert, SEC_SignedCertificateTemplate, - &cert->derCert); - - if ( rv ) { - goto loser; - } - - if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) { - PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); - goto loser; - } - - /* generate and save the database key for the cert */ - rv = CERT_KeyFromDERCert(arena, &cert->derCert, &cert->certKey); - if ( rv ) { - goto loser; - } - - /* set the nickname */ - if ( nickname == NULL ) { - cert->nickname = NULL; - } else { - /* copy and install the nickname */ - len = PORT_Strlen(nickname) + 1; - cert->nickname = (char*)PORT_ArenaAlloc(arena, len); - if ( cert->nickname == NULL ) { - goto loser; - } - - PORT_Memcpy(cert->nickname, nickname, len); - } - - /* set the email address */ - cert->emailAddr = CERT_GetCertificateEmailAddress(cert); - - /* initialize the subjectKeyID */ - rv = cert_GetKeyID(cert); - if ( rv != SECSuccess ) { - goto loser; - } - - /* initialize keyUsage */ - rv = GetKeyUsage(cert); - if ( rv != SECSuccess ) { - goto loser; - } - - /* initialize the certType */ - rv = CERT_GetCertType(cert); - if ( rv != SECSuccess ) { - goto loser; - } - - tmpname = CERT_NameToAscii(&cert->subject); - if ( tmpname != NULL ) { - cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname); - PORT_Free(tmpname); - } - - tmpname = CERT_NameToAscii(&cert->issuer); - if ( tmpname != NULL ) { - cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname); - PORT_Free(tmpname); - } - - cert->referenceCount = 1; - cert->slot = NULL; - cert->pkcs11ID = CK_INVALID_KEY; - cert->dbnickname = NULL; - - return(cert); - -loser: - - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(0); -} - -/* -** Amount of time that a certifiate is allowed good before it is actually -** good. This is used for pending certificates, ones that are about to be -** valid. The slop is designed to allow for some variance in the clocks -** of the machine checking the certificate. -*/ -#define PENDING_SLOP (24L*60L*60L) - -SECStatus -CERT_GetCertTimes(CERTCertificate *c, int64 *notBefore, int64 *notAfter) -{ - int rv; - - /* convert DER not-before time */ - rv = DER_UTCTimeToTime(notBefore, &c->validity.notBefore); - if (rv) { - return(SECFailure); - } - - /* convert DER not-after time */ - rv = DER_UTCTimeToTime(notAfter, &c->validity.notAfter); - if (rv) { - return(SECFailure); - } - - return(SECSuccess); -} - -/* - * Check the validity times of a certificate - */ -SECCertTimeValidity -CERT_CheckCertValidTimes(CERTCertificate *c, int64 t, PRBool allowOverride) -{ - int64 notBefore, notAfter, pendingSlop; - SECStatus rv; - - /* if cert is already marked OK, then don't bother to check */ - if ( allowOverride && c->timeOK ) { - return(secCertTimeValid); - } - - rv = CERT_GetCertTimes(c, ¬Before, ¬After); - - if (rv) { - return(secCertTimeExpired); /*XXX is this the right thing to do here?*/ - } - - LL_I2L(pendingSlop, PENDING_SLOP); - LL_SUB(notBefore, notBefore, pendingSlop); - if ( LL_CMP( t, <, notBefore ) ) { - PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); - return(secCertTimeNotValidYet); - } - if ( LL_CMP( t, >, notAfter) ) { - PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); - return(secCertTimeExpired); - } - - return(secCertTimeValid); -} - -SECStatus -SEC_GetCrlTimes(CERTCrl *date, int64 *notBefore, int64 *notAfter) -{ - int rv; - - /* convert DER not-before time */ - rv = DER_UTCTimeToTime(notBefore, &date->lastUpdate); - if (rv) { - return(SECFailure); - } - - /* convert DER not-after time */ - if (date->nextUpdate.data) { - rv = DER_UTCTimeToTime(notAfter, &date->nextUpdate); - if (rv) { - return(SECFailure); - } - } - else { - LL_I2L(*notAfter, 0L); - } - return(SECSuccess); -} - -/* These routines should probably be combined with the cert - * routines using an common extraction routine. - */ -SECCertTimeValidity -SEC_CheckCrlTimes(CERTCrl *crl, int64 t) { - int64 notBefore, notAfter, pendingSlop; - SECStatus rv; - - rv = SEC_GetCrlTimes(crl, ¬Before, ¬After); - - if (rv) { - return(secCertTimeExpired); - } - - LL_I2L(pendingSlop, PENDING_SLOP); - LL_SUB(notBefore, notBefore, pendingSlop); - if ( LL_CMP( t, <, notBefore ) ) { - return(secCertTimeNotValidYet); - } - - /* If next update is omitted and the test for notBefore passes, then - we assume that the crl is up to date. - */ - if ( LL_IS_ZERO(notAfter) ) { - return(secCertTimeValid); - } - - if ( LL_CMP( t, >, notAfter) ) { - return(secCertTimeExpired); - } - - return(secCertTimeValid); -} - -PRBool -SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old) { - int64 newNotBefore, newNotAfter; - int64 oldNotBefore, oldNotAfter; - SECStatus rv; - - /* problems with the new CRL? reject it */ - rv = SEC_GetCrlTimes(inNew, &newNotBefore, &newNotAfter); - if (rv) return PR_FALSE; - - /* problems with the old CRL? replace it */ - rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter); - if (rv) return PR_TRUE; - - /* Question: what about the notAfter's? */ - return ((PRBool)LL_CMP(oldNotBefore, <, newNotBefore)); -} - -/* - * return required key usage and cert type based on cert usage - */ -SECStatus -CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, - PRBool ca, - unsigned int *retKeyUsage, - unsigned int *retCertType) -{ - unsigned int requiredKeyUsage = 0; - unsigned int requiredCertType = 0; - - if ( ca ) { - switch ( usage ) { - case certUsageSSLServerWithStepUp: - requiredKeyUsage = KU_NS_GOVT_APPROVED | KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_SSL_CA; - break; - case certUsageSSLClient: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_SSL_CA; - break; - case certUsageSSLServer: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_SSL_CA; - break; - case certUsageSSLCA: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_SSL_CA; - break; - case certUsageEmailSigner: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_EMAIL_CA; - break; - case certUsageEmailRecipient: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_EMAIL_CA; - break; - case certUsageObjectSigner: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA; - break; - case certUsageAnyCA: - case certUsageStatusResponder: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA | - NS_CERT_TYPE_EMAIL_CA | - NS_CERT_TYPE_SSL_CA; - break; - default: - PORT_Assert(0); - goto loser; - } - } else { - switch ( usage ) { - case certUsageSSLClient: - requiredKeyUsage = KU_DIGITAL_SIGNATURE; - requiredCertType = NS_CERT_TYPE_SSL_CLIENT; - break; - case certUsageSSLServer: - requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT; - requiredCertType = NS_CERT_TYPE_SSL_SERVER; - break; - case certUsageSSLServerWithStepUp: - requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT | - KU_NS_GOVT_APPROVED; - requiredCertType = NS_CERT_TYPE_SSL_SERVER; - break; - case certUsageSSLCA: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_SSL_CA; - break; - case certUsageEmailSigner: - requiredKeyUsage = KU_DIGITAL_SIGNATURE; - requiredCertType = NS_CERT_TYPE_EMAIL; - break; - case certUsageEmailRecipient: - requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT; - requiredCertType = NS_CERT_TYPE_EMAIL; - break; - case certUsageObjectSigner: - requiredKeyUsage = KU_DIGITAL_SIGNATURE; - requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING; - break; - case certUsageStatusResponder: - requiredKeyUsage = KU_DIGITAL_SIGNATURE; - requiredCertType = EXT_KEY_USAGE_STATUS_RESPONDER; - break; - default: - PORT_Assert(0); - goto loser; - } - } - - if ( retKeyUsage != NULL ) { - *retKeyUsage = requiredKeyUsage; - } - if ( retCertType != NULL ) { - *retCertType = requiredCertType; - } - - return(SECSuccess); -loser: - return(SECFailure); -} - -/* - * check the key usage of a cert against a set of required values - */ -SECStatus -CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage) -{ - SECKEYPublicKey *key; - - /* choose between key agreement or key encipherment based on key - * type in cert - */ - if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) { - key = CERT_ExtractPublicKey(cert); - if ( ( key->keyType == keaKey ) || ( key->keyType == fortezzaKey ) || - ( key->keyType == dhKey ) ) { - requiredUsage |= KU_KEY_AGREEMENT; - } else { - requiredUsage |= KU_KEY_ENCIPHERMENT; - } - - /* now turn off the special bit */ - requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT); - - SECKEY_DestroyPublicKey(key); - } - - if ( ( cert->keyUsage & requiredUsage ) != requiredUsage ) { - return(SECFailure); - } - return(SECSuccess); -} - - -CERTCertificate * -CERT_DupCertificate(CERTCertificate *c) -{ - if (c) { - CERT_LockCertRefCount(c); - ++c->referenceCount; - CERT_UnlockCertRefCount(c); - } - return c; -} - -/* - * Allow use of default cert database, so that apps(such as mozilla) don't - * have to pass the handle all over the place. - */ -static CERTCertDBHandle *default_cert_db_handle = 0; - -void -CERT_SetDefaultCertDB(CERTCertDBHandle *handle) -{ - default_cert_db_handle = handle; - - return; -} - -CERTCertDBHandle * -CERT_GetDefaultCertDB(void) -{ - return(default_cert_db_handle); -} - -/* - * Open volatile certificate database and index databases. This is a - * fallback if the real databases can't be opened or created. It is only - * resident in memory, so it will not be persistent. We do this so that - * we don't crash if the databases can't be created. - */ -SECStatus -CERT_OpenVolatileCertDB(CERTCertDBHandle *handle) -{ - /* - * Open the memory resident perm cert database. - */ - handle->permCertDB = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 ); - if ( !handle->permCertDB ) { - goto loser; - } - - /* - * Open the memory resident decoded cert database. - */ - handle->tempCertDB = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 ); - if ( !handle->tempCertDB ) { - goto loser; - } - - handle->dbMon = PR_NewMonitor(); - PORT_Assert(handle->dbMon != NULL); - - handle->spkDigestInfo = NULL; - handle->statusConfig = NULL; - - /* initialize the cert database */ - (void) CERT_InitCertDB(handle); - - return (SECSuccess); - -loser: - - PORT_SetError(SEC_ERROR_BAD_DATABASE); - - if ( handle->permCertDB ) { - (* handle->permCertDB->close)(handle->permCertDB); - handle->permCertDB = 0; - } - - if ( handle->tempCertDB ) { - (* handle->tempCertDB->close)(handle->tempCertDB); - handle->tempCertDB = 0; - } - - return(SECFailure); -} - -/* XXX this would probably be okay/better as an xp routine? */ -static void -sec_lower_string(char *s) -{ - if ( s == NULL ) { - return; - } - - while ( *s ) { - *s = PORT_Tolower(*s); - s++; - } - - return; -} - -/* -** Add a domain name to the list of names that the user has explicitly -** allowed (despite cert name mismatches) for use with a server cert. -*/ -SECStatus -CERT_AddOKDomainName(CERTCertificate *cert, const char *hn) -{ - CERTOKDomainName *domainOK; - int newNameLen; - - if (!hn || !(newNameLen = strlen(hn))) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena, - (sizeof *domainOK) + newNameLen); - if (!domainOK) - return SECFailure; /* error code is already set. */ - - PORT_Strcpy(domainOK->name, hn); - sec_lower_string(domainOK->name); - - /* put at head of list. */ - domainOK->next = cert->domainOK; - cert->domainOK = domainOK; - return SECSuccess; -} - -/* Make sure that the name of the host we are connecting to matches the - * name that is incoded in the common-name component of the certificate - * that they are using. - */ -SECStatus -CERT_VerifyCertName(CERTCertificate *cert, const char *hn) -{ - char * cn; - char * domain; - char * hndomain; - char * hostname; - int regvalid; - int match; - SECStatus rv; - CERTOKDomainName *domainOK; - - if (!hn || !strlen(hn)) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - hostname = PORT_Strdup(hn); - if ( hostname == NULL ) { - return(SECFailure); - } - sec_lower_string(hostname); - - /* if the name is one that the user has already approved, it's OK. */ - for (domainOK = cert->domainOK; domainOK; domainOK = domainOK->next) { - if (0 == PORT_Strcmp(hostname, domainOK->name)) { - PORT_Free(hostname); - return SECSuccess; - } - } - - /* try the cert extension first, then the common name */ - cn = CERT_FindNSStringExtension(cert, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME); - if ( cn == NULL ) { - cn = CERT_GetCommonName(&cert->subject); - } - - sec_lower_string(cn); - - if ( cn ) { - if ( ( hndomain = PORT_Strchr(hostname, '.') ) == NULL ) { - /* No domain in server name */ - if ( ( domain = PORT_Strchr(cn, '.') ) != NULL ) { - /* there is a domain in the cn string, so chop it off */ - *domain = '\0'; - } - } - - regvalid = PORT_RegExpValid(cn); - - if ( regvalid == NON_SXP ) { - /* compare entire hostname with cert name */ - if ( PORT_Strcmp(hostname, cn) == 0 ) { - rv = SECSuccess; - goto done; - } - - if ( hndomain ) { - /* compare just domain name with cert name */ - if ( PORT_Strcmp(hndomain+1, cn) == 0 ) { - rv = SECSuccess; - goto done; - } - } - - PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); - rv = SECFailure; - goto done; - - } else { - /* try to match the shexp */ - match = PORT_RegExpCaseSearch(hostname, cn); - - if ( match == 0 ) { - rv = SECSuccess; - } else { - PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); - rv = SECFailure; - } - goto done; - } - } - - PORT_SetError(SEC_ERROR_NO_MEMORY); - rv = SECFailure; - -done: - /* free the common name */ - if ( cn ) { - PORT_Free(cn); - } - - if ( hostname ) { - PORT_Free(hostname); - } - - return(rv); -} - -PRBool -CERT_CompareCerts(CERTCertificate *c1, CERTCertificate *c2) -{ - SECComparison comp; - - comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert); - if ( comp == SECEqual ) { /* certs are the same */ - return(PR_TRUE); - } else { - return(PR_FALSE); - } -} - -static SECStatus -StringsEqual(char *s1, char *s2) { - if ( ( s1 == NULL ) || ( s2 == NULL ) ) { - if ( s1 != s2 ) { /* only one is null */ - return(SECFailure); - } - return(SECSuccess); /* both are null */ - } - - if ( PORT_Strcmp( s1, s2 ) != 0 ) { - return(SECFailure); /* not equal */ - } - - return(SECSuccess); /* strings are equal */ -} - - -PRBool -CERT_CompareCertsForRedirection(CERTCertificate *c1, CERTCertificate *c2) -{ - SECComparison comp; - char *c1str, *c2str; - SECStatus eq; - - comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert); - if ( comp == SECEqual ) { /* certs are the same */ - return(PR_TRUE); - } - - /* check if they are issued by the same CA */ - comp = SECITEM_CompareItem(&c1->derIssuer, &c2->derIssuer); - if ( comp != SECEqual ) { /* different issuer */ - return(PR_FALSE); - } - - /* check country name */ - c1str = CERT_GetCountryName(&c1->subject); - c2str = CERT_GetCountryName(&c2->subject); - eq = StringsEqual(c1str, c2str); - PORT_Free(c1str); - PORT_Free(c2str); - if ( eq != SECSuccess ) { - return(PR_FALSE); - } - - /* check locality name */ - c1str = CERT_GetLocalityName(&c1->subject); - c2str = CERT_GetLocalityName(&c2->subject); - eq = StringsEqual(c1str, c2str); - PORT_Free(c1str); - PORT_Free(c2str); - if ( eq != SECSuccess ) { - return(PR_FALSE); - } - - /* check state name */ - c1str = CERT_GetStateName(&c1->subject); - c2str = CERT_GetStateName(&c2->subject); - eq = StringsEqual(c1str, c2str); - PORT_Free(c1str); - PORT_Free(c2str); - if ( eq != SECSuccess ) { - return(PR_FALSE); - } - - /* check org name */ - c1str = CERT_GetOrgName(&c1->subject); - c2str = CERT_GetOrgName(&c2->subject); - eq = StringsEqual(c1str, c2str); - PORT_Free(c1str); - PORT_Free(c2str); - if ( eq != SECSuccess ) { - return(PR_FALSE); - } - -#ifdef NOTDEF - /* check orgUnit name */ - /* - * We need to revisit this and decide which fields should be allowed to be - * different - */ - c1str = CERT_GetOrgUnitName(&c1->subject); - c2str = CERT_GetOrgUnitName(&c2->subject); - eq = StringsEqual(c1str, c2str); - PORT_Free(c1str); - PORT_Free(c2str); - if ( eq != SECSuccess ) { - return(PR_FALSE); - } -#endif - - return(PR_TRUE); /* all fields but common name are the same */ -} - - -/* CERT_CertChainFromCert and CERT_DestroyCertificateList moved - to certhigh.c */ - - -CERTIssuerAndSN * -CERT_GetCertIssuerAndSN(PRArenaPool *arena, CERTCertificate *cert) -{ - CERTIssuerAndSN *result; - SECStatus rv; - - if ( arena == NULL ) { - arena = cert->arena; - } - - result = (CERTIssuerAndSN*)PORT_ArenaZAlloc(arena, sizeof(*result)); - if (result == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer); - if (rv != SECSuccess) - return NULL; - - rv = CERT_CopyName(arena, &result->issuer, &cert->issuer); - if (rv != SECSuccess) - return NULL; - - rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber); - if (rv != SECSuccess) - return NULL; - - return result; -} - -char * -CERT_MakeCANickname(CERTCertificate *cert) -{ - char *firstname = NULL; - char *org = NULL; - char *nickname = NULL; - int count; - CERTCertificate *dummycert; - CERTCertDBHandle *handle; - - handle = cert->dbhandle; - - nickname = CERT_GetNickName(cert, handle, cert->arena); - if (nickname == NULL) { - firstname = CERT_GetCommonName(&cert->subject); - if ( firstname == NULL ) { - firstname = CERT_GetOrgUnitName(&cert->subject); - } - - org = CERT_GetOrgName(&cert->issuer); - if ( org == NULL ) { - goto loser; - } - - count = 1; - while ( 1 ) { - - if ( firstname ) { - if ( count == 1 ) { - nickname = PR_smprintf("%s - %s", firstname, org); - } else { - nickname = PR_smprintf("%s - %s #%d", firstname, org, count); - } - } else { - if ( count == 1 ) { - nickname = PR_smprintf("%s", org); - } else { - nickname = PR_smprintf("%s #%d", org, count); - } - } - if ( nickname == NULL ) { - goto loser; - } - - /* look up the nickname to make sure it isn't in use already */ - dummycert = CERT_FindCertByNickname(handle, nickname); - - if ( dummycert == NULL ) { - goto done; - } - - /* found a cert, destroy it and loop */ - CERT_DestroyCertificate(dummycert); - - /* free the nickname */ - PORT_Free(nickname); - - count++; - } - } -loser: - if ( nickname ) { - PORT_Free(nickname); - } - - nickname = ""; - -done: - if ( firstname ) { - PORT_Free(firstname); - } - if ( org ) { - PORT_Free(org); - } - - return(nickname); -} - -/* CERT_Import_CAChain moved to certhigh.c */ - -void -CERT_DestroyCrl (CERTSignedCrl *crl) -{ - SEC_DestroyCrl (crl); -} - - - -/* - * Does a cert belong to a CA? We decide based on perm database trust - * flags, Netscape Cert Type Extension, and KeyUsage Extension. - */ -PRBool -CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype) -{ - CERTCertTrust *trust; - SECStatus rv; - unsigned int type; - PRBool ret; - - ret = PR_FALSE; - type = 0; - - if ( cert->isperm ) { - trust = cert->trust; - if ( ( trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) { - ret = PR_TRUE; - type |= NS_CERT_TYPE_SSL_CA; - } - - if ( ( trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) { - ret = PR_TRUE; - type |= NS_CERT_TYPE_EMAIL_CA; - } - - if ( ( trust->objectSigningFlags & CERTDB_VALID_CA ) == - CERTDB_VALID_CA ) { - ret = PR_TRUE; - type |= NS_CERT_TYPE_OBJECT_SIGNING_CA; - } - } else { - if ( cert->nsCertType & - ( NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | - NS_CERT_TYPE_OBJECT_SIGNING_CA ) ) { - ret = PR_TRUE; - type = (cert->nsCertType & NS_CERT_TYPE_CA); - } else { - CERTBasicConstraints constraints; - rv = CERT_FindBasicConstraintExten(cert, &constraints); - if ( rv == SECSuccess ) { - if ( constraints.isCA ) { - ret = PR_TRUE; - type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA); - } - } - } - - /* finally check if it's a FORTEZZA V1 CA */ - if (ret == PR_FALSE) { - if (fortezzaIsCA(cert)) { - ret = PR_TRUE; - type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA); - } - } - } - if ( rettype != NULL ) { - *rettype = type; - } - - return(ret); -} - -/* - * is certa newer than certb? If one is expired, pick the other one. - */ -PRBool -CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb) -{ - int64 notBeforeA, notAfterA, notBeforeB, notAfterB, now; - SECStatus rv; - PRBool newerbefore, newerafter; - - rv = CERT_GetCertTimes(certa, ¬BeforeA, ¬AfterA); - if ( rv != SECSuccess ) { - return(PR_FALSE); - } - - rv = CERT_GetCertTimes(certb, ¬BeforeB, ¬AfterB); - if ( rv != SECSuccess ) { - return(PR_TRUE); - } - - newerbefore = PR_FALSE; - if ( LL_CMP(notBeforeA, >, notBeforeB) ) { - newerbefore = PR_TRUE; - } - - newerafter = PR_FALSE; - if ( LL_CMP(notAfterA, >, notAfterB) ) { - newerafter = PR_TRUE; - } - - if ( newerbefore && newerafter ) { - return(PR_TRUE); - } - - if ( ( !newerbefore ) && ( !newerafter ) ) { - return(PR_FALSE); - } - - /* get current UTC time */ - now = PR_Now(); - - if ( newerbefore ) { - /* cert A was issued after cert B, but expires sooner */ - /* if A is expired, then pick B */ - if ( LL_CMP(notAfterA, <, now ) ) { - return(PR_FALSE); - } - return(PR_TRUE); - } else { - /* cert B was issued after cert A, but expires sooner */ - /* if B is expired, then pick A */ - if ( LL_CMP(notAfterB, <, now ) ) { - return(PR_TRUE); - } - return(PR_FALSE); - } -} - -void -CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts) -{ - unsigned int i; - - if ( certs ) { - for ( i = 0; i < ncerts; i++ ) { - if ( certs[i] ) { - CERT_DestroyCertificate(certs[i]); - } - } - - PORT_Free(certs); - } - - return; -} - -char * -CERT_FixupEmailAddr(char *emailAddr) -{ - char *retaddr; - char *str; - - if ( emailAddr == NULL ) { - return(NULL); - } - - /* copy the string */ - str = retaddr = PORT_Strdup(emailAddr); - if ( str == NULL ) { - return(NULL); - } - - /* make it lower case */ - while ( *str ) { - *str = tolower( *str ); - str++; - } - - return(retaddr); -} - -/* - * NOTE - don't allow encode of govt-approved or invisible bits - */ -SECStatus -CERT_DecodeTrustString(CERTCertTrust *trust, char *trusts) -{ - int i; - unsigned int *pflags; - - trust->sslFlags = 0; - trust->emailFlags = 0; - trust->objectSigningFlags = 0; - - pflags = &trust->sslFlags; - - for (i=0; i < PORT_Strlen(trusts); i++) { - switch (trusts[i]) { - case 'p': - *pflags = *pflags | CERTDB_VALID_PEER; - break; - - case 'P': - *pflags = *pflags | CERTDB_TRUSTED | CERTDB_VALID_PEER; - break; - - case 'w': - *pflags = *pflags | CERTDB_SEND_WARN; - break; - - case 'c': - *pflags = *pflags | CERTDB_VALID_CA; - break; - - case 'T': - *pflags = *pflags | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA; - break; - - case 'C' : - *pflags = *pflags | CERTDB_TRUSTED_CA | CERTDB_VALID_CA; - break; - - case 'u': - *pflags = *pflags | CERTDB_USER; - break; - -#ifdef DEBUG_NSSTEAM_ONLY - case 'i': - *pflags = *pflags | CERTDB_INVISIBLE_CA; - break; - case 'g': - *pflags = *pflags | CERTDB_GOVT_APPROVED_CA; - break; -#endif /* DEBUG_NSSTEAM_ONLY */ - - case ',': - if ( pflags == &trust->sslFlags ) { - pflags = &trust->emailFlags; - } else { - pflags = &trust->objectSigningFlags; - } - break; - default: - return SECFailure; - } - } - - return SECSuccess; -} - -static void -EncodeFlags(char *trusts, unsigned int flags) -{ - if (flags & CERTDB_VALID_CA) - if (!(flags & CERTDB_TRUSTED_CA) && - !(flags & CERTDB_TRUSTED_CLIENT_CA)) - PORT_Strcat(trusts, "c"); - if (flags & CERTDB_VALID_PEER) - if (!(flags & CERTDB_TRUSTED)) - PORT_Strcat(trusts, "p"); - if (flags & CERTDB_TRUSTED_CA) - PORT_Strcat(trusts, "C"); - if (flags & CERTDB_TRUSTED_CLIENT_CA) - PORT_Strcat(trusts, "T"); - if (flags & CERTDB_TRUSTED) - PORT_Strcat(trusts, "P"); - if (flags & CERTDB_USER) - PORT_Strcat(trusts, "u"); - if (flags & CERTDB_SEND_WARN) - PORT_Strcat(trusts, "w"); - if (flags & CERTDB_INVISIBLE_CA) - PORT_Strcat(trusts, "I"); - if (flags & CERTDB_GOVT_APPROVED_CA) - PORT_Strcat(trusts, "G"); - return; -} - -char * -CERT_EncodeTrustString(CERTCertTrust *trust) -{ - char tmpTrustSSL[32]; - char tmpTrustEmail[32]; - char tmpTrustSigning[32]; - char *retstr = NULL; - - if ( trust ) { - tmpTrustSSL[0] = '\0'; - tmpTrustEmail[0] = '\0'; - tmpTrustSigning[0] = '\0'; - - EncodeFlags(tmpTrustSSL, trust->sslFlags); - EncodeFlags(tmpTrustEmail, trust->emailFlags); - EncodeFlags(tmpTrustSigning, trust->objectSigningFlags); - - retstr = PR_smprintf("%s,%s,%s", tmpTrustSSL, tmpTrustEmail, - tmpTrustSigning); - } - - return(retstr); -} - -SECStatus -CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage, - unsigned int ncerts, SECItem **derCerts, - CERTCertificate ***retCerts, PRBool keepCerts, - PRBool caOnly, char *nickname) -{ - int i; - CERTCertificate **certs = NULL; - SECStatus rv; - int fcerts; - - if ( ncerts ) { - certs = (CERTCertificate**)PORT_ZAlloc(sizeof(CERTCertificate *) * ncerts ); - if ( certs == NULL ) { - return(SECFailure); - } - - /* decode all of the certs into the temporary DB */ - for ( i = 0, fcerts= 0; i < ncerts; i++) { - certs[fcerts] = CERT_NewTempCertificate(certdb, derCerts[i], NULL, - PR_FALSE, PR_TRUE); - if (certs[fcerts]) fcerts++; - } - - if ( keepCerts ) { - for ( i = 0; i < fcerts; i++ ) { - SECKEY_UpdateCertPQG(certs[i]); - if(CERT_IsCACert(certs[i], NULL) && (fcerts > 1)) { - /* if we are importing only a single cert and specifying - * a nickname, we want to use that nickname if it a CA, - * otherwise if there are more than one cert, we don't - * know which cert it belongs to. - */ - rv = CERT_SaveImportedCert(certs[i], usage, caOnly, NULL); - } else { - rv = CERT_SaveImportedCert(certs[i], usage, caOnly, - nickname); - } - /* don't care if it fails - keep going */ - } - } - } - - if ( retCerts ) { - *retCerts = certs; - } else { - CERT_DestroyCertArray(certs, fcerts); - } - - return(SECSuccess); - -#if 0 /* dead code here - why ?? XXX */ -loser: - if ( retCerts ) { - *retCerts = NULL; - } - if ( certs ) { - CERT_DestroyCertArray(certs, ncerts); - } - return(SECFailure); -#endif -} - -/* - * a real list of certificates - need to convert CERTCertificateList - * stuff and ASN 1 encoder/decoder over to using this... - */ -CERTCertList * -CERT_NewCertList(void) -{ - PRArenaPool *arena = NULL; - CERTCertList *ret = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList)); - if ( ret == NULL ) { - goto loser; - } - - ret->arena = arena; - - PR_INIT_CLIST(&ret->list); - - return(ret); - -loser: - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -void -CERT_DestroyCertList(CERTCertList *certs) -{ - PRCList *node; - - while( !PR_CLIST_IS_EMPTY(&certs->list) ) { - node = PR_LIST_HEAD(&certs->list); - CERT_DestroyCertificate(((CERTCertListNode *)node)->cert); - PR_REMOVE_LINK(node); - } - - PORT_FreeArena(certs->arena, PR_FALSE); - - return; -} - -void -CERT_RemoveCertListNode(CERTCertListNode *node) -{ - CERT_DestroyCertificate(node->cert); - PR_REMOVE_LINK(&node->links); - return; -} - -SECStatus -CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert) -{ - CERTCertListNode *node; - - node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, - sizeof(CERTCertListNode)); - if ( node == NULL ) { - goto loser; - } - - PR_INSERT_BEFORE(&node->links, &certs->list); - /* certs->count++; */ - node->cert = cert; - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Sort callback function to determine if cert a is newer than cert b. - * Not valid certs are considered older than valid certs. - */ -PRBool -CERT_SortCBValidity(CERTCertificate *certa, - CERTCertificate *certb, - void *arg) -{ - int64 sorttime; - int64 notBeforeA, notAfterA, notBeforeB, notAfterB; - SECStatus rv; - PRBool newerbefore, newerafter; - PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE; - - sorttime = *(int64 *)arg; - - rv = CERT_GetCertTimes(certa, ¬BeforeA, ¬AfterA); - if ( rv != SECSuccess ) { - return(PR_FALSE); - } - - rv = CERT_GetCertTimes(certb, ¬BeforeB, ¬AfterB); - if ( rv != SECSuccess ) { - return(PR_TRUE); - } - newerbefore = PR_FALSE; - if ( LL_CMP(notBeforeA, >, notBeforeB) ) { - newerbefore = PR_TRUE; - } - newerafter = PR_FALSE; - if ( LL_CMP(notAfterA, >, notAfterB) ) { - newerafter = PR_TRUE; - } - - /* check if A is valid at sorttime */ - if ( CERT_CheckCertValidTimes(certa, sorttime, PR_FALSE) - != secCertTimeValid ) { - aNotValid = PR_TRUE; - } - - /* check if B is valid at sorttime */ - if ( CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE) - != secCertTimeValid ) { - bNotValid = PR_TRUE; - } - - /* a is valid, b is not */ - if ( bNotValid && ( ! aNotValid ) ) { - return(PR_TRUE); - } - - /* b is valid, a is not */ - if ( aNotValid && ( ! bNotValid ) ) { - return(PR_FALSE); - } - - /* a and b are either valid or not valid */ - if ( newerbefore && newerafter ) { - return(PR_TRUE); - } - - if ( ( !newerbefore ) && ( !newerafter ) ) { - return(PR_FALSE); - } - - if ( newerbefore ) { - /* cert A was issued after cert B, but expires sooner */ - return(PR_TRUE); - } else { - /* cert B was issued after cert A, but expires sooner */ - return(PR_FALSE); - } -} - - -SECStatus -CERT_AddCertToListSorted(CERTCertList *certs, - CERTCertificate *cert, - CERTSortCallback f, - void *arg) -{ - CERTCertListNode *node; - CERTCertListNode *head; - PRBool ret; - - node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, - sizeof(CERTCertListNode)); - if ( node == NULL ) { - goto loser; - } - - head = CERT_LIST_HEAD(certs); - - while ( !CERT_LIST_END(head, certs) ) { - - /* if cert is already in the list, then don't add it again */ - if ( cert == head->cert ) { - /*XXX*/ - /* don't keep a reference */ - CERT_DestroyCertificate(cert); - goto done; - } - - ret = (* f)(cert, head->cert, arg); - /* if sort function succeeds, then insert before current node */ - if ( ret ) { - PR_INSERT_BEFORE(&node->links, &head->links); - goto done; - } - - head = CERT_LIST_NEXT(head); - } - /* if we get to the end, then just insert it at the tail */ - PR_INSERT_BEFORE(&node->links, &certs->list); - -done: - /* certs->count++; */ - node->cert = cert; - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* This routine is here because pcertdb.c still has a call to it. - * The SMIME profile code in pcertdb.c should be split into high (find - * the email cert) and low (store the profile) code. At that point, we - * can move this to certhigh.c where it belongs. - * - * remove certs from a list that don't have keyUsage and certType - * that match the given usage. - */ -SECStatus -CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage, - PRBool ca) -{ - unsigned int requiredKeyUsage; - unsigned int requiredCertType; - CERTCertListNode *node, *savenode; - PRBool bad; - SECStatus rv; - unsigned int certType; - PRBool dummyret; - - if (certList == NULL) goto loser; - - rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage, - &requiredCertType); - if ( rv != SECSuccess ) { - goto loser; - } - - node = CERT_LIST_HEAD(certList); - - while ( !CERT_LIST_END(node, certList) ) { - - bad = PR_FALSE; - - /* bad key usage */ - if ( CERT_CheckKeyUsage(node->cert, requiredKeyUsage ) - != SECSuccess ) { - bad = PR_TRUE; - } - /* bad cert type */ - if ( ca ) { - /* This function returns a more comprehensive cert type that - * takes trust flags into consideration. Should probably - * fix the cert decoding code to do this. - */ - dummyret = CERT_IsCACert(node->cert, &certType); - } else { - certType = node->cert->nsCertType; - } - - if ( ! ( certType & requiredCertType ) ) { - bad = PR_TRUE; - } - - if ( bad ) { - /* remove the node if it is bad */ - savenode = CERT_LIST_NEXT(node); - CERT_RemoveCertListNode(node); - node = savenode; - } else { - node = CERT_LIST_NEXT(node); - } - } - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Acquire the global lock on the cert database. - * This lock is currently used for the following operations: - * adding or deleting a cert to either the temp or perm databases - * converting a temp to perm or perm to temp - * changing(maybe just adding????) the trust of a cert - * chaning the DB status checking Configuration - */ -void -CERT_LockDB(CERTCertDBHandle *handle) -{ - PR_EnterMonitor(handle->dbMon); - return; -} - -/* - * Free the global cert database lock. - */ -void -CERT_UnlockDB(CERTCertDBHandle *handle) -{ - PRStatus prstat; - - prstat = PR_ExitMonitor(handle->dbMon); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - -static PRLock *certRefCountLock = NULL; - -/* - * Acquire the cert reference count 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_LockCertRefCount(CERTCertificate *cert) -{ - if ( certRefCountLock == NULL ) { - nss_InitLock(&certRefCountLock); - PORT_Assert(certRefCountLock != NULL); - } - - PR_Lock(certRefCountLock); - return; -} - -/* - * Free the cert reference count lock - */ -void -CERT_UnlockCertRefCount(CERTCertificate *cert) -{ - PRStatus prstat; - - PORT_Assert(certRefCountLock != NULL); - - prstat = PR_Unlock(certRefCountLock); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - -static PRLock *certTrustLock = NULL; - -/* - * 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(CERTCertificate *cert) -{ - if ( certTrustLock == NULL ) { - nss_InitLock(&certTrustLock); - PORT_Assert(certTrustLock != NULL); - } - - PR_Lock(certTrustLock); - return; -} - -/* - * Free the cert trust lock - */ -void -CERT_UnlockCertTrust(CERTCertificate *cert) -{ - PRStatus prstat; - - PORT_Assert(certTrustLock != NULL); - - prstat = PR_Unlock(certTrustLock); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - - -/* - * Get the StatusConfig data for this handle - */ -CERTStatusConfig * -CERT_GetStatusConfig(CERTCertDBHandle *handle) -{ - return handle->statusConfig; -} - -/* - * Set the StatusConfig data for this handle. There - * should not be another configuration set. - */ -void -CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig) -{ - PORT_Assert(handle->statusConfig == NULL); - - handle->statusConfig = statusConfig; -} diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h deleted file mode 100644 index 7710b72c9..000000000 --- a/security/nss/lib/certdb/certdb.h +++ /dev/null @@ -1,396 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#ifndef _CERTDB_H_ -#define _CERTDB_H_ - -#include "plarena.h" -#include "prlong.h" -/* - * Certificate Database related definitions and data structures - */ - -/* version number of certificate database */ -#define CERT_DB_FILE_VERSION 7 -#ifdef USE_NS_ROOTS -#define CERT_DB_CONTENT_VERSION 24 -#else -#define CERT_DB_CONTENT_VERSION 2 -#endif - -#define SEC_DB_ENTRY_HEADER_LEN 3 -#define SEC_DB_KEY_HEADER_LEN 1 - -/* All database entries have this form: - * - * byte offset field - * ----------- ----- - * 0 version - * 1 type - * 2 flags - */ - -/* database entry types */ -typedef enum { - certDBEntryTypeVersion = 0, - certDBEntryTypeCert = 1, - certDBEntryTypeNickname = 2, - certDBEntryTypeSubject = 3, - certDBEntryTypeRevocation = 4, - certDBEntryTypeKeyRevocation = 5, - certDBEntryTypeSMimeProfile = 6, - certDBEntryTypeContentVersion = 7 -} certDBEntryType; - -typedef struct { - certDBEntryType type; - unsigned int version; - unsigned int flags; - PRArenaPool *arena; -} certDBEntryCommon; - -/* - * Certificate entry: - * - * byte offset field - * ----------- ----- - * 0 sslFlags-msb - * 1 sslFlags-lsb - * 2 emailFlags-msb - * 3 emailFlags-lsb - * 4 objectSigningFlags-msb - * 5 objectSigningFlags-lsb - * 6 derCert-len-msb - * 7 derCert-len-lsb - * 8 nickname-len-msb - * 9 nickname-len-lsb - * ... derCert - * ... nickname - * - * NOTE: the nickname string as stored in the database is null terminated, - * in other words, the last byte of the db entry is always 0 - * if a nickname is present. - * NOTE: if nickname is not present, then nickname-len-msb and - * nickname-len-lsb will both be zero. - */ -struct _certDBEntryCert { - certDBEntryCommon common; - CERTCertTrust trust; - SECItem derCert; - char *nickname; -}; - -/* - * Certificate Nickname entry: - * - * byte offset field - * ----------- ----- - * 0 subjectname-len-msb - * 1 subjectname-len-lsb - * 2... subjectname - * - * The database key for this type of entry is a nickname string - * The "subjectname" value is the DER encoded DN of the identity - * that matches this nickname. - */ -typedef struct { - certDBEntryCommon common; - char *nickname; - SECItem subjectName; -} certDBEntryNickname; - -#define DB_NICKNAME_ENTRY_HEADER_LEN 2 - -/* - * Certificate Subject entry: - * - * byte offset field - * ----------- ----- - * 0 ncerts-msb - * 1 ncerts-lsb - * 2 nickname-msb - * 3 nickname-lsb - * 4 emailAddr-msb - * 5 emailAddr-lsb - * ... nickname - * ... emailAddr - * ...+2*i certkey-len-msb - * ...+1+2*i certkey-len-lsb - * ...+2*ncerts+2*i keyid-len-msb - * ...+1+2*ncerts+2*i keyid-len-lsb - * ... certkeys - * ... keyids - * - * The database key for this type of entry is the DER encoded subject name - * The "certkey" value is an array of certificate database lookup keys that - * points to the database entries for the certificates that matche - * this subject. - * - */ -typedef struct _certDBEntrySubject { - certDBEntryCommon common; - SECItem derSubject; - unsigned int ncerts; - char *nickname; - char *emailAddr; - SECItem *certKeys; - SECItem *keyIDs; -} certDBEntrySubject; - -#define DB_SUBJECT_ENTRY_HEADER_LEN 6 - -/* - * Certificate SMIME profile entry: - * - * byte offset field - * ----------- ----- - * 0 subjectname-len-msb - * 1 subjectname-len-lsb - * 2 smimeoptions-len-msb - * 3 smimeoptions-len-lsb - * 4 options-date-len-msb - * 5 options-date-len-lsb - * 6... subjectname - * ... smimeoptions - * ... options-date - * - * The database key for this type of entry is the email address string - * The "subjectname" value is the DER encoded DN of the identity - * that matches this nickname. - * The "smimeoptions" value is a string that represents the algorithm - * capabilities on the remote user. - * The "options-date" is the date that the smime options value was created. - * This is generally the signing time of the signed message that contained - * the options. It is a UTCTime value. - */ -typedef struct { - certDBEntryCommon common; - char *emailAddr; - SECItem subjectName; - SECItem smimeOptions; - SECItem optionsDate; -} certDBEntrySMime; - -#define DB_SMIME_ENTRY_HEADER_LEN 6 - -/* - * Crl/krl entry: - * - * byte offset field - * ----------- ----- - * 0 derCert-len-msb - * 1 derCert-len-lsb - * 2 url-len-msb - * 3 url-len-lsb - * ... derCert - * ... url - * - * NOTE: the url string as stored in the database is null terminated, - * in other words, the last byte of the db entry is always 0 - * if a nickname is present. - * NOTE: if url is not present, then url-len-msb and - * url-len-lsb will both be zero. - */ -#define DB_CRL_ENTRY_HEADER_LEN 4 -struct _certDBEntryRevocation { - certDBEntryCommon common; - SECItem derCrl; - char *url; /* where to load the crl from */ -}; - -/* - * Database Version Entry: - * - * byte offset field - * ----------- ----- - * only the low level header... - * - * The database key for this type of entry is the string "Version" - */ -typedef struct { - certDBEntryCommon common; -} certDBEntryVersion; - -#define SEC_DB_VERSION_KEY "Version" -#define SEC_DB_VERSION_KEY_LEN sizeof(SEC_DB_VERSION_KEY) - -/* - * Database Content Version Entry: - * - * byte offset field - * ----------- ----- - * 0 contentVersion - * - * The database key for this type of entry is the string "ContentVersion" - */ -typedef struct { - certDBEntryCommon common; - char contentVersion; -} certDBEntryContentVersion; - -#define SEC_DB_CONTENT_VERSION_KEY "ContentVersion" -#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY) - -typedef union { - certDBEntryCommon common; - certDBEntryVersion version; - certDBEntryCert cert; - certDBEntryNickname nickname; - certDBEntrySubject subject; - certDBEntryRevocation revocation; -} certDBEntry; - -/* length of the fixed part of a database entry */ -#define DBCERT_V4_HEADER_LEN 7 -#define DB_CERT_V5_ENTRY_HEADER_LEN 7 -#define DB_CERT_V6_ENTRY_HEADER_LEN 7 -#define DB_CERT_ENTRY_HEADER_LEN 10 - -/* common flags for all types of certificates */ -#define CERTDB_VALID_PEER (1<<0) -#define CERTDB_TRUSTED (1<<1) -#define CERTDB_SEND_WARN (1<<2) -#define CERTDB_VALID_CA (1<<3) -#define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */ -#define CERTDB_NS_TRUSTED_CA (1<<5) -#define CERTDB_USER (1<<6) -#define CERTDB_TRUSTED_CLIENT_CA (1<<7) /* trusted for issuing client certs */ -#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */ -#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */ - -SEC_BEGIN_PROTOS - -/* -** Add a DER encoded certificate to the permanent database. -** "derCert" is the DER encoded certificate. -** "nickname" is the nickname to use for the cert -** "trust" is the trust parameters for the cert -*/ -SECStatus SEC_AddPermCertificate(CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, CERTCertTrust *trust); - -certDBEntryCert * -SEC_FindPermCertByKey(CERTCertDBHandle *handle, SECItem *certKey); - -certDBEntryCert -*SEC_FindPermCertByName(CERTCertDBHandle *handle, SECItem *name); - -SECStatus SEC_OpenPermCertDB(CERTCertDBHandle *handle, - PRBool readOnly, - CERTDBNameFunc namecb, - void *cbarg); - -SECStatus SEC_DeletePermCertificate(CERTCertificate *cert); - -typedef SECStatus (* PermCertCallback)(CERTCertificate *cert, SECItem *k, - void *pdata); -/* -** Traverse the entire permanent database, and pass the certs off to a -** user supplied function. -** "certfunc" is the user function to call for each certificate -** "udata" is the user's data, which is passed through to "certfunc" -*/ -SECStatus -SEC_TraversePermCerts(CERTCertDBHandle *handle, - PermCertCallback certfunc, - void *udata ); - -SECStatus -SEC_AddTempNickname(CERTCertDBHandle *handle, char *nickname, SECItem *certKey); - -SECStatus -SEC_DeleteTempNickname(CERTCertDBHandle *handle, char *nickname); - -PRBool -SEC_CertNicknameConflict(char *nickname, SECItem *derSubject, - CERTCertDBHandle *handle); - -PRBool -SEC_CertDBKeyConflict(SECItem *derCert, CERTCertDBHandle *handle); - -SECStatus -SEC_GetCrlTimes(CERTCrl *dates, int64 *notBefore, int64 *notAfter); - -SECCertTimeValidity -SEC_CheckCrlTimes(CERTCrl *crl, int64 t); - -PRBool -SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old); - -CERTSignedCrl * -SEC_AddPermCrlToTemp(CERTCertDBHandle *handle, certDBEntryRevocation *entry); - -SECStatus -SEC_DeleteTempCrl(CERTSignedCrl *crl); - -CERTSignedCrl * -SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type); - -CERTSignedCrl * -SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type); - -CERTSignedCrl * -SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type); - -SECStatus -SEC_DestroyCrl(CERTSignedCrl *crl); - -CERTSignedCrl * -SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type); - -CERTSignedCrl * -cert_DBInsertCRL - (CERTCertDBHandle *handle, char *url, - CERTSignedCrl *newCrl, SECItem *derCrl, int type); - -SECStatus -SEC_CheckKRL(CERTCertDBHandle *handle,SECKEYPublicKey *key, - CERTCertificate *rootCert, int64 t, void *wincx); - -SECStatus -SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, - CERTCertificate *caCert, int64 t, void *wincx); - -SECStatus -SEC_DeletePermCRL(CERTSignedCrl *crl); - - -SECStatus -SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type); - -SECStatus -SEC_CrlReplaceUrl(CERTSignedCrl *crl,char *url); - -SEC_END_PROTOS - -#endif /* _CERTDB_H_ */ diff --git a/security/nss/lib/certdb/certinit.c b/security/nss/lib/certdb/certinit.c deleted file mode 100644 index bc60ec733..000000000 --- a/security/nss/lib/certdb/certinit.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "cert.h" -#include "base64.h" -#include "mcom_db.h" -#include "certdb.h" - -static char example_com_server_ca[] = -"MIICBTCCAW6gAwIBAgIBATANBgkqhkiG9w0BAQQFADA+MREwDwYICZIm9ZgeZAET" -"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRIwEAYDVQQDEwlTZXJ2ZXIgQ0Ew" -"HhcNMDAwMjAzMjIyMDA3WhcNMTAwNTAzMjIyMDA3WjA+MREwDwYICZIm9ZgeZAET" -"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRIwEAYDVQQDEwlTZXJ2ZXIgQ0Ew" -"gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALGiKEvTd2k4ZJbdAVWokfFlB6Hz" -"WJXveXm8+IgmFlgtAnicZI11z5wAutFRvDpun7WmRLgHxvEhU3tLoiACGYdGJXPw" -"+lI2pzHzFSd63B0qcA/NVAW3EOBJeaEFwy0jkUaCIki8qQV06g8RosNX/zv6a+OF" -"d5NMpS0fecK4fEvdAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN" -"AQEEBQADgYEAi5rFiG6afWS1PHigssk2LwAJws5cszPbVIeIMHCBbtu259V7uWts" -"gNxUPJRjeQBsK0ItAfinC0xxLeuMbRfIdZoRYv/OYDxCwGW7hUcNLi+fHlGnJNXH" -"TWaCRdOwkljnws4v8ABas2DYA/k7xUFAygkIJd9NtE29ZrdrWpfSavI="; - -static char example_com_individual_ca[] = -"MIICDTCCAXagAwIBAgIBAjANBgkqhkiG9w0BAQQFADBCMREwDwYICZIm9ZgeZAET" -"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRYwFAYDVQQDEw1JbmRpdmlkdWFs" -"IENBMB4XDTAwMDIwMzIyMjE1NFoXDTEwMDUwMzIyMjE1NFowQjERMA8GCAmSJvWY" -"HmQBEwNjb20xFTATBggJkib1mB5kARMHRXhhbXBsZTEWMBQGA1UEAxMNSW5kaXZp" -"ZHVhbCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu5syfboe93MOkGec" -"dOuJholyX42wcaH/RgnL3C/8NnZp9WWaTaguvn7KrbCj4TAMzu0pabUN8apB3J60" -"9C/FlixjXF7r73OzbyTCM5ja6/bPfmHMPmDl9l/9tKqhh+loFvRizXDaWSFRViDS" -"XvKNeQztwwAOpEAqnJwyTkn4FjECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN" -"BgkqhkiG9w0BAQQFAAOBgQB1XK+5pXdXYq3O3TC/ZY5LWlZ7zuoWUO75OpuMY7XF" -"iW/jeXbVT5IYZXoRGXJFGGaDmnAuK1/m6FTDhjSTG0XUmd5tg4aFieI+LY4rkYEv" -"mbJElxKabXl5hVD4mg2bwYlFY7XBmifTa1Ll3HDX3VZM0DC1bm4KCHBnY0qXjSYq" -"PA=="; - -static char example_com_objsign_ca[] = -"MIICETCCAXqgAwIBAgIBAzANBgkqhkiG9w0BAQQFADBEMREwDwYICZIm9ZgeZAET" -"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRgwFgYDVQQDEw9Db2RlIFNpZ25p" -"bmcgQ0EwHhcNMDAwMjAzMjIyMzEzWhcNMTAwNTAzMjIyMzEzWjBEMREwDwYICZIm" -"9ZgeZAETA2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRgwFgYDVQQDEw9Db2Rl" -"IFNpZ25pbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALcy76InmpM9" -"S9K2MlNSjusx6nkYWWbx7eDRTV+xhRPeDxW4t8jtKPqDF5LTusyM9WCI/nneqsIP" -"7iTSHpxlGx37J1VbqKX5fZsfJ3wKv6ZIylzeRuFY9MFypPA2UmVd1ACDOUB3YDvY" -"mrCVkOPEhjnZKbq4FfCpf8KNL2A5EBcZAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB" -"Af8wDQYJKoZIhvcNAQEEBQADgYEAI0IXzwgBRXvow3JQi8Y4YdG2wZc4BWRGW87x" -"2zOD7GOA0CWN149vb6rEchECykDsJj9LoBl6o1aRxk9WkIFnXmMOJSuJA+ilCe//" -"81a5OhKbe0p7ym6rh190BLwh2VePFeyabq6NipfZlN6qgWUzoepf+jVblufW/2EI" -"fbMSylc="; - -/* This is the cert->certKey (serial number and issuer name) of - * the cert that we want to revoke. - */ -static unsigned char revoked_system_principal_key[] = { -0x40, 0x18, 0xf2, 0x35, 0x86, 0x06, 0x78, 0xce, 0x87, 0x89, -0x0c, 0x5d, 0x68, 0x67, 0x33, 0x09, 0x30, 0x81, 0xc1, 0x31, -0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, -0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, -0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, -0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, -0x0b, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, -0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x3a, 0x30, -0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x56, 0x65, -0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x62, 0x6a, -0x65, 0x63, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, -0x67, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x43, 0x6c, 0x61, -0x73, 0x73, 0x20, 0x33, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e, -0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x49, 0x30, -0x47, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x40, 0x77, 0x77, -0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, -0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x49, -0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x62, 0x79, 0x20, 0x52, -0x65, 0x66, 0x2e, 0x20, 0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, -0x49, 0x54, 0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63, -0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, -0x67, 0x6e -}; - -SECStatus -CERT_CheckForEvilCert(CERTCertificate *cert) -{ - if ( cert->certKey.len == sizeof(revoked_system_principal_key) ) { - if ( PORT_Memcmp(cert->certKey.data, - revoked_system_principal_key, - sizeof(revoked_system_principal_key)) == 0 ) { - return(SECFailure); - } - } - - return(SECSuccess); -} - -#define DEFAULT_TRUST_FLAGS (CERTDB_VALID_CA | \ - CERTDB_TRUSTED_CA | \ - CERTDB_NS_TRUSTED_CA) - -typedef enum { - certUpdateNone, - certUpdateAdd, - certUpdateDelete, - certUpdateAddTrust, - certUpdateRemoveTrust, - certUpdateSetTrust -} certUpdateOp; - -typedef struct { - char *cert; - char *nickname; - CERTCertTrust trust; - int updateVersion; - certUpdateOp op; - CERTCertTrust trustDelta; -} certInitEntry; - -static certInitEntry initialcerts[] = { - { - example_com_server_ca, - "Example.com Server CA", - { DEFAULT_TRUST_FLAGS | CERTDB_GOVT_APPROVED_CA, 0, 0 }, - 1, - certUpdateAdd, - { 0, 0, 0 } - }, - { - example_com_server_ca, - "Example.com Server CA", - { DEFAULT_TRUST_FLAGS | CERTDB_GOVT_APPROVED_CA, 0, 0 }, - 2, - certUpdateAddTrust, - { CERTDB_GOVT_APPROVED_CA, 0, 0 } - }, - - { - example_com_individual_ca, - "Example.com Individual CA", - { 0, DEFAULT_TRUST_FLAGS, 0 }, - 1, - certUpdateAdd, - { 0, 0, 0 } - }, - { - example_com_individual_ca, - "Example.com Individual CA", - { 0, DEFAULT_TRUST_FLAGS, 0 }, - 2, - certUpdateRemoveTrust, - { 0, 0, DEFAULT_TRUST_FLAGS } - }, - - { - example_com_objsign_ca, - "Example.com Code Signing CA", - { 0, 0, DEFAULT_TRUST_FLAGS }, - 2, - certUpdateAdd, - { 0, 0, 0 } - }, - - { - 0, 0 - } -}; - - -static SECStatus -ConvertAndCheckCertificate(CERTCertDBHandle *handle, char *asciicert, - char *nickname, CERTCertTrust *trust) -{ - SECItem sdder; - SECStatus rv; - CERTCertificate *cert; - PRBool conflict; - SECItem derSubject; - - /* First convert ascii to binary */ - rv = ATOB_ConvertAsciiToItem (&sdder, asciicert); - if (rv != SECSuccess) { - return(rv); - } - - /* - ** Inside the ascii is a Signed Certificate. - */ - - cert = NULL; - - /* make sure that no conflicts exist */ - conflict = SEC_CertDBKeyConflict(&sdder, handle); - if ( conflict ) { - goto done; - } - - rv = CERT_NameFromDERCert(&sdder, &derSubject); - if ( rv != SECSuccess ) { - goto loser; - } - - conflict = SEC_CertNicknameConflict(nickname, &derSubject, handle); - if ( conflict ) { - goto done; - } - - cert = CERT_NewTempCertificate(handle, &sdder, NULL, PR_FALSE, PR_TRUE); - if ( cert == NULL ) { - goto loser; - } - - rv = CERT_AddTempCertToPerm(cert, nickname, trust); - - CERT_DestroyCertificate(cert); - - if (rv == SECSuccess) { - /* - ** XXX should verify signatures too, if we have the certificate for - ** XXX its issuer... - */ - } - -done: - PORT_Free(sdder.data); - return(rv); - -loser: - return(SECFailure); -} - -extern void certdb_InitDBLock(void); - -SECStatus -CERT_InitCertDB(CERTCertDBHandle *handle) -{ - SECStatus rv; - certInitEntry *entry; - - certdb_InitDBLock(); - - entry = initialcerts; - - while ( entry->cert != NULL) { - if ( entry->op != certUpdateDelete ) { - rv = ConvertAndCheckCertificate(handle, entry->cert, - entry->nickname, &entry->trust); - /* keep going */ - } - - entry++; - } -done: - CERT_SetDBContentVersion(CERT_DB_CONTENT_VERSION, handle); - return(rv); -} - -static CERTCertificate * -CertFromEntry(CERTCertDBHandle *handle, char *asciicert) -{ - SECItem sdder; - SECStatus rv; - CERTCertificate *cert; - - /* First convert ascii to binary */ - rv = ATOB_ConvertAsciiToItem (&sdder, asciicert); - if (rv != SECSuccess) { - return(NULL); - } - - /* - ** Inside the ascii is a Signed Certificate. - */ - - cert = CERT_NewTempCertificate(handle, &sdder, NULL, PR_FALSE, PR_TRUE); - - return(cert); -} - -SECStatus -CERT_AddNewCerts(CERTCertDBHandle *handle) -{ - int oldversion; - int newversion; - certInitEntry *entry; - CERTCertTrust tmptrust; - SECStatus rv; - CERTCertificate *cert; - - newversion = CERT_DB_CONTENT_VERSION; - - oldversion = CERT_GetDBContentVersion(handle); - - if ( newversion > oldversion ) { - entry = initialcerts; - - while ( entry->cert != NULL ) { - if ( entry->updateVersion > oldversion ) { - switch ( entry->op ) { - default: - break; - case certUpdateAdd: - rv = ConvertAndCheckCertificate(handle, entry->cert, - entry->nickname, - &entry->trust); - break; - case certUpdateDelete: - cert = CertFromEntry(handle, entry->cert); - if ( cert != NULL ) { - if ( cert->isperm ) { - rv = SEC_DeletePermCertificate(cert); - } - CERT_DestroyCertificate(cert); - } - break; - case certUpdateAddTrust: - cert = CertFromEntry(handle, entry->cert); - if ( cert != NULL ) { - if ( cert->isperm ) { - tmptrust = *cert->trust; - tmptrust.sslFlags |= entry->trustDelta.sslFlags; - tmptrust.emailFlags |= - entry->trustDelta.emailFlags; - tmptrust.objectSigningFlags |= - entry->trustDelta.objectSigningFlags; - rv = CERT_ChangeCertTrust(handle, cert, -&tmptrust); - } - CERT_DestroyCertificate(cert); - } - break; - case certUpdateRemoveTrust: - cert = CertFromEntry(handle, entry->cert); - if ( cert != NULL ) { - if ( cert->isperm ) { - tmptrust = *cert->trust; - tmptrust.sslFlags &= - (~entry->trustDelta.sslFlags); - tmptrust.emailFlags &= - (~entry->trustDelta.emailFlags); - tmptrust.objectSigningFlags &= - (~entry->trustDelta.objectSigningFlags); - rv = CERT_ChangeCertTrust(handle, cert, -&tmptrust); - } - CERT_DestroyCertificate(cert); - } - break; - case certUpdateSetTrust: - cert = CertFromEntry(handle, entry->cert); - if ( cert != NULL ) { - if ( cert->isperm ) { - tmptrust = *cert->trust; - tmptrust.sslFlags = entry->trustDelta.sslFlags; - tmptrust.emailFlags = - entry->trustDelta.emailFlags; - tmptrust.objectSigningFlags = - entry->trustDelta.objectSigningFlags; - rv = CERT_ChangeCertTrust(handle, cert, -&tmptrust); - } - CERT_DestroyCertificate(cert); - } - break; - } - } - - entry++; - } - - CERT_SetDBContentVersion(newversion, handle); - } - - return(SECSuccess); -} diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h deleted file mode 100644 index ffaaaca66..000000000 --- a/security/nss/lib/certdb/certt.h +++ /dev/null @@ -1,804 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ -/* - * certt.h - public data structures for the certificate library - * - * $Id$ - */ -#ifndef _CERTT_H_ -#define _CERTT_H_ - -#include "prclist.h" -#include "pkcs11t.h" -#include "seccomon.h" -#include "secmodt.h" -#include "secoidt.h" -#include "plarena.h" -#include "prcvar.h" -#include "prlock.h" -#include "prio.h" -#include "prmon.h" - -/* Non-opaque objects */ -typedef struct CERTAVAStr CERTAVA; -typedef struct CERTAttributeStr CERTAttribute; -typedef struct CERTAuthInfoAccessStr CERTAuthInfoAccess; -typedef struct CERTAuthKeyIDStr CERTAuthKeyID; -typedef struct CERTBasicConstraintsStr CERTBasicConstraints; -typedef struct CERTCertDBHandleStr CERTCertDBHandle; -typedef struct CERTCertExtensionStr CERTCertExtension; -typedef struct CERTCertKeyStr CERTCertKey; -typedef struct CERTCertListStr CERTCertList; -typedef struct CERTCertListNodeStr CERTCertListNode; -typedef struct CERTCertNicknamesStr CERTCertNicknames; -typedef struct CERTCertTrustStr CERTCertTrust; -typedef struct CERTCertificateStr CERTCertificate; -typedef struct CERTCertificateListStr CERTCertificateList; -typedef struct CERTCertificateRequestStr CERTCertificateRequest; -typedef struct CERTCrlStr CERTCrl; -typedef struct CERTCrlDistributionPointsStr CERTCrlDistributionPoints; -typedef struct CERTCrlEntryStr CERTCrlEntry; -typedef struct CERTCrlHeadNodeStr CERTCrlHeadNode; -typedef struct CERTCrlKeyStr CERTCrlKey; -typedef struct CERTCrlNodeStr CERTCrlNode; -typedef struct CERTDERCertsStr CERTDERCerts; -typedef struct CERTDistNamesStr CERTDistNames; -typedef struct CERTGeneralNameStr CERTGeneralName; -typedef struct CERTGeneralNameListStr CERTGeneralNameList; -typedef struct CERTIssuerAndSNStr CERTIssuerAndSN; -typedef struct CERTNameStr CERTName; -typedef struct CERTNameConstraintStr CERTNameConstraint; -typedef struct CERTNameConstraintsStr CERTNameConstraints; -typedef struct CERTOKDomainNameStr CERTOKDomainName; -typedef struct CERTPublicKeyAndChallengeStr CERTPublicKeyAndChallenge; -typedef struct CERTRDNStr CERTRDN; -typedef struct CERTSignedCrlStr CERTSignedCrl; -typedef struct CERTSignedDataStr CERTSignedData; -typedef struct CERTStatusConfigStr CERTStatusConfig; -typedef struct CERTSubjectListStr CERTSubjectList; -typedef struct CERTSubjectNodeStr CERTSubjectNode; -typedef struct CERTSubjectPublicKeyInfoStr CERTSubjectPublicKeyInfo; -typedef struct CERTValidityStr CERTValidity; -typedef struct CERTVerifyLogStr CERTVerifyLog; -typedef struct CERTVerifyLogNodeStr CERTVerifyLogNode; -typedef struct CRLDistributionPointStr CRLDistributionPoint; - -/* CRL extensions type */ -typedef unsigned long CERTCrlNumber; - -/* -** An X.500 AVA object -*/ -struct CERTAVAStr { - SECItem type; - SECItem value; -}; - -/* -** An X.500 RDN object -*/ -struct CERTRDNStr { - CERTAVA **avas; -}; - -/* -** An X.500 name object -*/ -struct CERTNameStr { - PRArenaPool *arena; - CERTRDN **rdns; -}; - -/* -** An X.509 validity object -*/ -struct CERTValidityStr { - PRArenaPool *arena; - SECItem notBefore; - SECItem notAfter; -}; - -/* - * A serial number and issuer name, which is used as a database key - */ -struct CERTCertKeyStr { - SECItem serialNumber; - SECItem derIssuer; -}; - -/* -** A signed data object. Used to implement the "signed" macro used -** in the X.500 specs. -*/ -struct CERTSignedDataStr { - SECItem data; - SECAlgorithmID signatureAlgorithm; - SECItem signature; -}; - -/* -** An X.509 subject-public-key-info object -*/ -struct CERTSubjectPublicKeyInfoStr { - PRArenaPool *arena; - SECAlgorithmID algorithm; - SECItem subjectPublicKey; -}; - -struct CERTPublicKeyAndChallengeStr { - SECItem spki; - SECItem challenge; -}; - -typedef struct _certDBEntryCert certDBEntryCert; -typedef struct _certDBEntryRevocation certDBEntryRevocation; - -struct CERTCertTrustStr { - unsigned int sslFlags; - unsigned int emailFlags; - unsigned int objectSigningFlags; -}; - -/* - * defined the types of trust that exist - */ -typedef enum { - trustSSL, - trustEmail, - trustObjectSigning, - trustTypeNone -} SECTrustType; - -#define SEC_GET_TRUST_FLAGS(trust,type) \ - (((type)==trustSSL)?((trust)->sslFlags): \ - (((type)==trustEmail)?((trust)->emailFlags): \ - (((type)==trustObjectSigning)?((trust)->objectSigningFlags):0))) - -/* -** An X.509.3 certificate extension -*/ -struct CERTCertExtensionStr { - SECItem id; - SECItem critical; - SECItem value; -}; - -struct CERTSubjectNodeStr { - struct CERTSubjectNodeStr *next; - struct CERTSubjectNodeStr *prev; - SECItem certKey; - SECItem keyID; -}; - -struct CERTSubjectListStr { - PRArenaPool *arena; - int ncerts; - char *emailAddr; - CERTSubjectNode *head; - CERTSubjectNode *tail; /* do we need tail? */ - struct _certDBEntrySubject *entry; -}; - -/* -** An X.509 certificate object (the unsigned form) -*/ -struct CERTCertificateStr { - /* the arena is used to allocate any data structures that have the same - * lifetime as the cert. This is all stuff that hangs off of the cert - * structure, and is all freed at the same time. I is used when the - * cert is decoded, destroyed, and at some times when it changes - * state - */ - PRArenaPool *arena; - - /* The following fields are static after the cert has been decoded */ - char *subjectName; - char *issuerName; - CERTSignedData signatureWrap; /* XXX */ - SECItem derCert; /* original DER for the cert */ - SECItem derIssuer; /* DER for issuer name */ - SECItem derSubject; /* DER for subject name */ - SECItem derPublicKey; /* DER for the public key */ - SECItem certKey; /* database key for this cert */ - SECItem version; - SECItem serialNumber; - SECAlgorithmID signature; - CERTName issuer; - CERTValidity validity; - CERTName subject; - CERTSubjectPublicKeyInfo subjectPublicKeyInfo; - SECItem issuerID; - SECItem subjectID; - CERTCertExtension **extensions; - char *emailAddr; - CERTCertDBHandle *dbhandle; - SECItem subjectKeyID; /* x509v3 subject key identifier */ - PRBool keyIDGenerated; /* was the keyid generated? */ - unsigned int keyUsage; /* what uses are allowed for this cert */ - unsigned int rawKeyUsage; /* value of the key usage extension */ - PRBool keyUsagePresent; /* was the key usage extension present */ - unsigned int nsCertType; /* value of the ns cert type extension */ - - /* these values can be set by the application to bypass certain checks - * or to keep the cert in memory for an entire session. - * XXX - need an api to set these - */ - PRBool keepSession; /* keep this cert for entire session*/ - PRBool timeOK; /* is the bad validity time ok? */ - CERTOKDomainName *domainOK; /* these domain names are ok */ - - /* - * these values can change when the cert changes state. These state - * changes include transitions from temp to perm or vice-versa, and - * changes of trust flags - */ - PRBool isperm; - PRBool istemp; - char *nickname; - char *dbnickname; - certDBEntryCert *dbEntry; /* database entry struct */ - CERTCertTrust *trust; - - /* the reference count is modified whenever someone looks up, dups - * or destroys a certificate - */ - int referenceCount; - - /* The subject list is a list of all certs with the same subject name. - * It can be modified any time a cert is added or deleted from either - * the in-memory(temporary) or on-disk(permanent) database. - */ - CERTSubjectList *subjectList; - - /* these fields are used by client GUI code to keep track of ssl sockets - * that are blocked waiting on GUI feedback related to this cert. - * XXX - these should be moved into some sort of application specific - * data structure. They are only used by the browser right now. - */ - struct SECSocketNode *socketlist; - int socketcount; - struct SECSocketNode *authsocketlist; - int authsocketcount; - - /* This is PKCS #11 stuff. */ - PK11SlotInfo *slot; /*if this cert came of a token, which is it*/ - CK_OBJECT_HANDLE pkcs11ID; /*and which object on that token is it */ - PRBool ownSlot; /*true if the cert owns the slot reference */ -}; -#define SEC_CERTIFICATE_VERSION_1 0 /* default created */ -#define SEC_CERTIFICATE_VERSION_2 1 /* v2 */ -#define SEC_CERTIFICATE_VERSION_3 2 /* v3 extensions */ - -#define SEC_CRL_VERSION_1 0 /* default */ -#define SEC_CRL_VERSION_2 1 /* v2 extensions */ - -/* - * used to identify class of cert in mime stream code - */ -#define SEC_CERT_CLASS_CA 1 -#define SEC_CERT_CLASS_SERVER 2 -#define SEC_CERT_CLASS_USER 3 -#define SEC_CERT_CLASS_EMAIL 4 - -struct CERTDERCertsStr { - PRArenaPool *arena; - int numcerts; - SECItem *rawCerts; -}; - -/* -** A PKCS ? Attribute -** XXX this is duplicated through out the code, it *should* be moved -** to a central location. Where would be appropriate? -*/ -struct CERTAttributeStr { - SECItem attrType; - SECItem **attrValue; -}; - -/* -** A PKCS#10 certificate-request object (the unsigned form) -*/ -struct CERTCertificateRequestStr { - PRArenaPool *arena; - SECItem version; - CERTName subject; - CERTSubjectPublicKeyInfo subjectPublicKeyInfo; - SECItem **attributes; -}; -#define SEC_CERTIFICATE_REQUEST_VERSION 0 /* what we *create* */ - - -/* -** A certificate list object. -*/ -struct CERTCertificateListStr { - SECItem *certs; - int len; /* number of certs */ - PRArenaPool *arena; -}; - -struct CERTCertListNodeStr { - PRCList links; - CERTCertificate *cert; - void *appData; -}; - -struct CERTCertListStr { - PRCList list; - PRArenaPool *arena; -}; - -#define CERT_LIST_HEAD(l) ((CERTCertListNode *)PR_LIST_HEAD(&l->list)) -#define CERT_LIST_NEXT(n) ((CERTCertListNode *)n->links.next) -#define CERT_LIST_END(n,l) (((void *)n) == ((void *)&l->list)) - -struct CERTCrlEntryStr { - SECItem serialNumber; - SECItem revocationDate; - CERTCertExtension **extensions; -}; - -struct CERTCrlStr { - PRArenaPool *arena; - SECItem version; - SECAlgorithmID signatureAlg; - SECItem derName; - CERTName name; - SECItem lastUpdate; - SECItem nextUpdate; /* optional for x.509 CRL */ - CERTCrlEntry **entries; - CERTCertExtension **extensions; -}; - -struct CERTCrlKeyStr { - SECItem derName; - SECItem dummy; /* The decoder can not skip a primitive, - this serves as a place holder for the - decoder to finish its task only - */ -}; - -struct CERTSignedCrlStr { - PRArenaPool *arena; - CERTCrl crl; - certDBEntryRevocation *dbEntry; /* database entry struct */ - PRBool keep; /* keep this crl in the cache for the session*/ - PRBool isperm; - PRBool istemp; - int referenceCount; - CERTCertDBHandle *dbhandle; - CERTSignedData signatureWrap; /* XXX */ - char *url; -}; - - -struct CERTCrlHeadNodeStr { - PRArenaPool *arena; - CERTCertDBHandle *dbhandle; - CERTCrlNode *first; - CERTCrlNode *last; -}; - - -struct CERTCrlNodeStr { - CERTCrlNode *next; - int type; - CERTSignedCrl *crl; -}; - - -/* - * Array of X.500 Distinguished Names - */ -struct CERTDistNamesStr { - PRArenaPool *arena; - int nnames; - SECItem *names; - void *head; /* private */ -}; - - -#define NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ -#define NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ -#define NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ -#define NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ -#define NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ -#define NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ -#define NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ -#define NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ - -#define EXT_KEY_USAGE_TIME_STAMP (0x8000) -#define EXT_KEY_USAGE_STATUS_RESPONDER (0x4000) - -#define NS_CERT_TYPE_APP ( NS_CERT_TYPE_SSL_CLIENT | \ - NS_CERT_TYPE_SSL_SERVER | \ - NS_CERT_TYPE_EMAIL | \ - NS_CERT_TYPE_OBJECT_SIGNING ) - -#define NS_CERT_TYPE_CA ( NS_CERT_TYPE_SSL_CA | \ - NS_CERT_TYPE_EMAIL_CA | \ - NS_CERT_TYPE_OBJECT_SIGNING_CA | \ - EXT_KEY_USAGE_STATUS_RESPONDER ) -typedef enum { - certUsageSSLClient, - certUsageSSLServer, - certUsageSSLServerWithStepUp, - certUsageSSLCA, - certUsageEmailSigner, - certUsageEmailRecipient, - certUsageObjectSigner, - certUsageUserCertImport, - certUsageVerifyCA, - certUsageProtectedObjectSigner, - certUsageStatusResponder, - certUsageAnyCA -} SECCertUsage; - -/* - * Does the cert belong to the user, a peer, or a CA. - */ -typedef enum { - certOwnerUser, - certOwnerPeer, - certOwnerCA -} CERTCertOwner; - -/* - * This enum represents the state of validity times of a certificate - */ -typedef enum { - secCertTimeValid, - secCertTimeExpired, - secCertTimeNotValidYet -} SECCertTimeValidity; - -/* - * Interface for getting certificate nickname strings out of the database - */ - -/* these are values for the what argument below */ -#define SEC_CERT_NICKNAMES_ALL 1 -#define SEC_CERT_NICKNAMES_USER 2 -#define SEC_CERT_NICKNAMES_SERVER 3 -#define SEC_CERT_NICKNAMES_CA 4 - -struct CERTCertNicknamesStr { - PRArenaPool *arena; - void *head; - int numnicknames; - char **nicknames; - int what; - int totallen; -}; - -struct CERTIssuerAndSNStr { - SECItem derIssuer; - CERTName issuer; - SECItem serialNumber; -}; - - -/* X.509 v3 Key Usage Extension flags */ -#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ -#define KU_NON_REPUDIATION (0x40) /* bit 1 */ -#define KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ -#define KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ -#define KU_KEY_AGREEMENT (0x08) /* bit 4 */ -#define KU_KEY_CERT_SIGN (0x04) /* bit 5 */ -#define KU_CRL_SIGN (0x02) /* bit 6 */ -#define KU_ALL (KU_DIGITAL_SIGNATURE | \ - KU_NON_REPUDIATION | \ - KU_KEY_ENCIPHERMENT | \ - KU_DATA_ENCIPHERMENT | \ - KU_KEY_AGREEMENT | \ - KU_KEY_CERT_SIGN | \ - KU_CRL_SIGN) - -/* This value will not occur in certs. It is used internally for the case - * when the key type is not know ahead of time and either key agreement or - * key encipherment are the correct value based on key type - */ -#define KU_KEY_AGREEMENT_OR_ENCIPHERMENT (0x4000) - -/* internal bits that do not match bits in the x509v3 spec, but are used - * for similar purposes - */ -#define KU_NS_GOVT_APPROVED (0x8000) /*don't make part of KU_ALL!*/ -/* - * x.509 v3 Basic Constraints Extension - * If isCA is false, the pathLenConstraint is ignored. - * Otherwise, the following pathLenConstraint values will apply: - * < 0 - there is no limit to the certificate path - * 0 - CA can issues end-entity certificates only - * > 0 - the number of certificates in the certificate path is - * limited to this number - */ -#define CERT_UNLIMITED_PATH_CONSTRAINT -2 - -struct CERTBasicConstraintsStr { - PRBool isCA; /* on if is CA */ - int pathLenConstraint; /* maximum number of certificates that can be - in the cert path. Only applies to a CA - certificate; otherwise, it's ignored. - */ -}; - -/* Maximum length of a certificate chain */ -#define CERT_MAX_CERT_CHAIN 20 - -/* x.509 v3 Reason Falgs, used in CRLDistributionPoint Extension */ -#define RF_UNUSED (0x80) /* bit 0 */ -#define RF_KEY_COMPROMISE (0x40) /* bit 1 */ -#define RF_CA_COMPROMISE (0x20) /* bit 2 */ -#define RF_AFFILIATION_CHANGED (0x10) /* bit 3 */ -#define RF_SUPERSEDED (0x08) /* bit 4 */ -#define RF_CESSATION_OF_OPERATION (0x04) /* bit 5 */ -#define RF_CERTIFICATE_HOLD (0x02) /* bit 6 */ - -/* If we needed to extract the general name field, use this */ -/* General Name types */ -typedef enum { - certOtherName = 1, - certRFC822Name = 2, - certDNSName = 3, - certX400Address = 4, - certDirectoryName = 5, - certEDIPartyName = 6, - certURI = 7, - certIPAddress = 8, - certRegisterID = 9 -} CERTGeneralNameType; - - -typedef struct OtherNameStr { - SECItem name; - SECItem oid; -}OtherName; - - - -struct CERTGeneralNameStr { - CERTGeneralNameType type; /* name type */ - union { - CERTName directoryName; /* distinguish name */ - OtherName OthName; /* Other Name */ - SECItem other; /* the rest of the name forms */ - }name; - SECItem derDirectoryName; /* this is saved to simplify directory name - comparison */ - PRCList l; -}; - -struct CERTGeneralNameListStr { - PRArenaPool *arena; - CERTGeneralName *name; - int refCount; - int len; - PRLock *lock; -}; - -struct CERTNameConstraintStr { - CERTGeneralName name; - SECItem DERName; - SECItem min; - SECItem max; - PRCList l; -}; - - -struct CERTNameConstraintsStr { - CERTNameConstraint *permited; - CERTNameConstraint *excluded; - SECItem **DERPermited; - SECItem **DERExcluded; -}; - - -/* X.509 v3 Authority Key Identifier extension. For the authority certificate - issuer field, we only support URI now. - */ -struct CERTAuthKeyIDStr { - SECItem keyID; /* unique key identifier */ - CERTGeneralName *authCertIssuer; /* CA's issuer name. End with a NULL */ - SECItem authCertSerialNumber; /* CA's certificate serial number */ - SECItem **DERAuthCertIssuer; /* This holds the DER encoded format of - the authCertIssuer field. It is used - by the encoding engine. It should be - used as a read only field by the caller. - */ -}; - -/* x.509 v3 CRL Distributeion Point */ - -/* - * defined the types of CRL Distribution points - */ -typedef enum { - generalName = 1, /* only support this for now */ - relativeDistinguishedName = 2 -} DistributionPointTypes; - -struct CRLDistributionPointStr { - DistributionPointTypes distPointType; - union { - CERTGeneralName *fullName; - CERTRDN relativeName; - } distPoint; - SECItem reasons; - CERTGeneralName *crlIssuer; - - /* Reserved for internal use only*/ - SECItem derDistPoint; - SECItem derRelativeName; - SECItem **derCrlIssuer; - SECItem **derFullName; - SECItem bitsmap; -}; - -struct CERTCrlDistributionPointsStr { - CRLDistributionPoint **distPoints; -}; - -/* - * This structure is used to keep a log of errors when verifying - * a cert chain. This allows multiple errors to be reported all at - * once. - */ -struct CERTVerifyLogNodeStr { - CERTCertificate *cert; /* what cert had the error */ - long error; /* what error was it? */ - unsigned int depth; /* how far up the chain are we */ - void *arg; /* error specific argument */ - struct CERTVerifyLogNodeStr *next; /* next in the list */ - struct CERTVerifyLogNodeStr *prev; /* next in the list */ -}; - - -struct CERTVerifyLogStr { - PRArenaPool *arena; - unsigned int count; - struct CERTVerifyLogNodeStr *head; - struct CERTVerifyLogNodeStr *tail; -}; - - -struct CERTOKDomainNameStr { - CERTOKDomainName *next; - char name[1]; /* actual length may be longer. */ -}; - - -typedef SECStatus PR_CALLBACK (*CERTStatusChecker) (CERTCertDBHandle *handle, - CERTCertificate *cert, - int64 time, - void *pwArg); - -typedef SECStatus PR_CALLBACK (*CERTStatusDestroy) (CERTStatusConfig *handle); - -struct CERTStatusConfigStr { - CERTStatusChecker statusChecker; /* NULL means no checking enabled */ - CERTStatusDestroy statusDestroy; /* enabled or no, will clean up */ - void *statusContext; /* cx specific to checking protocol */ -}; - -struct CERTAuthInfoAccessStr { - SECItem method; - SECItem derLocation; - CERTGeneralName *location; /* decoded location */ -}; - - -/* This is the typedef for the callback passed to CERT_OpenCertDB() */ -/* callback to return database name based on version number */ -typedef char * (*CERTDBNameFunc)(void *arg, int dbVersion); - -/* - * types of cert packages that we can decode - */ -typedef enum { - certPackageNone, - certPackageCert, - certPackagePKCS7, - certPackageNSCertSeq, - certPackageNSCertWrap -} CERTPackageType; - -/* - * these types are for the PKIX Certificate Policies extension - */ -typedef struct { - SECOidTag oid; - SECItem qualifierID; - SECItem qualifierValue; -} CERTPolicyQualifier; - -typedef struct { - SECOidTag oid; - SECItem policyID; - CERTPolicyQualifier **policyQualifiers; -} CERTPolicyInfo; - -typedef struct { - PRArenaPool *arena; - CERTPolicyInfo **policyInfos; -} CERTCertificatePolicies; - -typedef struct { - SECItem organization; - SECItem **noticeNumbers; -} CERTNoticeReference; - -typedef struct { - PRArenaPool *arena; - CERTNoticeReference noticeReference; - SECItem derNoticeReference; - SECItem displayText; -} CERTUserNotice; - -typedef struct { - PRArenaPool *arena; - SECItem **oids; -} CERTOidSequence; - - -/* XXX Lisa thinks the template declarations belong in cert.h, not here? */ - -#include "secasn1t.h" /* way down here because I expect template stuff to - * move out of here anyway */ - -extern const SEC_ASN1Template CERT_CertificateRequestTemplate[]; -extern const SEC_ASN1Template CERT_CertificateTemplate[]; -extern const SEC_ASN1Template SEC_SignedCertificateTemplate[]; -extern const SEC_ASN1Template CERT_CertExtensionTemplate[]; -extern const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[]; -extern const SEC_ASN1Template SECKEY_PublicKeyTemplate[]; -extern const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[]; -extern const SEC_ASN1Template CERT_ValidityTemplate[]; -extern const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[]; -extern const SEC_ASN1Template SEC_CertSequenceTemplate[]; - -extern const SEC_ASN1Template CERT_IssuerAndSNTemplate[]; -extern const SEC_ASN1Template CERT_NameTemplate[]; -extern const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[]; -extern const SEC_ASN1Template CERT_RDNTemplate[]; -extern const SEC_ASN1Template CERT_SignedDataTemplate[]; -extern const SEC_ASN1Template CERT_CrlTemplate[]; - -/* -** XXX should the attribute stuff be centralized for all of ns/security? -*/ -extern const SEC_ASN1Template CERT_AttributeTemplate[]; -extern const SEC_ASN1Template CERT_SetOfAttributeTemplate[]; - -#endif /* _CERTT_H_ */ diff --git a/security/nss/lib/certdb/certv3.c b/security/nss/lib/certdb/certv3.c deleted file mode 100644 index ea1016234..000000000 --- a/security/nss/lib/certdb/certv3.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Code for dealing with X509.V3 extensions. - * - * $Id$ - */ - -#include "cert.h" -#include "secitem.h" -#include "secoid.h" -#include "secder.h" -#include "secasn1.h" -#include "certxutl.h" -#include "secerr.h" - -SECStatus -CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid, - SECItem *value) -{ - return (cert_FindExtensionByOID (cert->extensions, oid, value)); -} - - -SECStatus -CERT_FindCertExtension(CERTCertificate *cert, int tag, SECItem *value) -{ - return (cert_FindExtension (cert->extensions, tag, value)); -} - -static void -SetExts(void *object, CERTCertExtension **exts) -{ - CERTCertificate *cert = (CERTCertificate *)object; - - cert->extensions = exts; - DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3); -} - -void * -CERT_StartCertExtensions(CERTCertificate *cert) -{ - return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); -} - -/* find the given extension in the certificate of the Issuer of 'cert' */ -SECStatus -CERT_FindIssuerCertExtension(CERTCertificate *cert, int tag, SECItem *value) -{ - CERTCertificate *issuercert; - SECStatus rv; - - issuercert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer); - if ( issuercert ) { - rv = cert_FindExtension(issuercert->extensions, tag, value); - CERT_DestroyCertificate(issuercert); - } else { - rv = SECFailure; - } - - return(rv); -} - -/* find a URL extension in the cert or its CA - * apply the base URL string if it exists - */ -char * -CERT_FindCertURLExtension(CERTCertificate *cert, int tag, int catag) -{ - SECStatus rv; - SECItem urlitem; - SECItem baseitem; - SECItem urlstringitem = {siBuffer,0}; - SECItem basestringitem = {siBuffer,0}; - PRArenaPool *arena = NULL; - PRBool hasbase; - char *urlstring; - char *str; - int len; - int i; - - urlstring = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( ! arena ) { - goto loser; - } - - hasbase = PR_FALSE; - urlitem.data = NULL; - baseitem.data = NULL; - - rv = cert_FindExtension(cert->extensions, tag, &urlitem); - if ( rv == SECSuccess ) { - rv = cert_FindExtension(cert->extensions, SEC_OID_NS_CERT_EXT_BASE_URL, - &baseitem); - if ( rv == SECSuccess ) { - hasbase = PR_TRUE; - } - - } else if ( catag ) { - /* if the cert doesn't have the extensions, see if the issuer does */ - rv = CERT_FindIssuerCertExtension(cert, catag, &urlitem); - if ( rv != SECSuccess ) { - goto loser; - } - rv = CERT_FindIssuerCertExtension(cert, SEC_OID_NS_CERT_EXT_BASE_URL, - &baseitem); - if ( rv == SECSuccess ) { - hasbase = PR_TRUE; - } - } else { - goto loser; - } - - rv = SEC_ASN1DecodeItem(arena, &urlstringitem, SEC_IA5StringTemplate, - &urlitem); - - if ( rv != SECSuccess ) { - goto loser; - } - if ( hasbase ) { - rv = SEC_ASN1DecodeItem(arena, &basestringitem, SEC_IA5StringTemplate, - &baseitem); - - if ( rv != SECSuccess ) { - goto loser; - } - } - - len = urlstringitem.len + ( hasbase ? basestringitem.len : 0 ) + 1; - - str = urlstring = (char *)PORT_Alloc(len); - if ( urlstring == NULL ) { - goto loser; - } - - /* copy the URL base first */ - if ( hasbase ) { - - /* if the urlstring has a : in it, then we assume it is an absolute - * URL, and will not get the base string pre-pended - */ - for ( i = 0; i < urlstringitem.len; i++ ) { - if ( urlstringitem.data[i] == ':' ) { - goto nobase; - } - } - - PORT_Memcpy(str, basestringitem.data, basestringitem.len); - str += basestringitem.len; - - } - -nobase: - /* copy the rest (or all) of the URL */ - PORT_Memcpy(str, urlstringitem.data, urlstringitem.len); - str += urlstringitem.len; - - *str = '\0'; - goto done; - -loser: - if ( urlstring ) { - PORT_Free(urlstring); - } - - urlstring = NULL; -done: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - if ( baseitem.data ) { - PORT_Free(baseitem.data); - } - if ( urlitem.data ) { - PORT_Free(urlitem.data); - } - - return(urlstring); -} - -/* - * get the value of the Netscape Certificate Type Extension - */ -SECStatus -CERT_FindNSCertTypeExtension(CERTCertificate *cert, SECItem *retItem) -{ - - return (CERT_FindBitStringExtension - (cert->extensions, SEC_OID_NS_CERT_EXT_CERT_TYPE, retItem)); -} - - -/* - * get the value of a string type extension - */ -char * -CERT_FindNSStringExtension(CERTCertificate *cert, int oidtag) -{ - SECItem wrapperItem, tmpItem = {siBuffer,0}; - SECStatus rv; - PRArenaPool *arena = NULL; - char *retstring = NULL; - - wrapperItem.data = NULL; - tmpItem.data = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( ! arena ) { - goto loser; - } - - rv = cert_FindExtension(cert->extensions, oidtag, - &wrapperItem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = SEC_ASN1DecodeItem(arena, &tmpItem, SEC_IA5StringTemplate, - &wrapperItem); - - if ( rv != SECSuccess ) { - goto loser; - } - - retstring = (char *)PORT_Alloc(tmpItem.len + 1 ); - if ( retstring == NULL ) { - goto loser; - } - - PORT_Memcpy(retstring, tmpItem.data, tmpItem.len); - retstring[tmpItem.len] = '\0'; - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - if ( wrapperItem.data ) { - PORT_Free(wrapperItem.data); - } - - return(retstring); -} - -/* - * get the value of the X.509 v3 Key Usage Extension - */ -SECStatus -CERT_FindKeyUsageExtension(CERTCertificate *cert, SECItem *retItem) -{ - - return (CERT_FindBitStringExtension(cert->extensions, - SEC_OID_X509_KEY_USAGE, retItem)); -} - -/* - * get the value of the X.509 v3 Key Usage Extension - */ -SECStatus -CERT_FindSubjectKeyIDExten(CERTCertificate *cert, SECItem *retItem) -{ - - SECItem encodedValue; - SECStatus rv; - - encodedValue.data = NULL; - rv = cert_FindExtension - (cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue); - if (rv != SECSuccess) - return (rv); - rv = SEC_ASN1DecodeItem (NULL, retItem, SEC_OctetStringTemplate, - &encodedValue); - PORT_Free (encodedValue.data); - - return (rv); -} - -SECStatus -CERT_FindBasicConstraintExten(CERTCertificate *cert, - CERTBasicConstraints *value) -{ - SECItem encodedExtenValue; - SECStatus rv; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS, - &encodedExtenValue); - if ( rv != SECSuccess ) { - return (rv); - } - - rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue); - - /* free the raw extension data */ - PORT_Free(encodedExtenValue.data); - encodedExtenValue.data = NULL; - - return(rv); -} - -CERTAuthKeyID * -CERT_FindAuthKeyIDExten (PRArenaPool *arena, CERTCertificate *cert) -{ - SECItem encodedExtenValue; - SECStatus rv; - CERTAuthKeyID *ret; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID, - &encodedExtenValue); - if ( rv != SECSuccess ) { - return (NULL); - } - - ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue); - - PORT_Free(encodedExtenValue.data); - encodedExtenValue.data = NULL; - - return(ret); -} - -SECStatus -CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage) -{ - PRBool critical; - SECItem keyUsage; - SECStatus rv; - - /* There is no extension, v1 or v2 certificate */ - if (cert->extensions == NULL) { - return (SECSuccess); - } - - keyUsage.data = NULL; - - do { - /* if the keyUsage extension exists and is critical, make sure that the - CA certificate is used for certificate signing purpose only. If the - extension does not exist, we will assum that it can be used for - certificate signing purpose. - */ - rv = CERT_GetExtenCriticality(cert->extensions, - SEC_OID_X509_KEY_USAGE, - &critical); - if (rv == SECFailure) { - rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ? - SECSuccess : SECFailure; - break; - } - - if (critical == PR_FALSE) { - rv = SECSuccess; - break; - } - - rv = CERT_FindKeyUsageExtension(cert, &keyUsage); - if (rv != SECSuccess) { - break; - } - if (!(keyUsage.data[0] & usage)) { - PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID); - rv = SECFailure; - } - }while (0); - PORT_Free (keyUsage.data); - return (rv); -} diff --git a/security/nss/lib/certdb/certxutl.c b/security/nss/lib/certdb/certxutl.c deleted file mode 100644 index 619f576b2..000000000 --- a/security/nss/lib/certdb/certxutl.c +++ /dev/null @@ -1,482 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Certificate Extensions handling code - * - */ - -#include "cert.h" -#include "secitem.h" -#include "secoid.h" -#include "secder.h" -#include "secasn1.h" -#include "certxutl.h" -#include "secerr.h" - -#ifdef OLD -#include "ocspti.h" /* XXX a better extensions interface would not - * require knowledge of data structures of callers */ -#endif - -static CERTCertExtension * -GetExtension (CERTCertExtension **extensions, SECItem *oid) -{ - CERTCertExtension **exts; - CERTCertExtension *ext = NULL; - SECComparison comp; - - exts = extensions; - - if (exts) { - while ( *exts ) { - ext = *exts; - comp = SECITEM_CompareItem(oid, &ext->id); - if ( comp == SECEqual ) - break; - - exts++; - } - return (*exts ? ext : NULL); - } - return (NULL); -} - -SECStatus -cert_FindExtensionByOID (CERTCertExtension **extensions, SECItem *oid, SECItem *value) -{ - CERTCertExtension *ext; - SECStatus rv = SECSuccess; - - ext = GetExtension (extensions, oid); - if (ext == NULL) { - PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND); - return (SECFailure); - } - if (value) - rv = SECITEM_CopyItem(NULL, value, &ext->value); - return (rv); -} - - -SECStatus -CERT_GetExtenCriticality (CERTCertExtension **extensions, int tag, PRBool *isCritical) -{ - CERTCertExtension *ext; - SECOidData *oid; - - if (!isCritical) - return (SECSuccess); - - /* find the extension in the extensions list */ - oid = SECOID_FindOIDByTag((SECOidTag)tag); - if ( !oid ) { - return(SECFailure); - } - ext = GetExtension (extensions, &oid->oid); - if (ext == NULL) { - PORT_SetError (SEC_ERROR_EXTENSION_NOT_FOUND); - return (SECFailure); - } - - /* If the criticality is omitted, then it is false by default. - ex->critical.data is NULL */ - if (ext->critical.data == NULL) - *isCritical = PR_FALSE; - else - *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE; - return (SECSuccess); -} - -SECStatus -cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value) -{ - SECOidData *oid; - - oid = SECOID_FindOIDByTag((SECOidTag)tag); - if ( !oid ) { - return(SECFailure); - } - - return(cert_FindExtensionByOID(extensions, &oid->oid, value)); -} - - -typedef struct _extNode { - struct _extNode *next; - CERTCertExtension *ext; -} extNode; - -typedef struct { - void (*setExts)(void *object, CERTCertExtension **exts); - void *object; - PRArenaPool *ownerArena; - PRArenaPool *arena; - extNode *head; - int count; -}extRec; - -/* - * cert_StartExtensions - * - * NOTE: This interface changed significantly to remove knowledge - * about callers data structures (owner objects) - */ -void * -cert_StartExtensions(void *owner, PRArenaPool *ownerArena, - void (*setExts)(void *object, CERTCertExtension **exts)) -{ - PRArenaPool *arena; - extRec *handle; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( !arena ) { - return(0); - } - - handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec)); - if ( !handle ) { - PORT_FreeArena(arena, PR_FALSE); - return(0); - } - - handle->object = owner; - handle->ownerArena = ownerArena; - handle->setExts = setExts; - - handle->arena = arena; - handle->head = 0; - handle->count = 0; - - return(handle); -} - -static unsigned char hextrue = 0xff; - -/* - * Note - assumes that data pointed to by oid->data will not move - */ -SECStatus -CERT_AddExtensionByOID (void *exthandle, SECItem *oid, SECItem *value, - PRBool critical, PRBool copyData) -{ - CERTCertExtension *ext; - SECStatus rv; - extNode *node; - extRec *handle; - - handle = (extRec *)exthandle; - - /* allocate space for extension and list node */ - ext = (CERTCertExtension*)PORT_ArenaZAlloc(handle->ownerArena, - sizeof(CERTCertExtension)); - if ( !ext ) { - return(SECFailure); - } - - node = (extNode*)PORT_ArenaAlloc(handle->arena, sizeof(extNode)); - if ( !node ) { - return(SECFailure); - } - - /* add to list */ - node->next = handle->head; - handle->head = node; - - /* point to ext struct */ - node->ext = ext; - - /* the object ID of the extension */ - ext->id = *oid; - - /* set critical field */ - if ( critical ) { - ext->critical.data = (unsigned char*)&hextrue; - ext->critical.len = 1; - } - - /* set the value */ - if ( copyData ) { - rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value); - if ( rv ) { - return(SECFailure); - } - } else { - ext->value = *value; - } - - handle->count++; - - return(SECSuccess); - -} - -SECStatus -CERT_AddExtension(void *exthandle, int idtag, SECItem *value, - PRBool critical, PRBool copyData) -{ - SECOidData *oid; - - oid = SECOID_FindOIDByTag((SECOidTag)idtag); - if ( !oid ) { - return(SECFailure); - } - - return(CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical, copyData)); -} - -SECStatus -CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value, - PRBool critical, const SEC_ASN1Template *atemplate) -{ - extRec *handle; - SECItem *encitem; - - handle = (extRec *)exthandle; - - encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate); - if ( encitem == NULL ) { - return(SECFailure); - } - - return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE); -} - -void -PrepareBitStringForEncoding (SECItem *bitsmap, SECItem *value) -{ - unsigned char onebyte; - unsigned int i, len = 0; - - /* to prevent warning on some platform at compile time */ - onebyte = '\0'; - /* Get the position of the right-most turn-on bit */ - for (i = 0; i < (value->len ) * 8; ++i) { - if (i % 8 == 0) - onebyte = value->data[i/8]; - if (onebyte & 0x80) - len = i; - onebyte <<= 1; - - } - bitsmap->data = value->data; - /* Add one here since we work with base 1 */ - bitsmap->len = len + 1; -} - -SECStatus -CERT_EncodeAndAddBitStrExtension (void *exthandle, int idtag, - SECItem *value, PRBool critical) -{ - SECItem bitsmap; - - PrepareBitStringForEncoding (&bitsmap, value); - return (CERT_EncodeAndAddExtension - (exthandle, idtag, &bitsmap, critical, SEC_BitStringTemplate)); -} - -SECStatus -CERT_FinishExtensions(void *exthandle) -{ - extRec *handle; - extNode *node; - CERTCertExtension **exts; - SECStatus rv = SECFailure; - - handle = (extRec *)exthandle; - - /* allocate space for extensions array */ - exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *, - handle->count + 1); - if (exts == NULL) { - goto loser; - } - - /* put extensions in owner object and update its version number */ - -#ifdef OLD - switch (handle->type) { - case CertificateExtensions: - handle->owner.cert->extensions = exts; - DER_SetUInteger (ownerArena, &(handle->owner.cert->version), - SEC_CERTIFICATE_VERSION_3); - break; - case CrlExtensions: - handle->owner.crl->extensions = exts; - DER_SetUInteger (ownerArena, &(handle->owner.crl->version), - SEC_CRL_VERSION_2); - break; - case OCSPRequestExtensions: - handle->owner.request->tbsRequest->requestExtensions = exts; - break; - case OCSPSingleRequestExtensions: - handle->owner.singleRequest->singleRequestExtensions = exts; - break; - case OCSPResponseSingleExtensions: - handle->owner.singleResponse->singleExtensions = exts; - break; - } -#endif - - handle->setExts(handle->object, exts); - - /* update the version number */ - - /* copy each extension pointer */ - node = handle->head; - while ( node ) { - *exts = node->ext; - - node = node->next; - exts++; - } - - /* terminate the array of extensions */ - *exts = 0; - - rv = SECSuccess; - -loser: - /* free working arena */ - PORT_FreeArena(handle->arena, PR_FALSE); - return rv; -} - -/* - * get the value of the Netscape Certificate Type Extension - */ -SECStatus -CERT_FindBitStringExtension (CERTCertExtension **extensions, int tag, - SECItem *retItem) -{ - SECItem wrapperItem, tmpItem = {siBuffer,0}; - SECStatus rv; - PRArenaPool *arena = NULL; - - wrapperItem.data = NULL; - tmpItem.data = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( ! arena ) { - return(SECFailure); - } - - rv = cert_FindExtension(extensions, tag, &wrapperItem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = SEC_ASN1DecodeItem(arena, &tmpItem, SEC_BitStringTemplate, - &wrapperItem); - - if ( rv != SECSuccess ) { - goto loser; - } - - retItem->data = (unsigned char *)PORT_Alloc( ( tmpItem.len + 7 ) >> 3 ); - if ( retItem->data == NULL ) { - goto loser; - } - - PORT_Memcpy(retItem->data, tmpItem.data, ( tmpItem.len + 7 ) >> 3); - retItem->len = tmpItem.len; - - rv = SECSuccess; - goto done; - -loser: - rv = SECFailure; - -done: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - if ( wrapperItem.data ) { - PORT_Free(wrapperItem.data); - } - - return(rv); -} - -PRBool -cert_HasCriticalExtension (CERTCertExtension **extensions) -{ - CERTCertExtension **exts; - CERTCertExtension *ext = NULL; - PRBool hasCriticalExten = PR_FALSE; - - exts = extensions; - - if (exts) { - while ( *exts ) { - ext = *exts; - /* If the criticality is omitted, it's non-critical */ - if (ext->critical.data && ext->critical.data[0] == 0xff) { - hasCriticalExten = PR_TRUE; - break; - } - exts++; - } - } - return (hasCriticalExten); -} - -PRBool -cert_HasUnknownCriticalExten (CERTCertExtension **extensions) -{ - CERTCertExtension **exts; - CERTCertExtension *ext = NULL; - PRBool hasUnknownCriticalExten = PR_FALSE; - - exts = extensions; - - if (exts) { - while ( *exts ) { - ext = *exts; - /* If the criticality is omitted, it's non-critical. - If an extension is critical, make sure that we know - how to process the extension. - */ - if (ext->critical.data && ext->critical.data[0] == 0xff) { - if (SECOID_KnownCertExtenOID (&ext->id) == PR_FALSE) { - hasUnknownCriticalExten = PR_TRUE; - break; - } - } - exts++; - } - } - return (hasUnknownCriticalExten); -} diff --git a/security/nss/lib/certdb/certxutl.h b/security/nss/lib/certdb/certxutl.h deleted file mode 100644 index 381226a43..000000000 --- a/security/nss/lib/certdb/certxutl.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * x.509 v3 certificate extension helper routines - * - */ - - -#ifndef _CERTXUTL_H_ -#define _CERTXUTL_H_ - -#include "nspr.h" - -#ifdef OLD -typedef enum { - CertificateExtensions, - CrlExtensions, - OCSPRequestExtensions, - OCSPSingleRequestExtensions, - OCSPResponseSingleExtensions -} ExtensionsType; -#endif - -extern PRBool -cert_HasCriticalExtension (CERTCertExtension **extensions); - -extern SECStatus -CERT_FindBitStringExtension (CERTCertExtension **extensions, - int tag, SECItem *retItem); -extern void * -cert_StartExtensions (void *owner, PLArenaPool *arena, - void (*setExts)(void *object, CERTCertExtension **exts)); - -extern SECStatus -cert_FindExtension (CERTCertExtension **extensions, int tag, SECItem *value); - -extern SECStatus -cert_FindExtensionByOID (CERTCertExtension **extensions, - SECItem *oid, SECItem *value); - -extern SECStatus -cert_GetExtenCriticality (CERTCertExtension **extensions, - int tag, PRBool *isCritical); - -extern PRBool -cert_HasUnknownCriticalExten (CERTCertExtension **extensions); - -#endif diff --git a/security/nss/lib/certdb/config.mk b/security/nss/lib/certdb/config.mk deleted file mode 100644 index a73a1086e..000000000 --- a/security/nss/lib/certdb/config.mk +++ /dev/null @@ -1,44 +0,0 @@ -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -# -# Override TARGETS variable so that only static libraries -# are specifed as dependencies within rules.mk. -# - -TARGETS = $(LIBRARY) -SHARED_LIBRARY = -IMPORT_LIBRARY = -PURE_LIBRARY = -PROGRAM = - diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c deleted file mode 100644 index 1e0e909e1..000000000 --- a/security/nss/lib/certdb/crl.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Moved from secpkcs7.c - * - * $Id$ - */ - -#include "cert.h" -#include "secder.h" -#include "secasn1.h" -#include "secoid.h" -#include "certdb.h" -#include "certxutl.h" -#include "prtime.h" -#include "secerr.h" - -const SEC_ASN1Template SEC_CERTExtensionTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertExtension) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTCertExtension,id) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ - offsetof(CERTCertExtension,critical), }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTCertExtension,value) }, - { 0, } -}; - -static const SEC_ASN1Template SEC_CERTExtensionsTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, SEC_CERTExtensionTemplate} -}; - -/* - * XXX Also, these templates, especially the Krl/FORTEZZA ones, need to - * be tested; Lisa did the obvious translation but they still should be - * verified. - */ - -const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTIssuerAndSN) }, - { SEC_ASN1_SAVE, - offsetof(CERTIssuerAndSN,derIssuer) }, - { SEC_ASN1_INLINE, - offsetof(CERTIssuerAndSN,issuer), - CERT_NameTemplate }, - { SEC_ASN1_INTEGER, - offsetof(CERTIssuerAndSN,serialNumber) }, - { 0 } -}; - -static const SEC_ASN1Template cert_KrlEntryTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrlEntry) }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTCrlEntry,serialNumber) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrlEntry,revocationDate) }, - { 0 } -}; - -static const SEC_ASN1Template cert_KrlTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrl) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,signatureAlg), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_SAVE, - offsetof(CERTCrl,derName) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,name), - CERT_NameTemplate }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,lastUpdate) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,nextUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCrl,entries), - cert_KrlEntryTemplate }, - { 0 } -}; - -static const SEC_ASN1Template cert_SignedKrlTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTSignedCrl) }, - { SEC_ASN1_SAVE, - offsetof(CERTSignedCrl,signatureWrap.data) }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedCrl,crl), - cert_KrlTemplate }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedCrl,signatureWrap.signatureAlgorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(CERTSignedCrl,signatureWrap.signature) }, - { 0 } -}; - -static const SEC_ASN1Template cert_CrlKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrlKey) }, - { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(CERTCrlKey,dummy) }, - { SEC_ASN1_SKIP }, - { SEC_ASN1_ANY, offsetof(CERTCrlKey,derName) }, - { SEC_ASN1_SKIP_REST }, - { 0 } -}; - -static const SEC_ASN1Template cert_CrlEntryTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrlEntry) }, - { SEC_ASN1_INTEGER, - offsetof(CERTCrlEntry,serialNumber) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrlEntry,revocationDate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCrlEntry, extensions), - SEC_CERTExtensionTemplate}, - { 0 } -}; - -const SEC_ASN1Template CERT_CrlTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrl) }, - { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof (CERTCrl, version) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,signatureAlg), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_SAVE, - offsetof(CERTCrl,derName) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,name), - CERT_NameTemplate }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,lastUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,nextUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCrl,entries), - cert_CrlEntryTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_EXPLICIT | 0, - offsetof(CERTCrl,extensions), - SEC_CERTExtensionsTemplate}, - { 0 } -}; - -static const SEC_ASN1Template cert_SignedCrlTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTSignedCrl) }, - { SEC_ASN1_SAVE, - offsetof(CERTSignedCrl,signatureWrap.data) }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedCrl,crl), - CERT_CrlTemplate }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedCrl,signatureWrap.signatureAlgorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(CERTSignedCrl,signatureWrap.signature) }, - { 0 } -}; - -const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[] = { - { SEC_ASN1_SET_OF, 0, cert_SignedCrlTemplate }, -}; - -/* Check the version of the CRL. If there is a critical extension in the crl - or crl entry, then the version must be v2. Otherwise, it should be v1. If - the crl contains critical extension(s), then we must recognized the extension's - OID. - */ -SECStatus cert_check_crl_version (CERTCrl *crl) -{ - CERTCrlEntry **entries; - CERTCrlEntry *entry; - PRBool hasCriticalExten = PR_FALSE; - SECStatus rv = SECSuccess; - int version; - - /* CRL version is defaulted to v1 */ - version = SEC_CRL_VERSION_1; - if (crl->version.data != 0) - version = (int)DER_GetUInteger (&crl->version); - - if (version > SEC_CRL_VERSION_2) { - PORT_SetError (SEC_ERROR_BAD_DER); - return (SECFailure); - } - - /* Check the crl extensions for a critial extension. If one is found, - and the version is not v2, then we are done. - */ - if (crl->extensions) { - hasCriticalExten = cert_HasCriticalExtension (crl->extensions); - if (hasCriticalExten) { - if (version != SEC_CRL_VERSION_2) - return (SECFailure); - /* make sure that there is no unknown critical extension */ - if (cert_HasUnknownCriticalExten (crl->extensions) == PR_TRUE) { - PORT_SetError (SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); - return (SECFailure); - } - } - } - - - if (crl->entries == NULL) { - if (hasCriticalExten == PR_FALSE && version == SEC_CRL_VERSION_2) { - PORT_SetError (SEC_ERROR_BAD_DER); - return (SECFailure); - } - return (SECSuccess); - } - /* Look in the crl entry extensions. If there is a critical extension, - then the crl version must be v2; otherwise, it should be v1. - */ - entries = crl->entries; - while (*entries) { - entry = *entries; - if (entry->extensions) { - /* If there is a critical extension in the entries, then the - CRL must be of version 2. If we already saw a critical extension, - there is no need to check the version again. - */ - if (hasCriticalExten == PR_FALSE) { - hasCriticalExten = cert_HasCriticalExtension (entry->extensions); - if (hasCriticalExten && version != SEC_CRL_VERSION_2) { - rv = SECFailure; - break; - } - } - - /* For each entry, make sure that it does not contain an unknown - critical extension. If it does, we must reject the CRL since - we don't know how to process the extension. - */ - if (cert_HasUnknownCriticalExten (entry->extensions) == PR_TRUE) { - PORT_SetError (SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); - rv = SECFailure; - break; - } - } - ++entries; - } - if (rv == SECFailure) - return (rv); - - /* There is no critical extension, but the version is set to v2 */ - if (version != SEC_CRL_VERSION_1 && hasCriticalExten == PR_FALSE) { - PORT_SetError (SEC_ERROR_BAD_DER); - return (SECFailure); - } - return (SECSuccess); -} - -/* - * Generate a database key, based on the issuer name from a - * DER crl. - */ -SECStatus -CERT_KeyFromDERCrl(PRArenaPool *arena, SECItem *derCrl, SECItem *key) -{ - SECStatus rv; - CERTSignedData sd; - CERTCrlKey crlkey; - - PORT_Memset (&sd, 0, sizeof (sd)); - rv = SEC_ASN1DecodeItem (arena, &sd, CERT_SignedDataTemplate, derCrl); - if (rv != SECSuccess) { - return rv; - } - - PORT_Memset (&crlkey, 0, sizeof (crlkey)); - rv = SEC_ASN1DecodeItem(arena, &crlkey, cert_CrlKeyTemplate, &sd.data); - if (rv != SECSuccess) { - return rv; - } - - key->len = crlkey.derName.len; - key->data = crlkey.derName.data; - - return(SECSuccess); -} - -/* - * take a DER CRL or KRL and decode it into a CRL structure - */ -CERTSignedCrl * -CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) -{ - PRArenaPool *arena; - CERTSignedCrl *crl; - SECStatus rv; - - /* make a new arena */ - if (narena == NULL) { - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( !arena ) { - return NULL; - } - } else { - arena = narena; - } - - /* allocate the CRL structure */ - crl = (CERTSignedCrl *)PORT_ArenaZAlloc(arena, sizeof(CERTSignedCrl)); - if ( !crl ) { - goto loser; - } - - crl->arena = arena; - - /* Save the arena in the inner crl for CRL extensions support */ - crl->crl.arena = arena; - - /* decode the CRL info */ - switch (type) { - case SEC_CRL_TYPE: - rv = SEC_ASN1DecodeItem - (arena, crl, cert_SignedCrlTemplate, derSignedCrl); - if (rv != SECSuccess) - break; - - /* If the version is set to v2, make sure that it contains at - least 1 critical extension either the crl extensions or - crl entry extensions. */ - rv = cert_check_crl_version (&crl->crl); - break; - - case SEC_KRL_TYPE: - rv = SEC_ASN1DecodeItem - (arena, crl, cert_SignedKrlTemplate, derSignedCrl); - break; - default: - rv = SECFailure; - break; - } - - if (rv != SECSuccess) { - goto loser; - } - - crl->referenceCount = 1; - - return(crl); - -loser: - - if ((narena == NULL) && arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(0); -} diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c deleted file mode 100644 index a603b8cec..000000000 --- a/security/nss/lib/certdb/genname.c +++ /dev/null @@ -1,1589 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "plarena.h" -#include "seccomon.h" -#include "secitem.h" -#include "secoidt.h" -#include "mcom_db.h" -#include "secasn1.h" -#include "secder.h" -#include "certt.h" -#include "cert.h" -#include "xconst.h" -#include "secerr.h" -#include "secoid.h" -#include "prprf.h" -#include "genname.h" - - - -static const SEC_ASN1Template CERTNameConstraintTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) }, - { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTNameConstraint, min), SEC_IntegerTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTNameConstraint, max), SEC_IntegerTemplate }, - { 0, } -}; - -const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate } -}; - - -const SEC_ASN1Template CERT_NameConstraintSubtreePermitedTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 0, 0, CERT_NameConstraintSubtreeSubTemplate } -}; - -const SEC_ASN1Template CERT_NameConstraintSubtreeExcludedTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 1, 0, CERT_NameConstraintSubtreeSubTemplate } -}; - - -static const SEC_ASN1Template CERTNameConstraintsTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTNameConstraints, DERPermited), CERT_NameConstraintSubtreeSubTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTNameConstraints, DERExcluded), CERT_NameConstraintSubtreeSubTemplate}, - { 0, } -}; - - -static const SEC_ASN1Template CERTOthNameTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) }, - { SEC_ASN1_OBJECT_ID, - offsetof(OtherName, oid) }, - { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, - offsetof(OtherName, name), SEC_AnyTemplate }, - { 0, } -}; - -static const SEC_ASN1Template CERTOtherNameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 0 , - offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate, - sizeof(CERTGeneralName) } -}; - -static const SEC_ASN1Template CERTOtherName2Template[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_CONTEXT_SPECIFIC | 0 , - 0, NULL, sizeof(CERTGeneralName) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, oid) }, - { SEC_ASN1_ANY, - offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, name) }, - { 0, } -}; - -static const SEC_ASN1Template CERT_RFC822NameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 1 , - offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_DNSNameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 2 , - offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_X400AddressTemplate[] = { - { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 3, - offsetof(CERTGeneralName, name.other), SEC_AnyTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 4, - offsetof(CERTGeneralName, derDirectoryName), SEC_AnyTemplate, - sizeof (CERTGeneralName)} -}; - - -static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = { - { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 5, - offsetof(CERTGeneralName, name.other), SEC_AnyTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_URITemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 6 , - offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_IPAddressTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 7 , - offsetof(CERTGeneralName, name.other), SEC_OctetStringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 8 , - offsetof(CERTGeneralName, name.other), SEC_ObjectIDTemplate, - sizeof (CERTGeneralName)} -}; - - -const SEC_ASN1Template CERT_GeneralNamesTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate } -}; - - - -void -CERT_DestroyGeneralNameList(CERTGeneralNameList *list) -{ - PRLock *lock; - - if (list != NULL) { - lock = list->lock; - PR_Lock(lock); - if (--list->refCount <= 0 && list->arena != NULL) { - PORT_FreeArena(list->arena, PR_FALSE); - PR_Unlock(lock); - PR_DestroyLock(lock); - } else { - PR_Unlock(lock); - } - } - return; -} - -CERTGeneralNameList * -CERT_CreateGeneralNameList(CERTGeneralName *name) { - PRArenaPool *arena; - CERTGeneralNameList *list = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto done; - } - list = (CERTGeneralNameList *) - PORT_ArenaZAlloc(arena, sizeof(CERTGeneralNameList)); - if (name != NULL) { - list->name = (CERTGeneralName *) - PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - list->name->l.next = list->name->l.prev = &list->name->l; - CERT_CopyGeneralName(arena, list->name, name); - } - list->lock = PR_NewLock(); - list->arena = arena; - list->refCount = 1; -done: - return list; -} - -CERTGeneralName * -cert_get_next_general_name(CERTGeneralName *current) -{ - PRCList *next; - - next = current->l.next; - return (CERTGeneralName *) (((char *) next) - offsetof(CERTGeneralName, l)); -} - -CERTGeneralName * -cert_get_prev_general_name(CERTGeneralName *current) -{ - PRCList *prev; - prev = current->l.prev; - return (CERTGeneralName *) (((char *) prev) - offsetof(CERTGeneralName, l)); -} - -CERTNameConstraint * -cert_get_next_name_constraint(CERTNameConstraint *current) -{ - PRCList *next; - - next = current->l.next; - return (CERTNameConstraint *) (((char *) next) - offsetof(CERTNameConstraint, l)); -} - -CERTNameConstraint * -cert_get_prev_name_constraint(CERTNameConstraint *current) -{ - PRCList *prev; - prev = current->l.prev; - return (CERTNameConstraint *) (((char *) prev) - offsetof(CERTNameConstraint, l)); -} - -SECItem * -cert_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PRArenaPool *arena) -{ - - - PORT_Assert(arena); - if (arena == NULL) { - goto loser; - } - if (dest == NULL) { - dest = (SECItem *) PORT_ArenaZAlloc(arena, sizeof(SECItem)); - } - switch (genName->type) { - case certURI: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_URITemplate); - break; - case certRFC822Name: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_RFC822NameTemplate); - break; - case certDNSName: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_DNSNameTemplate); - break; - case certIPAddress: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_IPAddressTemplate); - break; - case certOtherName: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERTOtherNameTemplate); - break; - case certRegisterID: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_RegisteredIDTemplate); - break; - case certEDIPartyName: - /* for this type, we expect the value is already encoded */ - dest = SEC_ASN1EncodeItem (arena, dest, genName, - CERT_EDIPartyNameTemplate); - break; - case certX400Address: - /* for this type, we expect the value is already encoded */ - dest = SEC_ASN1EncodeItem (arena, dest, genName, - CERT_X400AddressTemplate); - break; - case certDirectoryName: - if (genName->derDirectoryName.data == NULL) { - /* The field hasn't been encoded yet. */ - SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName), - &(genName->name.directoryName), - CERT_NameTemplate); - } - if (genName->derDirectoryName.data == NULL) { - goto loser; - } - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_DirectoryNameTemplate); - break; - } - if (!dest) { - goto loser; - } - return dest; -loser: - return NULL; -} - - - -SECItem ** -cert_EncodeGeneralNames(PRArenaPool *arena, CERTGeneralName *names) -{ - CERTGeneralName *current_name; - SECItem **items = NULL; - int count = 0; - int i; - PRCList *head; - - PORT_Assert(arena); - current_name = names; - if (names != NULL) { - count = 1; - } - head = &(names->l); - while (current_name->l.next != head) { - current_name = cert_get_next_general_name(current_name); - ++count; - } - current_name = cert_get_next_general_name(current_name); - items = (SECItem **) PORT_ArenaAlloc(arena, sizeof(SECItem *) * (count + 1)); - - if (items == NULL) { - goto loser; - } - for (i = 0; i < count; i++) { - items[i] = cert_EncodeGeneralName(current_name, (SECItem *) NULL, arena); - if (items[i] == NULL) { - goto loser; - } - current_name = cert_get_next_general_name(current_name); - } - items[i] = NULL; - return items; -loser: - return NULL; -} - -CERTGeneralName * -cert_DecodeGeneralName(PRArenaPool *arena, - SECItem *encodedName, - CERTGeneralName *genName) -{ - CERTGeneralNameType genNameType; - SECStatus rv = SECSuccess; - - PORT_Assert(arena); - if (genName == NULL) { - genName = (CERTGeneralName *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - } - genNameType = (CERTGeneralNameType)((*(encodedName->data) & 0x0f) + 1); - switch (genNameType) { - case certURI: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_URITemplate, encodedName); - break; - case certRFC822Name: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_RFC822NameTemplate, encodedName); - break; - case certDNSName: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_DNSNameTemplate, encodedName); - break; - case certIPAddress: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_IPAddressTemplate, encodedName); - break; - case certOtherName: - rv = SEC_ASN1DecodeItem(arena, genName, CERTOtherNameTemplate, encodedName); - break; - case certRegisterID: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_RegisteredIDTemplate, encodedName); - break; - case certEDIPartyName: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_EDIPartyNameTemplate, encodedName); - break; - case certX400Address: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_X400AddressTemplate, encodedName); - break; - case certDirectoryName: - rv = SEC_ASN1DecodeItem - (arena, genName, CERT_DirectoryNameTemplate, encodedName); - if (rv != SECSuccess) { - goto loser; - } - rv = SEC_ASN1DecodeItem - (arena, &(genName->name.directoryName), CERT_NameTemplate, - &(genName->derDirectoryName)); - break; - } - - if (rv != SECSuccess) { - goto loser; - } - genName->type = genNameType; - genName->l.next = (PRCList *) ((char *) genName) + offsetof(CERTGeneralName, l); - genName->l.prev = genName->l.next; - return genName; -loser: - return NULL; -} - -CERTGeneralName * -cert_DecodeGeneralNames (PRArenaPool *arena, - SECItem **encodedGenName) -{ - PRCList *head = NULL; - PRCList *tail = NULL; - CERTGeneralName *currentName = NULL; - - PORT_Assert(arena); - if (!encodedGenName) { - goto loser; - } - while (*encodedGenName != NULL) { - currentName = cert_DecodeGeneralName(arena, *encodedGenName, NULL); - if (currentName == NULL) { - goto loser; - } - if (head == NULL) { - head = &(currentName->l); - tail = head; - } - currentName->l.next = head; - currentName->l.prev = tail; - tail = &(currentName->l); - (cert_get_prev_general_name(currentName))->l.next = tail; - encodedGenName++; - } - (cert_get_next_general_name(currentName))->l.prev = tail; - return cert_get_next_general_name(currentName); -loser: - return NULL; -} - -void -CERT_DestroyGeneralName(CERTGeneralName *name) -{ - cert_DestroyGeneralNames(name); -} - -SECStatus -cert_DestroyGeneralNames(CERTGeneralName *name) -{ - CERTGeneralName *first; - CERTGeneralName *next = NULL; - - - first = name; - do { - next = cert_get_next_general_name(name); - PORT_Free(name); - name = next; - } while (name != first); - return SECSuccess; -} - -SECItem * -cert_EncodeNameConstraint(CERTNameConstraint *constraint, - SECItem *dest, - PRArenaPool *arena) -{ - PORT_Assert(arena); - if (dest == NULL) { - dest = (SECItem *) PORT_ArenaZAlloc(arena, sizeof(SECItem)); - if (dest == NULL) { - return NULL; - } - } - cert_EncodeGeneralName(&(constraint->name), &(constraint->DERName), - arena); - - dest = SEC_ASN1EncodeItem (arena, dest, constraint, - CERTNameConstraintTemplate); - return dest; -} - -SECStatus -cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints, - PRArenaPool *arena, - SECItem ***dest, - PRBool permited) -{ - CERTNameConstraint *current_constraint = constraints; - SECItem **items = NULL; - int count = 0; - int i; - PRCList *head; - - PORT_Assert(arena); - if (constraints != NULL) { - count = 1; - } - head = (PRCList *) (((char *) constraints) + offsetof(CERTNameConstraint, l)); - while (current_constraint->l.next != head) { - current_constraint = cert_get_next_name_constraint(current_constraint); - ++count; - } - current_constraint = cert_get_next_name_constraint(current_constraint); - items = (SECItem **) PORT_ArenaZAlloc(arena, sizeof(SECItem *) * (count + 1)); - - if (items == NULL) { - goto loser; - } - for (i = 0; i < count; i++) { - items[i] = cert_EncodeNameConstraint(current_constraint, - (SECItem *) NULL, arena); - if (items[i] == NULL) { - goto loser; - } - current_constraint = cert_get_next_name_constraint(current_constraint); - } - *dest = items; - if (*dest == NULL) { - goto loser; - } - return SECSuccess; -loser: - return SECFailure; -} - -SECStatus -cert_EncodeNameConstraints(CERTNameConstraints *constraints, - PRArenaPool *arena, - SECItem *dest) -{ - SECStatus rv = SECSuccess; - - PORT_Assert(arena); - if (constraints->permited != NULL) { - rv = cert_EncodeNameConstraintSubTree(constraints->permited, arena, - &constraints->DERPermited, PR_TRUE); - if (rv == SECFailure) { - goto loser; - } - } - if (constraints->excluded != NULL) { - rv = cert_EncodeNameConstraintSubTree(constraints->excluded, arena, - &constraints->DERExcluded, PR_FALSE); - if (rv == SECFailure) { - goto loser; - } - } - dest = SEC_ASN1EncodeItem(arena, dest, constraints, - CERTNameConstraintsTemplate); - if (dest == NULL) { - goto loser; - } - return SECSuccess; -loser: - return SECFailure; -} - - -CERTNameConstraint * -cert_DecodeNameConstraint(PRArenaPool *arena, - SECItem *encodedConstraint) -{ - CERTNameConstraint *constraint; - SECStatus rv = SECSuccess; - CERTGeneralName *temp; - - - - PORT_Assert(arena); - constraint = (CERTNameConstraint *) PORT_ArenaZAlloc(arena, sizeof(CERTNameConstraint)); - rv = SEC_ASN1DecodeItem(arena, constraint, CERTNameConstraintTemplate, encodedConstraint); - if (rv != SECSuccess) { - goto loser; - } - temp = cert_DecodeGeneralName(arena, &(constraint->DERName), &(constraint->name)); - if (temp != &(constraint->name)) { - goto loser; - } - - /* ### sjlee: since the name constraint contains only one - * CERTGeneralName, the list within CERTGeneralName shouldn't - * point anywhere else. Otherwise, bad things will happen. - */ - constraint->name.l.prev = constraint->name.l.next = &(constraint->name.l); - return constraint; -loser: - return NULL; -} - - -CERTNameConstraint * -cert_DecodeNameConstraintSubTree(PRArenaPool *arena, - SECItem **subTree, - PRBool permited) -{ - CERTNameConstraint *current = NULL; - CERTNameConstraint *first = NULL; - CERTNameConstraint *last = NULL; - CERTNameConstraint *next = NULL; - int i = 0; - - while (subTree[i] != NULL) { - current = cert_DecodeNameConstraint(arena, subTree[i]); - if (current == NULL) { - goto loser; - } - if (last == NULL) { - first = last = current; - } - current->l.prev = &(last->l); - current->l.next = last->l.next; - last->l.next = &(current->l); - i++; - } - first->l.prev = &(current->l); - return first; -loser: - if (first) { - current = first; - do { - next = cert_get_next_name_constraint(current); - PORT_Free(current); - current = next; - }while (current != first); - } - return NULL; -} - -CERTNameConstraints * -cert_DecodeNameConstraints(PRArenaPool *arena, - SECItem *encodedConstraints) -{ - CERTNameConstraints *constraints; - SECStatus rv; - - PORT_Assert(arena); - PORT_Assert(encodedConstraints); - constraints = (CERTNameConstraints *) PORT_ArenaZAlloc(arena, - sizeof(CERTNameConstraints)); - if (constraints == NULL) { - goto loser; - } - rv = SEC_ASN1DecodeItem(arena, constraints, CERTNameConstraintsTemplate, - encodedConstraints); - if (rv != SECSuccess) { - goto loser; - } - if (constraints->DERPermited != NULL && constraints->DERPermited[0] != NULL) { - constraints->permited = cert_DecodeNameConstraintSubTree(arena, - constraints->DERPermited, - PR_TRUE); - if (constraints->permited == NULL) { - goto loser; - } - } - if (constraints->DERExcluded != NULL && constraints->DERExcluded[0] != NULL) { - constraints->excluded = cert_DecodeNameConstraintSubTree(arena, - constraints->DERExcluded, - PR_FALSE); - if (constraints->excluded == NULL) { - goto loser; - } - } - return constraints; -loser: - return NULL; -} - - -SECStatus -CERT_CopyGeneralName(PRArenaPool *arena, - CERTGeneralName *dest, - CERTGeneralName *src) -{ - SECStatus rv; - CERTGeneralName *destHead = dest; - CERTGeneralName *srcHead = src; - CERTGeneralName *temp; - - PORT_Assert(dest != NULL); - dest->type = src->type; - do { - switch (src->type) { - case certDirectoryName: { - rv = SECITEM_CopyItem(arena, &dest->derDirectoryName, &src->derDirectoryName); - if (rv != SECSuccess) { - return rv; - } - rv = CERT_CopyName(arena, &dest->name.directoryName, &src->name.directoryName); - break; - } - case certOtherName: { - rv = SECITEM_CopyItem(arena, &dest->name.OthName.name, &src->name.OthName.name); - if (rv != SECSuccess) { - return rv; - } - rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid, &src->name.OthName.oid); - break; - } - default: { - rv = SECITEM_CopyItem(arena, &dest->name.other, &src->name.other); - } - } - src = cert_get_next_general_name(src); - /* if there is only one general name, we shouldn't do this */ - if (src != srcHead) { - if (dest->l.next == &destHead->l) { - if (arena) { - temp = (CERTGeneralName *) - PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - } else { - temp = (CERTGeneralName *) - PORT_ZAlloc(sizeof(CERTGeneralName)); - } - temp->l.next = &destHead->l; - temp->l.prev = &dest->l; - destHead->l.prev = &temp->l; - dest->l.next = &temp->l; - dest = temp; - } else { - dest = cert_get_next_general_name(dest); - } - } - } while (src != srcHead && rv == SECSuccess); - return rv; -} - - -CERTGeneralNameList * -CERT_DupGeneralNameList(CERTGeneralNameList *list) -{ - if (list != NULL) { - PR_Lock(list->lock); - list->refCount++; - PR_Unlock(list->lock); - } - return list; -} - -CERTNameConstraint * -CERT_CopyNameConstraint(PRArenaPool *arena, - CERTNameConstraint *dest, - CERTNameConstraint *src) -{ - SECStatus rv; - - if (dest == NULL) { - dest = (CERTNameConstraint *) PORT_ArenaZAlloc(arena, sizeof(CERTNameConstraint)); - /* mark that it is not linked */ - dest->name.l.prev = dest->name.l.next = &(dest->name.l); - } - rv = CERT_CopyGeneralName(arena, &dest->name, &src->name); - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName); - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &dest->min, &src->min); - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &dest->max, &src->max); - if (rv != SECSuccess) { - goto loser; - } - dest->l.prev = dest->l.next = &dest->l; - return dest; -loser: - return NULL; -} - - -CERTGeneralName * -cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2) -{ - PRCList *begin1; - PRCList *begin2; - PRCList *end1; - PRCList *end2; - - if (list1 == NULL){ - return list2; - } else if (list2 == NULL) { - return list1; - } else { - begin1 = &list1->l; - begin2 = &list2->l; - end1 = list1->l.prev; - end2 = list2->l.prev; - end1->next = begin2; - end2->next = begin1; - begin1->prev = end2; - begin2->prev = end1; - return list1; - } -} - - -CERTNameConstraint * -cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2) -{ - PRCList *begin1; - PRCList *begin2; - PRCList *end1; - PRCList *end2; - - if (list1 == NULL){ - return list2; - } else if (list2 == NULL) { - return list1; - } else { - begin1 = &list1->l; - begin2 = &list2->l; - end1 = list1->l.prev; - end2 = list2->l.prev; - end1->next = begin2; - end2->next = begin1; - begin1->prev = end2; - begin2->prev = end1; - return list1; - } -} - - -CERTNameConstraint * -CERT_AddNameConstraint(CERTNameConstraint *list, - CERTNameConstraint *constraint) -{ - PORT_Assert(constraint != NULL); - constraint->l.next = constraint->l.prev = &constraint->l; - list = cert_CombineConstraintsLists(list, constraint); - return list; -} - - -SECStatus -CERT_GetNameConstriantByType (CERTNameConstraint *constraints, - CERTGeneralNameType type, - CERTNameConstraint **returnList, - PRArenaPool *arena) -{ - CERTNameConstraint *current; - CERTNameConstraint *temp; - - *returnList = NULL; - if (!constraints) - return SECSuccess; - current = constraints; - - do { - if (current->name.type == type || - (type == certDirectoryName && current->name.type == certRFC822Name)) { - temp = NULL; - temp = CERT_CopyNameConstraint(arena, temp, current); - if (temp == NULL) { - goto loser; - } - *returnList = CERT_AddNameConstraint(*returnList, temp); - } - current = cert_get_next_name_constraint(current); - } while (current != constraints); - return SECSuccess; -loser: - return SECFailure; -} - - -void * -CERT_GetGeneralNameByType (CERTGeneralName *genNames, - CERTGeneralNameType type, PRBool derFormat) -{ - CERTGeneralName *current; - - if (!genNames) - return (NULL); - current = genNames; - - do { - if (current->type == type) { - switch (type) { - case certDNSName: - case certEDIPartyName: - case certIPAddress: - case certRegisterID: - case certRFC822Name: - case certX400Address: - case certURI: { - return &(current->name.other); - } - case certOtherName: { - return &(current->name.OthName); - break; - } - case certDirectoryName: { - if (derFormat) { - return &(current->derDirectoryName); - } else{ - return &(current->name.directoryName); - } - break; - } - } - } - current = cert_get_next_general_name(current); - } while (current != genNames); - return (NULL); -} - -int -CERT_GetNamesLength(CERTGeneralName *names) -{ - int length = 0; - CERTGeneralName *first; - - first = names; - if (names != NULL) { - do { - length++; - names = cert_get_next_general_name(names); - } while (names != first); - } - return length; -} - -CERTGeneralName * -CERT_GetCertificateNames(CERTCertificate *cert, PRArenaPool *arena) -{ - CERTGeneralName *DN; - CERTGeneralName *altName; - SECItem altNameExtension; - SECStatus rv; - - - DN = (CERTGeneralName *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - if (DN == NULL) { - goto loser; - } - rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject); - DN->type = certDirectoryName; - DN->l.next = DN->l.prev = &DN->l; - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject); - if (rv != SECSuccess) { - goto loser; - } - rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, - &altNameExtension); - if (rv != SECSuccess) { - return DN; - } - altName = CERT_DecodeAltNameExtension(arena, &altNameExtension); - if (altName == NULL) { - goto loser; - } - DN = cert_CombineNamesLists(DN, altName); - return DN; -loser: - return NULL; -} - -static SECStatus -compareNameToConstraint(char *name, char *constraint, PRBool substring) -{ - SECStatus rv; - - if (*constraint == '\0' && *name == '\0') { - return SECSuccess; - } - if (*constraint == '*') { - return compareNameToConstraint(name, constraint + 1, PR_TRUE); - } - if (substring) { - if (*constraint == '\0') { - return SECSuccess; - } - while (*name != *constraint) { - if (*name == '\0') { - return SECFailure; - } - name++; - } - rv = compareNameToConstraint(name + 1, constraint + 1, PR_FALSE); - if (rv == SECSuccess) { - return rv; - } - name++; - } else { - if (*name == *constraint) { - name++; - constraint++; - } else { - return SECFailure; - } - } - return compareNameToConstraint(name, constraint, substring); -} - -SECStatus -cert_CompareNameWithConstraints(CERTGeneralName *name, - CERTNameConstraint *constraints, - PRBool excluded) -{ - SECStatus rv = SECSuccess; - char *nameString = NULL; - char *constraintString = NULL; - int start; - int end; - int tag; - CERTRDN **nameRDNS, *nameRDN; - CERTRDN **constraintRDNS, *constraintRDN; - CERTAVA **nameAVAS, *nameAVA; - CERTAVA **constraintAVAS, *constraintAVA; - CERTNameConstraint *current; - SECItem *avaValue; - CERTName constraintName; - CERTName certName; - SECComparison status = SECEqual; - PRArenaPool *certNameArena; - PRArenaPool *constraintNameArena; - - certName.arena = NULL; - certName.rdns = NULL; - constraintName.arena = NULL; - constraintName.rdns = NULL; - if (constraints != NULL) { - current = constraints; - if (name->type == certDirectoryName) { - certNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(certNameArena, &certName, &name->name.directoryName); - nameRDNS = certName.rdns; - for (;;) { - nameRDN = *nameRDNS++; - nameAVAS = nameRDN->avas; - for(;;) { - nameAVA = *nameAVAS++; - tag = CERT_GetAVATag(nameAVA); - if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS || - tag == SEC_OID_RFC1274_MAIL) { - avaValue = CERT_DecodeAVAValue(&nameAVA->value); - nameString = (char*)PORT_ZAlloc(avaValue->len + 1); - nameString = PORT_Strncpy(nameString, (char *) avaValue->data, avaValue->len); - start = 0; - while(nameString[start] != '@' && nameString[start + 1] != '\0') { - start++; - } - start++; - do{ - if (current->name.type == certRFC822Name) { - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, - PR_FALSE); - - if (constraintString != NULL) { - PORT_Free(constraintString); - constraintString = NULL; - } - if (nameString != NULL) { - PORT_Free(nameString); - nameString = NULL; - } - if (rv == SECSuccess && excluded == PR_TRUE) { - goto found; - } - if (rv == SECSuccess && excluded == PR_FALSE) { - break; - } - } - current = cert_get_next_name_constraint(current); - } while (current != constraints); - } - if (rv != SECSuccess && excluded == PR_FALSE) { - goto loser; - } - if (*nameAVAS == NULL) { - break; - } - } - if (*nameRDNS == NULL) { - break; - } - } - } - current = constraints; - do { - switch (name->type) { - case certDNSName: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certRFC822Name: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - start = 0; - while(nameString[start] != '@' && nameString[start + 1] != '\0') { - start++; - } - start++; - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certURI: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - while(PORT_Strncmp(nameString + start, "://", 3) != 0 && - nameString[start + 3] != '\0') { - start++; - } - start +=3; - end = 0; - while(nameString[start + end] != '/' && - nameString[start + end] != '\0') { - end++; - } - nameString[start + end] = '\0'; - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certDirectoryName: - if (current->name.type == certDirectoryName) { - constraintNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(constraintNameArena, &constraintName, ¤t->name.name.directoryName); - constraintRDNS = constraintName.rdns; - for (;;) { - constraintRDN = *constraintRDNS++; - constraintAVAS = constraintRDN->avas; - for(;;) { - constraintAVA = *constraintAVAS++; - certNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(certNameArena, &certName, &name->name.directoryName); - nameRDNS = certName.rdns; - for (;;) { - nameRDN = *nameRDNS++; - nameAVAS = nameRDN->avas++; - for(;;) { - nameAVA = *nameAVAS++; - status = CERT_CompareAVA(constraintAVA, nameAVA); - if (status == SECEqual || *nameAVAS == NULL) { - break; - } - } - if (status == SECEqual || *nameRDNS == NULL) { - break; - } - } - if (status != SECEqual || *constraintAVAS == NULL) { - break; - } - } - if (status != SECEqual || *constraintRDNS == NULL) { - break; - } - } - if (status == SECEqual) { - if (excluded == PR_FALSE) { - goto found; - } else { - goto loser; - } - } - break; - } else if (current->name.type == certRFC822Name) { - current = cert_get_next_name_constraint(current); - continue; - } - default: - /* other types are not supported */ - if (excluded) { - goto found; - } else { - goto loser; - } - } - if (rv == SECSuccess && status == SECEqual) { - goto found; - } - current = cert_get_next_name_constraint(current); - } while (current !=constraints); - } else { - goto found; - } -loser: - if (certName.arena) { - CERT_DestroyName(&certName); - } - if (constraintName.arena) { - CERT_DestroyName(&constraintName); - } - return SECFailure; -found: - if (certName.arena) { - CERT_DestroyName(&certName); - } - if (constraintName.arena) { - CERT_DestroyName(&constraintName); - } - return SECSuccess; -} - - -CERTCertificate * -CERT_CompareNameSpace(CERTCertificate *cert, - CERTGeneralName *namesList, - SECItem *namesListIndex, - PRArenaPool *arena, - CERTCertDBHandle *handle) -{ - SECStatus rv; - SECItem constraintsExtension; - CERTNameConstraints *constraints; - CERTGeneralName *currentName; - int count = 0; - CERTNameConstraint *matchingConstraints; - CERTCertificate *badCert = NULL; - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, &constraintsExtension); - if (rv != SECSuccess) { - return NULL; - } - constraints = cert_DecodeNameConstraints(arena, &constraintsExtension); - currentName = namesList; - if (constraints == NULL) { - goto loser; - } - do { - if (constraints->excluded != NULL) { - rv = CERT_GetNameConstriantByType(constraints->excluded, currentName->type, - &matchingConstraints, arena); - if (rv != SECSuccess) { - goto loser; - } - if (matchingConstraints != NULL) { - rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, - PR_TRUE); - if (rv != SECFailure) { - goto loser; - } - } - } - if (constraints->permited != NULL) { - rv = CERT_GetNameConstriantByType(constraints->permited, currentName->type, - &matchingConstraints, arena); - if (rv != SECSuccess) { - goto loser; - } - if (matchingConstraints != NULL) { - rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, - PR_FALSE); - if (rv != SECSuccess) { - goto loser; - } - } else { - goto loser; - } - } - currentName = cert_get_next_general_name(currentName); - count ++; - } while (currentName != namesList); - return NULL; -loser: - badCert = CERT_FindCertByName (handle, &namesListIndex[count]); - return badCert; -} - - - - - -char * -CERT_GetNickName(CERTCertificate *cert, - CERTCertDBHandle *handle, - PRArenaPool *nicknameArena) -{ - CERTGeneralName *current; - CERTGeneralName *names; - SECItem altNameExtension; - char *nickname = NULL; - char *returnName = NULL; - char *tempname = NULL; - SECItem *nick; - SECStatus rv; - PRArenaPool *arena = NULL; - int count; - int length; - - - - if (handle == NULL) { - handle = CERT_GetDefaultCertDB(); - } - rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, - &altNameExtension); - if (rv != SECSuccess) { - goto loser; - } - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto loser; - } - names = CERT_DecodeAltNameExtension(arena, &altNameExtension); - if (names == NULL) { - goto loser; - } - current = names; - do { - if (current->type == certOtherName && - SECOID_FindOIDTag(¤t->name.OthName.oid) == SEC_OID_NETSCAPE_NICKNAME) { - rv = SEC_ASN1DecodeItem(arena, nick, SEC_IA5StringTemplate, - ¤t->name.OthName.name); - if (rv != SECSuccess) { - goto loser; - } - nickname = (char*)PORT_ZAlloc(nick->len + 1); - if (nickname == NULL) { - goto loser; - } - nickname = PORT_Strncpy(nickname, (char *) nick->data, nick->len); - length = nick->len; - count = 1; - tempname = nickname; - while (CERT_FindCertByNickname(handle, nickname) != NULL) { - nickname = PR_smprintf("%s #%d", tempname, count); - count++; - } - goto done; - } - current = cert_get_next_general_name(current); - } while (current != names); -loser: - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - if (nickname != NULL) { - PORT_Free(nickname); - } - return NULL; -done: - if (nicknameArena != NULL) { - returnName = PORT_ArenaStrdup(cert->arena, nickname); - } else { - returnName = PORT_Strdup(nickname); - } - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - PORT_Free(nickname); - return returnName; -} - - -SECStatus -CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b) -{ - CERTGeneralName *currentA; - CERTGeneralName *currentB; - PRBool found; - - currentA = a; - currentB = b; - if (a != NULL) { - do { - if (currentB == NULL) { - return SECFailure; - } - currentB = cert_get_next_general_name(currentB); - currentA = cert_get_next_general_name(currentA); - } while (currentA != a); - } - if (currentB != b) { - return SECFailure; - } - currentA = a; - do { - currentB = b; - found = PR_FALSE; - do { - if (currentB->type == currentA->type) { - switch (currentB->type) { - case certDNSName: - case certEDIPartyName: - case certIPAddress: - case certRegisterID: - case certRFC822Name: - case certX400Address: - case certURI: - if (SECITEM_CompareItem(¤tA->name.other, - ¤tB->name.other) - == SECEqual) { - found = PR_TRUE; - } - break; - case certOtherName: - if (SECITEM_CompareItem(¤tA->name.OthName.oid, - ¤tB->name.OthName.oid) - == SECEqual && - SECITEM_CompareItem(¤tA->name.OthName.name, - ¤tB->name.OthName.name) - == SECEqual) { - found = PR_TRUE; - } - break; - case certDirectoryName: - if (CERT_CompareName(¤tA->name.directoryName, - ¤tB->name.directoryName) - == SECEqual) { - found = PR_TRUE; - } - } - - } - currentB = cert_get_next_general_name(currentB); - } while (currentB != b && found != PR_TRUE); - if (found != PR_TRUE) { - return SECFailure; - } - currentA = cert_get_next_general_name(currentA); - } while (currentA != a); - return SECSuccess; -} - -SECStatus -CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b) -{ - SECStatus rv; - - if (a == b) { - return SECSuccess; - } - if (a != NULL && b != NULL) { - PR_Lock(a->lock); - PR_Lock(b->lock); - rv = CERT_CompareGeneralName(a->name, b->name); - PR_Unlock(a->lock); - PR_Unlock(b->lock); - } else { - rv = SECFailure; - } - return rv; -} - -void * -CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, - CERTGeneralNameType type, - PRArenaPool *arena) -{ - CERTName *name = NULL; - SECItem *item = NULL; - OtherName *other = NULL; - OtherName *tmpOther = NULL; - void *data; - - PR_Lock(list->lock); - data = CERT_GetGeneralNameByType(list->name, type, PR_FALSE); - if (data != NULL) { - switch (type) { - case certDNSName: - case certEDIPartyName: - case certIPAddress: - case certRegisterID: - case certRFC822Name: - case certX400Address: - case certURI: - if (arena != NULL) { - item = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); - if (item != NULL) { - SECITEM_CopyItem(arena, item, (SECItem *) data); - } - } else { - item = SECITEM_DupItem((SECItem *) data); - } - PR_Unlock(list->lock); - return item; - case certOtherName: - other = (OtherName *) data; - if (arena != NULL) { - tmpOther = (OtherName *)PORT_ArenaAlloc(arena, - sizeof(OtherName)); - } else { - tmpOther = (OtherName *) PORT_Alloc(sizeof(OtherName)); - } - if (tmpOther != NULL) { - SECITEM_CopyItem(arena, &tmpOther->oid, &other->oid); - SECITEM_CopyItem(arena, &tmpOther->name, &other->name); - } - PR_Unlock(list->lock); - return tmpOther; - case certDirectoryName: - if (arena == NULL) { - PR_Unlock(list->lock); - return NULL; - } else { - name = (CERTName *) PORT_ArenaZAlloc(list->arena, - sizeof(CERTName)); - if (name != NULL) { - CERT_CopyName(arena, name, (CERTName *) data); - } - PR_Unlock(list->lock); - return name; - } - } - } - PR_Unlock(list->lock); - return NULL; -} - -void -CERT_AddGeneralNameToList(CERTGeneralNameList *list, - CERTGeneralNameType type, - void *data, SECItem *oid) -{ - CERTGeneralName *name; - - if (list != NULL && data != NULL) { - PR_Lock(list->lock); - name = (CERTGeneralName *) - PORT_ArenaZAlloc(list->arena, sizeof(CERTGeneralName)); - name->type = type; - switch (type) { - case certDNSName: - case certEDIPartyName: - case certIPAddress: - case certRegisterID: - case certRFC822Name: - case certX400Address: - case certURI: - SECITEM_CopyItem(list->arena, &name->name.other, (SECItem *)data); - break; - case certOtherName: - SECITEM_CopyItem(list->arena, &name->name.OthName.name, - (SECItem *) data); - SECITEM_CopyItem(list->arena, &name->name.OthName.oid, - oid); - break; - case certDirectoryName: - CERT_CopyName(list->arena, &name->name.directoryName, - (CERTName *) data); - break; - } - name->l.prev = name->l.next = &name->l; - list->name = cert_CombineNamesLists(list->name, name); - list->len++; - PR_Unlock(list->lock); - } - return; -} diff --git a/security/nss/lib/certdb/genname.h b/security/nss/lib/certdb/genname.h deleted file mode 100644 index 0e33b8eaf..000000000 --- a/security/nss/lib/certdb/genname.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#ifndef _GENAME_H_ -#define _GENAME_H_ - -#include "plarena.h" -#include "seccomon.h" -#include "secoidt.h" -#include "secasn1.h" -#include "secder.h" -#include "certt.h" - -/************************************************************************/ -SEC_BEGIN_PROTOS - -extern const SEC_ASN1Template CERT_GeneralNamesTemplate[]; - -extern CERTGeneralName * -cert_get_next_general_name(CERTGeneralName *current); - -extern CERTGeneralName * -cert_get_prev_general_name(CERTGeneralName *current); - -extern SECItem * -cert_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, - PRArenaPool *arena); - -extern SECItem ** -cert_EncodeGeneralNames(PRArenaPool *arena, CERTGeneralName *names); - -extern CERTGeneralName * -cert_DecodeGeneralName(PRArenaPool *arena, SECItem *encodedName, - CERTGeneralName *genName); - -extern CERTGeneralName * -cert_DecodeGeneralNames(PRArenaPool *arena, SECItem **encodedGenName); - -extern SECStatus -cert_DestroyGeneralNames(CERTGeneralName *name); - -extern SECStatus -cert_EncodeNameConstraints(CERTNameConstraints *constraints, PRArenaPool *arena, - SECItem *dest); - -extern CERTNameConstraints * -cert_DecodeNameConstraints(PRArenaPool *arena, SECItem *encodedConstraints); - -extern CERTGeneralName * -cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2); - -extern CERTNameConstraint * -cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2); - -SECStatus -CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b); - -SECStatus -CERT_CopyGeneralName(PRArenaPool *arena, - CERTGeneralName *dest, - CERTGeneralName *src); - -/* General Name Lists are a thread safe, reference counting layer to - * general names */ - -void -CERT_DestroyGeneralNameList(CERTGeneralNameList *list); - -CERTGeneralNameList * -CERT_CreateGeneralNameList(CERTGeneralName *name); - -SECStatus -CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b); - -void * -CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, - CERTGeneralNameType type, - PRArenaPool *arena); - -void -CERT_AddGeneralNameToList(CERTGeneralNameList *list, - CERTGeneralNameType type, - void *data, SECItem *oid); - - -CERTGeneralNameList * -CERT_DupGeneralNameList(CERTGeneralNameList *list); - - -int -CERT_GetNamesLength(CERTGeneralName *names); -/************************************************************************/ -SEC_END_PROTOS - -#endif diff --git a/security/nss/lib/certdb/manifest.mn b/security/nss/lib/certdb/manifest.mn deleted file mode 100644 index 168cd2b6a..000000000 --- a/security/nss/lib/certdb/manifest.mn +++ /dev/null @@ -1,76 +0,0 @@ -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# -CORE_DEPTH = ../../.. - -EXPORTS = \ - cert.h \ - certt.h \ - certdb.h \ - cdbhdl.h \ - $(NULL) - -PRIVATE_EXPORTS = \ - genname.h \ - xconst.h \ - certxutl.h \ - $(NULL) - -MODULE = security - -ifdef MOZILLA_SECURITY_BUILD -CERTINIT=nscertinit.c -DEFINES += -DUSE_NS_ROOTS -else -CERTINIT=certinit.c -endif - -CSRCS = \ - alg1485.c \ - certdb.c \ - certv3.c \ - $(CERTINIT) \ - certxutl.c \ - crl.c \ - genname.c \ - pcertdb.c \ - polcyxtn.c \ - secname.c \ - xauthkid.c \ - xbsconst.c \ - xconst.c \ - $(NULL) - -REQUIRES = security dbm - -LIBRARY_NAME = certdb - diff --git a/security/nss/lib/certdb/pcertdb.c b/security/nss/lib/certdb/pcertdb.c deleted file mode 100644 index 9edd232b0..000000000 --- a/security/nss/lib/certdb/pcertdb.c +++ /dev/null @@ -1,7340 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Permanent Certificate database handling code - * - * $Id$ - */ -#include "prtime.h" - -#include "cert.h" -#include "mcom_db.h" -#include "certdb.h" -#include "secitem.h" -#include "secder.h" - -/* Call to PK11_FreeSlot below */ - -#include "secasn1.h" -#include "secerr.h" -#include "prlock.h" -#include "prmon.h" -#include "nsslocks.h" -#include "base64.h" -#include "sechash.h" -#include "plhash.h" - -#include "cdbhdl.h" - -/* - * the following functions are wrappers for the db library that implement - * a global lock to make the database thread safe. - */ -static PRLock *dbLock = NULL; - -void -certdb_InitDBLock(void) -{ - if (dbLock == NULL) { - nss_InitLock(&dbLock); - PORT_Assert(dbLock != NULL); - } - - return; -} - -static int -certdb_Get(DB *db, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PR_Lock(dbLock); - - ret = (* db->get)(db, key, data, flags); - - prstat = PR_Unlock(dbLock); - - return(ret); -} - -static int -certdb_Put(DB *db, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PR_Lock(dbLock); - - ret = (* db->put)(db, key, data, flags); - - prstat = PR_Unlock(dbLock); - - return(ret); -} - -static int -certdb_Sync(DB *db, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PR_Lock(dbLock); - - ret = (* db->sync)(db, flags); - - prstat = PR_Unlock(dbLock); - - return(ret); -} - -static int -certdb_Del(DB *db, DBT *key, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PR_Lock(dbLock); - - ret = (* db->del)(db, key, flags); - - prstat = PR_Unlock(dbLock); - - return(ret); -} - -static int -certdb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PR_Lock(dbLock); - - ret = (* db->seq)(db, key, data, flags); - - prstat = PR_Unlock(dbLock); - - return(ret); -} - -static void -certdb_Close(DB *db) -{ - PRStatus prstat; - - PORT_Assert(dbLock != NULL); - PR_Lock(dbLock); - - (* db->close)(db); - - prstat = PR_Unlock(dbLock); - - return; -} - -/* forward references */ -static void CERT_DestroyCertificateNoLocking(CERTCertificate *cert); -static SECStatus AddCertToSPKDigestTable(CERTCertDBHandle *handle, - CERTCertificate *cert); -static SECStatus RemoveCertFromSPKDigestTable(CERTCertDBHandle *handle, - CERTCertificate *cert); - -static SECStatus -DeleteDBEntry(CERTCertDBHandle *handle, certDBEntryType type, SECItem *dbkey) -{ - DBT key; - int ret; - - /* init the database key */ - key.data = dbkey->data; - key.size = dbkey->len; - - dbkey->data[0] = (unsigned char)type; - - /* delete entry from database */ - ret = certdb_Del(handle->permCertDB, &key, 0 ); - if ( ret != 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - ret = certdb_Sync(handle->permCertDB, 0); - if ( ret ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -ReadDBEntry(CERTCertDBHandle *handle, certDBEntryCommon *entry, - SECItem *dbkey, SECItem *dbentry, PRArenaPool *arena) -{ - DBT data, key; - int ret; - unsigned char *buf; - - /* init the database key */ - key.data = dbkey->data; - key.size = dbkey->len; - - dbkey->data[0] = (unsigned char)entry->type; - - /* read entry from database */ - ret = certdb_Get(handle->permCertDB, &key, &data, 0 ); - if ( ret != 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* validate the entry */ - if ( data.size < SEC_DB_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - buf = (unsigned char *)data.data; - if ( buf[0] != (unsigned char)CERT_DB_FILE_VERSION ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - if ( buf[1] != (unsigned char)entry->type ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy out header information */ - entry->version = (unsigned int)buf[0]; - entry->type = (certDBEntryType)buf[1]; - entry->flags = (unsigned int)buf[2]; - - /* format body of entry for return to caller */ - dbentry->len = data.size - SEC_DB_ENTRY_HEADER_LEN; - if ( dbentry->len ) { - dbentry->data = (unsigned char *)PORT_ArenaAlloc(arena, dbentry->len); - if ( dbentry->data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - PORT_Memcpy(dbentry->data, &buf[SEC_DB_ENTRY_HEADER_LEN], - dbentry->len); - } else { - dbentry->data = NULL; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/** - ** Implement low level database access - **/ -static SECStatus -WriteDBEntry(CERTCertDBHandle *handle, certDBEntryCommon *entry, - SECItem *dbkey, SECItem *dbentry) -{ - int ret; - DBT data, key; - unsigned char *buf; - - data.data = dbentry->data; - data.size = dbentry->len; - - buf = (unsigned char*)data.data; - - buf[0] = (unsigned char)entry->version; - buf[1] = (unsigned char)entry->type; - buf[2] = (unsigned char)entry->flags; - - key.data = dbkey->data; - key.size = dbkey->len; - - dbkey->data[0] = (unsigned char)entry->type; - - /* put the record into the database now */ - ret = certdb_Put(handle->permCertDB, &key, &data, 0); - - if ( ret != 0 ) { - goto loser; - } - - ret = certdb_Sync( handle->permCertDB, 0 ); - - if ( ret ) { - goto loser; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * encode a database cert record - */ -static SECStatus -EncodeDBCertEntry(certDBEntryCert *entry, PRArenaPool *arena, SECItem *dbitem) -{ - unsigned int nnlen; - unsigned char *buf; - char *nn; - char zbuf = 0; - - if ( entry->nickname ) { - nn = entry->nickname; - } else { - nn = &zbuf; - } - nnlen = PORT_Strlen(nn) + 1; - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->derCert.len + nnlen + DB_CERT_ENTRY_HEADER_LEN + - SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->trust.sslFlags >> 8 ) & 0xff; - buf[1] = entry->trust.sslFlags & 0xff; - buf[2] = ( entry->trust.emailFlags >> 8 ) & 0xff; - buf[3] = entry->trust.emailFlags & 0xff; - buf[4] = ( entry->trust.objectSigningFlags >> 8 ) & 0xff; - buf[5] = entry->trust.objectSigningFlags & 0xff; - buf[6] = ( entry->derCert.len >> 8 ) & 0xff; - buf[7] = entry->derCert.len & 0xff; - buf[8] = ( nnlen >> 8 ) & 0xff; - buf[9] = nnlen & 0xff; - - PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN], entry->derCert.data, - entry->derCert.len); - - PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN + entry->derCert.len], - nn, nnlen); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * encode a database key for a cert record - */ -static SECStatus -EncodeDBCertKey(SECItem *certKey, PRArenaPool *arena, SECItem *dbkey) -{ - dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], - certKey->data, certKey->len); - dbkey->data[0] = certDBEntryTypeCert; - - return(SECSuccess); -loser: - return(SECFailure); -} - -static SECStatus -EncodeDBGenericKey(SECItem *certKey, PRArenaPool *arena, SECItem *dbkey, - certDBEntryType entryType) -{ - /* - * we only allow _one_ KRL key! - */ - if (entryType == certDBEntryTypeKeyRevocation) { - dbkey->len = SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - dbkey->data[0] = (unsigned char) entryType; - return(SECSuccess); - } - - - dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], - certKey->data, certKey->len); - dbkey->data[0] = (unsigned char) entryType; - - return(SECSuccess); -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry) -{ - unsigned int nnlen; - int headerlen; - int lenoff; - - /* allow updates of old versions of the database */ - switch ( entry->common.version ) { - case 5: - headerlen = DB_CERT_V5_ENTRY_HEADER_LEN; - lenoff = 3; - break; - case 6: - /* should not get here */ - PORT_Assert(0); - headerlen = DB_CERT_V6_ENTRY_HEADER_LEN; - lenoff = 3; - break; - case 7: - headerlen = DB_CERT_ENTRY_HEADER_LEN; - lenoff = 6; - break; - default: - /* better not get here */ - PORT_Assert(0); - headerlen = DB_CERT_V5_ENTRY_HEADER_LEN; - lenoff = 3; - break; - } - - /* is record long enough for header? */ - if ( dbentry->len < headerlen ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->derCert.len = ( ( dbentry->data[lenoff] << 8 ) | - dbentry->data[lenoff+1] ); - nnlen = ( ( dbentry->data[lenoff+2] << 8 ) | dbentry->data[lenoff+3] ); - if ( ( entry->derCert.len + nnlen + headerlen ) - != dbentry->len) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy the dercert */ - entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->derCert.len); - if ( entry->derCert.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->derCert.data, &dbentry->data[headerlen], - entry->derCert.len); - - /* copy the nickname */ - if ( nnlen > 1 ) { - entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen); - if ( entry->nickname == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->nickname, - &dbentry->data[headerlen + - entry->derCert.len], - nnlen); - } else { - entry->nickname = NULL; - } - - if ( entry->common.version < 7 ) { - /* allow updates of v5 db */ - entry->trust.sslFlags = dbentry->data[0]; - entry->trust.emailFlags = dbentry->data[1]; - entry->trust.objectSigningFlags = dbentry->data[2]; - } else { - entry->trust.sslFlags = ( dbentry->data[0] << 8 ) | dbentry->data[1]; - entry->trust.emailFlags = ( dbentry->data[2] << 8 ) | dbentry->data[3]; - entry->trust.objectSigningFlags = - ( dbentry->data[4] << 8 ) | dbentry->data[5]; - } - - return(SECSuccess); -loser: - return(SECFailure); -} - - -/* - * Create a new certDBEntryCert from existing data - */ -static certDBEntryCert * -NewDBCertEntry(SECItem *derCert, char *nickname, - CERTCertTrust *trust, int flags) -{ - certDBEntryCert *entry; - PRArenaPool *arena = NULL; - int nnlen; - - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); - - if ( !arena ) { - goto loser; - } - - entry = (certDBEntryCert *)PORT_ArenaZAlloc(arena, sizeof(certDBEntryCert)); - - if ( entry == NULL ) { - goto loser; - } - - /* fill in the dbCert */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeCert; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - if ( trust ) { - entry->trust = *trust; - } - - entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, derCert->len); - if ( !entry->derCert.data ) { - goto loser; - } - entry->derCert.len = derCert->len; - PORT_Memcpy(entry->derCert.data, derCert->data, derCert->len); - - nnlen = ( nickname ? strlen(nickname) + 1 : 0 ); - - if ( nnlen ) { - entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( !entry->nickname ) { - goto loser; - } - PORT_Memcpy(entry->nickname, nickname, nnlen); - - } else { - entry->nickname = 0; - } - - return(entry); - -loser: - - /* allocation error, free arena and return */ - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); -} - -/* - * Decode a version 4 DBCert from the byte stream database format - * and construct a current database entry struct - */ -static certDBEntryCert * -DecodeV4DBCertEntry(unsigned char *buf, int len) -{ - certDBEntryCert *entry; - int certlen; - int nnlen; - PRArenaPool *arena; - - /* make sure length is at least long enough for the header */ - if ( len < DBCERT_V4_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(0); - } - - /* get other lengths */ - certlen = buf[3] << 8 | buf[4]; - nnlen = buf[5] << 8 | buf[6]; - - /* make sure DB entry is the right size */ - if ( ( certlen + nnlen + DBCERT_V4_HEADER_LEN ) != len ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(0); - } - - /* allocate arena */ - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); - - if ( !arena ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); - } - - /* allocate structure and members */ - entry = (certDBEntryCert *) PORT_ArenaAlloc(arena, sizeof(certDBEntryCert)); - - if ( !entry ) { - goto loser; - } - - entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen); - if ( !entry->derCert.data ) { - goto loser; - } - entry->derCert.len = certlen; - - if ( nnlen ) { - entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen); - if ( !entry->nickname ) { - goto loser; - } - } else { - entry->nickname = 0; - } - - entry->common.arena = arena; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.type = certDBEntryTypeCert; - entry->common.flags = 0; - entry->trust.sslFlags = buf[0]; - entry->trust.emailFlags = buf[1]; - entry->trust.objectSigningFlags = buf[2]; - - PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen); - PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen); - - return(entry); - -loser: - PORT_FreeArena(arena, PR_FALSE); - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); -} - -/* - * Encode a Certificate database entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBCertEntry(CERTCertDBHandle *handle, certDBEntryCert *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECItem tmpitem; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBCertEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - /* get the database key and format it */ - rv = CERT_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem); - if ( rv == SECFailure ) { - goto loser; - } - - rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); -} - - -/* - * delete a certificate entry - */ -static SECStatus -DeleteDBCertEntry(CERTCertDBHandle *handle, SECItem *certKey) -{ - SECItem dbkey; - PRArenaPool *arena = NULL; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBCertKey(certKey, arena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeCert, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read a certificate entry - */ -static certDBEntryCert * -ReadDBCertEntry(CERTCertDBHandle *handle, SECItem *certKey) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryCert *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeCert; - - rv = EncodeDBCertKey(certKey, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - rv = DecodeDBCertEntry(entry, &dbentry); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * encode a database cert record - */ -static SECStatus -EncodeDBCrlEntry(certDBEntryRevocation *entry, PRArenaPool *arena, SECItem *dbitem) -{ - unsigned int nnlen = 0; - unsigned char *buf; - - if (entry->url) { - nnlen = PORT_Strlen(entry->url) + 1; - } - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->derCrl.len + nnlen - + SEC_DB_ENTRY_HEADER_LEN + DB_CRL_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->derCrl.len >> 8 ) & 0xff; - buf[1] = entry->derCrl.len & 0xff; - buf[2] = ( nnlen >> 8 ) & 0xff; - buf[3] = nnlen & 0xff; - - PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN], entry->derCrl.data, - entry->derCrl.len); - - if (nnlen != 0) { - PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len], - entry->url, nnlen); - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry) -{ - unsigned int nnlen; - - /* is record long enough for header? */ - if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->derCrl.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] ); - if ( ( entry->derCrl.len + nnlen + DB_CRL_ENTRY_HEADER_LEN ) - != dbentry->len) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy the dercert */ - entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->derCrl.len); - if ( entry->derCrl.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->derCrl.data, &dbentry->data[DB_CRL_ENTRY_HEADER_LEN], - entry->derCrl.len); - - /* copy the url */ - entry->url = NULL; - if (nnlen != 0) { - entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen); - if ( entry->url == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->url, - &dbentry->data[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len], - nnlen); - } - - return(SECSuccess); -loser: - return(SECFailure); -} - -/* - * Create a new certDBEntryRevocation from existing data - */ -static certDBEntryRevocation * -NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags) -{ - certDBEntryRevocation *entry; - PRArenaPool *arena = NULL; - int nnlen; - - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); - - if ( !arena ) { - goto loser; - } - - entry = (certDBEntryRevocation*) - PORT_ArenaZAlloc(arena, sizeof(certDBEntryRevocation)); - - if ( entry == NULL ) { - goto loser; - } - - /* fill in the dbRevolcation */ - entry->common.arena = arena; - entry->common.type = crlType; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - - entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(arena, derCrl->len); - if ( !entry->derCrl.data ) { - goto loser; - } - - if (url) { - nnlen = PORT_Strlen(url) + 1; - entry->url = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( !entry->url ) { - goto loser; - } - PORT_Memcpy(entry->url, url, nnlen); - } else { - entry->url = NULL; - } - - - entry->derCrl.len = derCrl->len; - PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len); - - return(entry); - -loser: - - /* allocation error, free arena and return */ - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); -} - - -static SECStatus -WriteDBCrlEntry(CERTCertDBHandle *handle, certDBEntryRevocation *entry ) -{ - SECItem dbkey; - PRArenaPool *tmparena = NULL; - SECItem tmpitem,encodedEntry; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - /* get the database key and format it */ - rv = CERT_KeyFromDERCrl(tmparena, &entry->derCrl, &tmpitem); - if ( rv == SECFailure ) { - goto loser; - } - - rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry); - if ( rv == SECFailure ) { - goto loser; - } - - rv = EncodeDBGenericKey(&tmpitem, tmparena, &dbkey, entry->common.type); - if ( rv == SECFailure ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); -} -/* - * delete a crl entry - */ -static SECStatus -DeleteDBCrlEntry(CERTCertDBHandle *handle, SECItem *crlKey, - certDBEntryType crlType) -{ - SECItem dbkey; - PRArenaPool *arena = NULL; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, crlType, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read a certificate entry - */ -static certDBEntryRevocation * -ReadDBCrlEntry(CERTCertDBHandle *handle, SECItem *certKey, - certDBEntryType crlType) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryRevocation *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryRevocation *) - PORT_ArenaAlloc(arena, sizeof(certDBEntryRevocation)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = crlType; - - rv = EncodeDBGenericKey(certKey, tmparena, &dbkey, crlType); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - rv = DecodeDBCrlEntry(entry, &dbentry); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * destroy a database entry - */ -static void -DestroyDBEntry(certDBEntry *entry) -{ - PRArenaPool *arena = entry->common.arena; - - /* Zero out the entry struct, so that any further attempts to use it - * will cause an exception (e.g. null pointer reference). */ - PORT_Memset(&entry->common, 0, sizeof entry->common); - PORT_FreeArena(arena, PR_FALSE); - - return; -} - -/* - * Encode a database nickname record - */ -static SECStatus -EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena, - SECItem *dbitem) -{ - unsigned char *buf; - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN + - SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->subjectName.len >> 8 ) & 0xff; - buf[1] = entry->subjectName.len & 0xff; - - PORT_Memcpy(&buf[DB_NICKNAME_ENTRY_HEADER_LEN], entry->subjectName.data, - entry->subjectName.len); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Encode a database key for a nickname record - */ -static SECStatus -EncodeDBNicknameKey(char *nickname, PRArenaPool *arena, - SECItem *dbkey) -{ - unsigned int nnlen; - - nnlen = PORT_Strlen(nickname) + 1; /* includes null */ - - /* now get the database key and format it */ - dbkey->len = nnlen + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen); - dbkey->data[0] = certDBEntryTypeNickname; - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry) -{ - /* is record long enough for header? */ - if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - if (( entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN ) != - dbentry->len ){ - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy the certkey */ - entry->subjectName.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->subjectName.len); - if ( entry->subjectName.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->subjectName.data, - &dbentry->data[DB_NICKNAME_ENTRY_HEADER_LEN], - entry->subjectName.len); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new nickname entry - */ -static certDBEntryNickname * -NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntryNickname *entry; - int nnlen; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryNickname)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* init common fields */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeNickname; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - /* copy the nickname */ - nnlen = PORT_Strlen(nickname) + 1; - - entry->nickname = (char*)PORT_ArenaAlloc(arena, nnlen); - if ( entry->nickname == NULL ) { - goto loser; - } - - PORT_Memcpy(entry->nickname, nickname, nnlen); - - rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName); - if ( rv != SECSuccess ) { - goto loser; - } - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * delete a nickname entry - */ -static SECStatus -DeleteDBNicknameEntry(CERTCertDBHandle *handle, char *nickname) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - SECItem dbkey; - - if ( nickname == NULL ) { - return(SECSuccess); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBNicknameKey(nickname, arena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read a nickname entry - */ -static certDBEntryNickname * -ReadDBNicknameEntry(CERTCertDBHandle *handle, char *nickname) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryNickname *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryNickname)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeNickname; - - rv = EncodeDBNicknameKey(nickname, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - /* is record long enough for header? */ - if ( dbentry.len < DB_NICKNAME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - rv = DecodeDBNicknameEntry(entry, &dbentry); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Encode a nickname entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBNicknameEntry(CERTCertDBHandle *handle, certDBEntryNickname *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); - -} - -/* - * Encode a database smime record - */ -static SECStatus -EncodeDBSMimeEntry(certDBEntrySMime *entry, PRArenaPool *arena, - SECItem *dbitem) -{ - unsigned char *buf; - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->subjectName.len + entry->smimeOptions.len + - entry->optionsDate.len + - DB_SMIME_ENTRY_HEADER_LEN + SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->subjectName.len >> 8 ) & 0xff; - buf[1] = entry->subjectName.len & 0xff; - buf[2] = ( entry->smimeOptions.len >> 8 ) & 0xff; - buf[3] = entry->smimeOptions.len & 0xff; - buf[4] = ( entry->optionsDate.len >> 8 ) & 0xff; - buf[5] = entry->optionsDate.len & 0xff; - - /* if no smime options, then there should not be an options date either */ - PORT_Assert( ! ( ( entry->smimeOptions.len == 0 ) && - ( entry->optionsDate.len != 0 ) ) ); - - PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN], entry->subjectName.data, - entry->subjectName.len); - if ( entry->smimeOptions.len ) { - PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN+entry->subjectName.len], - entry->smimeOptions.data, - entry->smimeOptions.len); - PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len + - entry->smimeOptions.len], - entry->optionsDate.data, - entry->optionsDate.len); - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Encode a database key for a SMIME record - */ -static SECStatus -EncodeDBSMimeKey(char *emailAddr, PRArenaPool *arena, - SECItem *dbkey) -{ - unsigned int addrlen; - - addrlen = PORT_Strlen(emailAddr) + 1; /* includes null */ - - /* now get the database key and format it */ - dbkey->len = addrlen + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen); - dbkey->data[0] = certDBEntryTypeSMimeProfile; - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Decode a database SMIME record - */ -static SECStatus -DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr) -{ - /* is record long enough for header? */ - if ( dbentry->len < DB_SMIME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - entry->smimeOptions.len = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] ); - entry->optionsDate.len = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] ); - if (( entry->subjectName.len + entry->smimeOptions.len + - entry->optionsDate.len + DB_SMIME_ENTRY_HEADER_LEN ) != dbentry->len){ - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy the subject name */ - entry->subjectName.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->subjectName.len); - if ( entry->subjectName.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->subjectName.data, - &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN], - entry->subjectName.len); - - /* copy the smime options */ - if ( entry->smimeOptions.len ) { - entry->smimeOptions.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->smimeOptions.len); - if ( entry->smimeOptions.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->smimeOptions.data, - &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN + - entry->subjectName.len], - entry->smimeOptions.len); - } - if ( entry->optionsDate.len ) { - entry->optionsDate.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->optionsDate.len); - if ( entry->optionsDate.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->optionsDate.data, - &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN + - entry->subjectName.len + - entry->smimeOptions.len], - entry->optionsDate.len); - } - - /* both options and options date must either exist or not exist */ - if ( ( ( entry->optionsDate.len == 0 ) || - ( entry->smimeOptions.len == 0 ) ) && - entry->smimeOptions.len != entry->optionsDate.len ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - entry->emailAddr = (char *)PORT_Alloc(PORT_Strlen(emailAddr)+1); - if ( entry->emailAddr ) { - PORT_Strcpy(entry->emailAddr, emailAddr); - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new SMIME entry - */ -static certDBEntrySMime * -NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions, - SECItem *optionsDate, unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntrySMime *entry; - int addrlen; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySMime)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* init common fields */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSMimeProfile; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - /* copy the email addr */ - addrlen = PORT_Strlen(emailAddr) + 1; - - entry->emailAddr = (char*)PORT_ArenaAlloc(arena, addrlen); - if ( entry->emailAddr == NULL ) { - goto loser; - } - - PORT_Memcpy(entry->emailAddr, emailAddr, addrlen); - - /* copy the subject name */ - rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName); - if ( rv != SECSuccess ) { - goto loser; - } - - /* copy the smime options */ - if ( smimeOptions ) { - rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - PORT_Assert(optionsDate == NULL); - entry->smimeOptions.data = NULL; - entry->smimeOptions.len = 0; - } - - /* copy the options date */ - if ( optionsDate ) { - rv = SECITEM_CopyItem(arena, &entry->optionsDate, optionsDate); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - PORT_Assert(smimeOptions == NULL); - entry->optionsDate.data = NULL; - entry->optionsDate.len = 0; - } - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * delete a SMIME entry - */ -static SECStatus -DeleteDBSMimeEntry(CERTCertDBHandle *handle, char *emailAddr) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - SECItem dbkey; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read a SMIME entry - */ -static certDBEntrySMime * -ReadDBSMimeEntry(CERTCertDBHandle *handle, char *emailAddr) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntrySMime *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySMime)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSMimeProfile; - - rv = EncodeDBSMimeKey(emailAddr, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - /* is record long enough for header? */ - if ( dbentry.len < DB_SMIME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - rv = DecodeDBSMimeEntry(entry, &dbentry, emailAddr); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Encode a SMIME entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBSMimeEntry(CERTCertDBHandle *handle, certDBEntrySMime *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBSMimeKey(entry->emailAddr, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); - -} - -/* - * Encode a database subject record - */ -static SECStatus -EncodeDBSubjectEntry(certDBEntrySubject *entry, PRArenaPool *arena, - SECItem *dbitem) -{ - unsigned char *buf; - int len; - unsigned int ncerts; - unsigned int i; - unsigned char *tmpbuf; - unsigned int nnlen = 0; - unsigned int eaddrlen = 0; - int keyidoff; - SECItem *certKeys; - SECItem *keyIDs; - - if ( entry->nickname ) { - nnlen = PORT_Strlen(entry->nickname) + 1; - } - if ( entry->emailAddr ) { - eaddrlen = PORT_Strlen(entry->emailAddr) + 1; - } - - ncerts = entry->ncerts; - - /* compute the length of the entry */ - keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen; - len = keyidoff + 4 * ncerts; - for ( i = 0; i < ncerts; i++ ) { - len += entry->certKeys[i].len; - len += entry->keyIDs[i].len; - } - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = len + SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( ncerts >> 8 ) & 0xff; - buf[1] = ncerts & 0xff; - buf[2] = ( nnlen >> 8 ) & 0xff; - buf[3] = nnlen & 0xff; - buf[4] = ( eaddrlen >> 8 ) & 0xff; - buf[5] = eaddrlen & 0xff; - - PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN], entry->nickname, nnlen); - PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen], entry->emailAddr, - eaddrlen); - - for ( i = 0; i < ncerts; i++ ) { - - certKeys = entry->certKeys; - keyIDs = entry->keyIDs; - - buf[keyidoff+i*2] = ( certKeys[i].len >> 8 ) & 0xff; - buf[keyidoff+1+i*2] = certKeys[i].len & 0xff; - buf[keyidoff+ncerts*2+i*2] = ( keyIDs[i].len >> 8 ) & 0xff; - buf[keyidoff+1+ncerts*2+i*2] = keyIDs[i].len & 0xff; - } - - /* temp pointer used to stuff certkeys and keyids into the buffer */ - tmpbuf = &buf[keyidoff+ncerts*4]; - - for ( i = 0; i < ncerts; i++ ) { - certKeys = entry->certKeys; - PORT_Memcpy(tmpbuf, certKeys[i].data, certKeys[i].len); - tmpbuf = tmpbuf + certKeys[i].len; - } - - for ( i = 0; i < ncerts; i++ ) { - keyIDs = entry->keyIDs; - PORT_Memcpy(tmpbuf, keyIDs[i].data, keyIDs[i].len); - tmpbuf = tmpbuf + keyIDs[i].len; - } - - PORT_Assert(tmpbuf == &buf[len]); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Encode a database key for a subject record - */ -static SECStatus -EncodeDBSubjectKey(SECItem *derSubject, PRArenaPool *arena, - SECItem *dbkey) -{ - dbkey->len = derSubject->len + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], derSubject->data, - derSubject->len); - dbkey->data[0] = certDBEntryTypeSubject; - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry, - SECItem *derSubject) -{ - unsigned int ncerts; - PRArenaPool *arena; - unsigned int len, itemlen; - unsigned char *tmpbuf; - unsigned int i; - SECStatus rv; - unsigned int keyidoff; - unsigned int nnlen, eaddrlen; - - arena = entry->common.arena; - - rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject); - if ( rv != SECSuccess ) { - goto loser; - } - - /* is record long enough for header? */ - if ( dbentry->len < DB_SUBJECT_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - entry->ncerts = ncerts = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] ); - eaddrlen = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] ); - if ( dbentry->len < ( ncerts * 4 + DB_SUBJECT_ENTRY_HEADER_LEN + - nnlen + eaddrlen) ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, - sizeof(SECItem) * ncerts); - entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, - sizeof(SECItem) * ncerts); - - if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - if ( nnlen > 1 ) { /* null terminator is stored */ - entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( entry->nickname == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->nickname, - &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN], - nnlen); - } else { - entry->nickname = NULL; - } - - if ( eaddrlen > 1 ) { /* null terminator is stored */ - entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen); - if ( entry->emailAddr == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->emailAddr, - &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen], - eaddrlen); - } else { - entry->emailAddr = NULL; - } - - /* collect the lengths of the certKeys and keyIDs, and total the - * overall length. - */ - keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen; - len = keyidoff + 4 * ncerts; - - tmpbuf = &dbentry->data[0]; - - for ( i = 0; i < ncerts; i++ ) { - - itemlen = ( tmpbuf[keyidoff + 2*i] << 8 ) | tmpbuf[keyidoff + 1 + 2*i] ; - len += itemlen; - entry->certKeys[i].len = itemlen; - - itemlen = ( tmpbuf[keyidoff + 2*ncerts + 2*i] << 8 ) | - tmpbuf[keyidoff + 1 + 2*ncerts + 2*i] ; - len += itemlen; - entry->keyIDs[i].len = itemlen; - } - - /* is database entry correct length? */ - if ( len != dbentry->len ){ - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - tmpbuf = &tmpbuf[keyidoff + 4*ncerts]; - for ( i = 0; i < ncerts; i++ ) { - entry->certKeys[i].data = - (unsigned char *)PORT_ArenaAlloc(arena, entry->certKeys[i].len); - if ( entry->certKeys[i].data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->certKeys[i].data, tmpbuf, entry->certKeys[i].len); - tmpbuf = &tmpbuf[entry->certKeys[i].len]; - } - - for ( i = 0; i < ncerts; i++ ) { - entry->keyIDs[i].data = - (unsigned char *)PORT_ArenaAlloc(arena, entry->keyIDs[i].len); - if ( entry->keyIDs[i].data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->keyIDs[i].data, tmpbuf, entry->keyIDs[i].len); - tmpbuf = &tmpbuf[entry->keyIDs[i].len]; - } - - PORT_Assert(tmpbuf == &dbentry->data[dbentry->len]); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new subject entry with a single cert - */ -static certDBEntrySubject * -NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey, - SECItem *keyID, char *nickname, char *emailAddr, - unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntrySubject *entry; - SECStatus rv; - unsigned int nnlen; - unsigned int eaddrlen; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySubject)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* init common fields */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSubject; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - /* copy the subject */ - rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject); - if ( rv != SECSuccess ) { - goto loser; - } - - entry->ncerts = 1; - /* copy nickname */ - if ( nickname && ( *nickname != '\0' ) ) { - nnlen = PORT_Strlen(nickname) + 1; - entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( entry->nickname == NULL ) { - goto loser; - } - - PORT_Memcpy(entry->nickname, nickname, nnlen); - } else { - entry->nickname = NULL; - } - - /* copy email addr */ - if ( emailAddr && ( *emailAddr != '\0' ) ) { - emailAddr = CERT_FixupEmailAddr(emailAddr); - if ( emailAddr == NULL ) { - entry->emailAddr = NULL; - goto loser; - } - - eaddrlen = PORT_Strlen(emailAddr) + 1; - entry->emailAddr = (char *)PORT_ArenaAlloc(arena, eaddrlen); - if ( entry->emailAddr == NULL ) { - PORT_Free(emailAddr); - goto loser; - } - - PORT_Memcpy(entry->emailAddr, emailAddr, eaddrlen); - PORT_Free(emailAddr); - } else { - entry->emailAddr = NULL; - } - - /* allocate space for certKeys and keyIDs */ - entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); - entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); - if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) { - goto loser; - } - - /* copy the certKey and keyID */ - rv = SECITEM_CopyItem(arena, &entry->certKeys[0], certKey); - if ( rv != SECSuccess ) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID); - if ( rv != SECSuccess ) { - goto loser; - } - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * delete a subject entry - */ -static SECStatus -DeleteDBSubjectEntry(CERTCertDBHandle *handle, SECItem *derSubject) -{ - SECItem dbkey; - PRArenaPool *arena = NULL; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBSubjectKey(derSubject, arena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read the subject entry - */ -static certDBEntrySubject * -ReadDBSubjectEntry(CERTCertDBHandle *handle, SECItem *derSubject) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntrySubject *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySubject)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSubject; - - rv = EncodeDBSubjectKey(derSubject, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Encode a subject name entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBSubjectEntry(CERTCertDBHandle *handle, certDBEntrySubject *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBSubjectKey(&entry->derSubject, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); - -} - -static SECStatus -UpdateSubjectWithEmailAddr(CERTCertificate *cert, char *emailAddr) -{ - CERTSubjectList *subjectList; - PRBool save = PR_FALSE, delold = PR_FALSE; - certDBEntrySubject *entry; - SECStatus rv; - - emailAddr = CERT_FixupEmailAddr(emailAddr); - if ( emailAddr == NULL ) { - return(SECFailure); - } - - subjectList = cert->subjectList; - PORT_Assert(subjectList != NULL); - - if ( subjectList->emailAddr ) { - if ( PORT_Strcmp(subjectList->emailAddr, emailAddr) != 0 ) { - save = PR_TRUE; - delold = PR_TRUE; - } - } else { - save = PR_TRUE; - } - - if ( delold ) { - /* delete the old smime entry, because this cert now has a new - * smime entry pointing to it - */ - PORT_Assert(save); - PORT_Assert(subjectList->emailAddr != NULL); - DeleteDBSMimeEntry(cert->dbhandle, subjectList->emailAddr); - } - - if ( save ) { - unsigned int len; - - entry = subjectList->entry; - - PORT_Assert(entry != NULL); - len = PORT_Strlen(emailAddr) + 1; - entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena, len); - if ( entry->emailAddr == NULL ) { - goto loser; - } - PORT_Memcpy(entry->emailAddr, emailAddr, len); - - /* delete the subject entry */ - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - - /* write the new one */ - rv = WriteDBSubjectEntry(cert->dbhandle, entry); - if ( rv != SECSuccess ) { - goto loser; - } - } - - PORT_Free(emailAddr); - return(SECSuccess); - -loser: - PORT_Free(emailAddr); - return(SECFailure); -} - -/* - * writes a nickname to an existing subject entry that does not currently - * have one - */ -static SECStatus -AddNicknameToSubject(CERTCertificate *cert, char *nickname) -{ - CERTSubjectList *subjectList; - certDBEntrySubject *entry; - SECStatus rv; - - if ( nickname == NULL ) { - return(SECFailure); - } - - subjectList = cert->subjectList; - PORT_Assert(subjectList != NULL); - if ( subjectList == NULL ) { - goto loser; - } - - entry = subjectList->entry; - PORT_Assert(entry != NULL); - if ( entry == NULL ) { - goto loser; - } - - PORT_Assert(entry->nickname == NULL); - if ( entry->nickname != NULL ) { - goto loser; - } - - entry->nickname = (nickname) ? PORT_ArenaStrdup(entry->common.arena, nickname) : NULL; - - if ( entry->nickname == NULL ) { - goto loser; - } - - /* delete the subject entry */ - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - - /* write the new one */ - rv = WriteDBSubjectEntry(cert->dbhandle, entry); - if ( rv != SECSuccess ) { - goto loser; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new version entry - */ -static certDBEntryVersion * -NewDBVersionEntry(unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntryVersion *entry; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryVersion)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeVersion; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Read the version entry - */ -static certDBEntryVersion * -ReadDBVersionEntry(CERTCertDBHandle *handle) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryVersion *entry; - SECItem dbkey; - SECItem dbentry; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryVersion)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeVersion; - - /* now get the database key and format it */ - dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN; - dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len); - if ( dbkey.data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY, - SEC_DB_VERSION_KEY_LEN); - - ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - - -/* - * Encode a version entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBVersionEntry(CERTCertDBHandle *handle, certDBEntryVersion *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem.len = SEC_DB_ENTRY_HEADER_LEN; - - dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len); - if ( dbitem.data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* now get the database key and format it */ - dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN; - dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len); - if ( dbkey.data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY, - SEC_DB_VERSION_KEY_LEN); - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); -} - -/* - * create a new version entry - */ -static certDBEntryContentVersion * -NewDBContentVersionEntry(unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntryContentVersion *entry; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryContentVersion *) - PORT_ArenaAlloc(arena, sizeof(certDBEntryContentVersion)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeContentVersion; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - entry->contentVersion = CERT_DB_CONTENT_VERSION; - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Read the version entry - */ -static certDBEntryContentVersion * -ReadDBContentVersionEntry(CERTCertDBHandle *handle) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryContentVersion *entry; - SECItem dbkey; - SECItem dbentry; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryContentVersion *) - PORT_ArenaAlloc(arena, sizeof(certDBEntryContentVersion)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeContentVersion; - - /* now get the database key and format it */ - dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN; - dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len); - if ( dbkey.data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY, - SEC_DB_CONTENT_VERSION_KEY_LEN); - - dbentry.len = 0; - dbentry.data = NULL; - - ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - - if ( dbentry.len != 1 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - entry->contentVersion = dbentry.data[0]; - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Encode a version entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBContentVersionEntry(CERTCertDBHandle *handle, - certDBEntryContentVersion *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem.len = SEC_DB_ENTRY_HEADER_LEN + 1; - - dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len); - if ( dbitem.data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - dbitem.data[SEC_DB_ENTRY_HEADER_LEN] = entry->contentVersion; - - /* now get the database key and format it */ - dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN; - dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len); - if ( dbkey.data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY, - SEC_DB_CONTENT_VERSION_KEY_LEN); - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); -} - -/* - * delete a content version entry - */ -static SECStatus -DeleteDBContentVersionEntry(CERTCertDBHandle *handle) -{ - SECItem dbkey; - PRArenaPool *arena = NULL; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - /* now get the database key and format it */ - dbkey.len = SEC_DB_CONTENT_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN; - dbkey.data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey.len); - if ( dbkey.data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_CONTENT_VERSION_KEY, - SEC_DB_CONTENT_VERSION_KEY_LEN); - - rv = DeleteDBEntry(handle, certDBEntryTypeContentVersion, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Routines and datastructures to manage the list of certificates for a - * particular subject name. - */ - -/* - * Create a new certificate subject list. If entry exists, then populate - * the list with the entries from the permanent database. - */ -static CERTSubjectList * -NewSubjectList(certDBEntrySubject *entry) -{ - PRArenaPool *permarena; - unsigned int i; - CERTSubjectList *subjectList; - CERTSubjectNode *node; - SECStatus rv; - - permarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( permarena == NULL ) { - goto loser; - } - subjectList = (CERTSubjectList *)PORT_ArenaAlloc(permarena, - sizeof(CERTSubjectList)); - if ( subjectList == NULL ) { - goto loser; - } - - subjectList->arena = permarena; - subjectList->ncerts = 0; - subjectList->head = NULL; - subjectList->tail = NULL; - subjectList->entry = entry; - subjectList->emailAddr = NULL; - if ( entry ) { - - /* initialize the list with certs from database entry */ - for ( i = 0; i < entry->ncerts; i++ ) { - /* Init the node */ - node = (CERTSubjectNode *)PORT_ArenaAlloc(permarena, - sizeof(CERTSubjectNode)); - if ( node == NULL ) { - goto loser; - } - - /* copy certKey and keyID to node */ - rv = SECITEM_CopyItem(permarena, &node->certKey, - &entry->certKeys[i]); - if ( rv != SECSuccess ) { - goto loser; - } - rv = SECITEM_CopyItem(permarena, &node->keyID, - &entry->keyIDs[i]); - if ( rv != SECSuccess ) { - goto loser; - } - - /* the certs are already in order, so just add them - * to the tail. - */ - node->next = NULL; - if ( subjectList->tail == NULL ) { - /* first in list */ - subjectList->head = node; - subjectList->tail = node; - node->prev = NULL; - } else { - /* add to end of list */ - node->prev = subjectList->tail; - subjectList->tail = node; - node->prev->next = node; - } - subjectList->ncerts++; - } - } - - return(subjectList); - -loser: - PORT_FreeArena(permarena, PR_FALSE); - return(NULL); -} - -/* - * Find the Subject entry in the temp database. It it is not in the - * temp database, then get it from the perm DB. It its not there either, - * then create a new one. - */ -static CERTSubjectList * -FindSubjectList(CERTCertDBHandle *handle, SECItem *subject, PRBool create) -{ - PRArenaPool *arena = NULL; - SECItem keyitem; - SECStatus rv; - DBT namekey; - DBT tmpdata; - int ret; - CERTSubjectList *subjectList = NULL; - certDBEntrySubject *entry; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBSubjectKey(subject, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - namekey.data = keyitem.data; - namekey.size = keyitem.len; - - /* lookup in the temporary database */ - ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0); - - /* error accessing the database */ - if ( ret < 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - if ( ret == 0 ) { /* found in temp database */ - if ( tmpdata.size != sizeof(CERTCertificate *) ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy pointer out of database */ - PORT_Memcpy(&subjectList, tmpdata.data, tmpdata.size); - } else { /* not found in temporary database */ - entry = ReadDBSubjectEntry(handle, subject); - if ( entry || create ) { - /* decode or create new subject list */ - subjectList = NewSubjectList(entry); - - /* put it in the temp database */ - if ( subjectList ) { - tmpdata.data = (unsigned char *)(&subjectList); - tmpdata.size = sizeof(subjectList); - ret = certdb_Put(handle->tempCertDB, &namekey, - &tmpdata, R_NOOVERWRITE); - if ( ret ) { - goto loser; - } - } - } else { - PORT_SetError(SEC_ERROR_UNKNOWN_CERT); - goto loser; - } - } - - goto done; - -loser: - subjectList = NULL; - -done: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(subjectList); -} - -/* - * Add a temp cert to the temp subject list - */ -static SECStatus -AddTempCertToSubjectList(CERTCertificate *cert) -{ - CERTSubjectList *subjectList; - CERTSubjectNode *node, *newnode; - CERTCertificate *cmpcert; - PRBool newer; - SECStatus rv; - - PORT_Assert(cert->isperm == PR_FALSE); - PORT_Assert(cert->subjectList == NULL); - - subjectList = FindSubjectList(cert->dbhandle, &cert->derSubject, PR_TRUE); - - if ( subjectList == NULL ) { - goto loser; - } - - newnode = (CERTSubjectNode*)PORT_ArenaAlloc(subjectList->arena, - sizeof(CERTSubjectNode)); - /* copy certKey and keyID to node */ - rv = SECITEM_CopyItem(subjectList->arena, &newnode->certKey, - &cert->certKey); - if ( rv != SECSuccess ) { - goto loser; - } - rv = SECITEM_CopyItem(subjectList->arena, &newnode->keyID, - &cert->subjectKeyID); - if ( rv != SECSuccess ) { - goto loser; - } - - node = subjectList->head; - - if ( node ) { - /* list is not empty */ - while ( node ) { - cmpcert = CERT_FindCertByKeyNoLocking(cert->dbhandle, - &node->certKey); - if ( cmpcert ) { - - newer = CERT_IsNewer(cert, cmpcert); - CERT_DestroyCertificateNoLocking(cmpcert); - if ( newer ) { - /* insert before this cert */ - newnode->next = node; - newnode->prev = node->prev; - if ( newnode->prev ) { - newnode->prev->next = newnode; - } else { - /* at the head of the list */ - subjectList->head = newnode; - } - node->prev = newnode; - goto done; - } - } - node = node->next; - } - /* if we get here, we add the node to the end of the list */ - newnode->prev = subjectList->tail; - newnode->next = NULL; - subjectList->tail->next = newnode; - subjectList->tail = newnode; - } else { - /* this is a new/empty list */ - newnode->next = NULL; - newnode->prev = NULL; - subjectList->head = newnode; - subjectList->tail = newnode; - } - -done: - subjectList->ncerts++; - cert->subjectList = subjectList; - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Find the node in a subjectList that belongs a cert - */ -static CERTSubjectNode * -FindCertSubjectNode(CERTCertificate *cert) -{ - CERTSubjectList *subjectList; - CERTSubjectNode *node = NULL; - - PORT_Assert(cert->subjectList); - - subjectList = cert->subjectList; - - if ( subjectList ) { - node = subjectList->head; - } - - while ( node ) { - if ( SECITEM_CompareItem(&node->certKey, &cert->certKey) == SECEqual ){ - return(node); - break; - } - - node = node->next; - } - - return(NULL); -} - -/* - * Remove a temp cert from the temp subject list - */ -static SECStatus -RemoveTempCertFromSubjectList(CERTCertificate *cert) -{ - CERTSubjectList *subjectList; - CERTSubjectNode *node; - SECItem keyitem; - DBT namekey; - SECStatus rv; - int ret; - CERTCertDBHandle *handle; - - PORT_Assert(cert->subjectList); - - /* don't remove perm certs */ - if ( cert->isperm ) { - return(SECSuccess); - } - - subjectList = cert->subjectList; - - node = FindCertSubjectNode(cert); - - if ( node ) { - /* found it, unlink it */ - if ( node->next ) { - node->next->prev = node->prev; - } else { - /* removing from tail of list */ - subjectList->tail = node->prev; - } - if ( node->prev ) { - node->prev->next = node->next; - } else { - /* removing from head of list */ - subjectList->head = node->next; - } - - subjectList->ncerts--; - - /* dont need to free the node, because it is from subjectList - * arena. - */ - - /* remove reference from cert */ - cert->subjectList = NULL; - - /* if the list is now empty, remove the list from the db and free it */ - if ( subjectList->head == NULL ) { - PORT_Assert(subjectList->ncerts == 0); - rv = EncodeDBSubjectKey(&cert->derSubject, subjectList->arena, - &keyitem); - if ( rv == SECSuccess ) { - namekey.data = keyitem.data; - namekey.size = keyitem.len; - - handle = cert->dbhandle; - - ret = certdb_Del(handle->tempCertDB, &namekey, 0); - /* keep going if it fails */ - - if ( cert->dbnickname ) { - rv = SEC_DeleteTempNickname(handle, cert->dbnickname); - } else if ( cert->nickname ) { - rv = SEC_DeleteTempNickname(handle, cert->nickname); - } - - /* keep going if it fails */ - } - - PORT_FreeArena(subjectList->arena, PR_FALSE); - } - } - - PORT_Assert(cert->subjectList == NULL); - - if ( cert->subjectList != NULL ) { - return(SECFailure); - } - - return(SECSuccess); -} - -/* - * cert is no longer a perm cert, but will remain a temp cert - */ -static SECStatus -RemovePermSubjectNode(CERTCertificate *cert) -{ - CERTSubjectList *subjectList; - certDBEntrySubject *entry; - unsigned int i; - SECStatus rv; - - PORT_Assert(cert->isperm); - if ( !cert->isperm ) { - return(SECFailure); - } - - subjectList = cert->subjectList; - PORT_Assert(subjectList); - if ( subjectList == NULL ) { - return(SECFailure); - } - entry = subjectList->entry; - PORT_Assert(entry); - if ( entry == NULL ) { - return(SECFailure); - } - - PORT_Assert(entry->ncerts); - rv = SECFailure; - - if ( entry->ncerts > 1 ) { - for ( i = 0; i < entry->ncerts; i++ ) { - if ( SECITEM_CompareItem(&entry->certKeys[i], &cert->certKey) == - SECEqual ) { - /* copy rest of list forward one entry */ - for ( i = i + 1; i < entry->ncerts; i++ ) { - entry->certKeys[i-1] = entry->certKeys[i]; - entry->keyIDs[i-1] = entry->keyIDs[i]; - } - entry->ncerts--; - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - rv = WriteDBSubjectEntry(cert->dbhandle, entry); - break; - } - } - } else { - /* no entries left, delete the perm entry in the DB */ - if ( subjectList->entry->emailAddr ) { - /* if the subject had an email record, then delete it too */ - DeleteDBSMimeEntry(cert->dbhandle, subjectList->entry->emailAddr); - } - - DestroyDBEntry((certDBEntry *)subjectList->entry); - subjectList->entry = NULL; - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - } - - return(rv); -} - -/* - * add a cert to the perm subject list - */ -static SECStatus -AddPermSubjectNode(CERTCertificate *cert, char *nickname) -{ - CERTSubjectList *subjectList; - certDBEntrySubject *entry; - SECItem *newCertKeys, *newKeyIDs; - int i; - SECStatus rv; - CERTCertificate *cmpcert; - unsigned int nnlen; - int ncerts; - - subjectList = cert->subjectList; - - PORT_Assert(subjectList); - if ( subjectList == NULL ) { - return(SECFailure); - } - - entry = subjectList->entry; - - if ( entry ) { - ncerts = entry->ncerts; - - if ( nickname && entry->nickname ) { - /* nicknames must be the same */ - PORT_Assert(PORT_Strcmp(nickname, entry->nickname) == 0); - } - - if ( ( entry->nickname == NULL ) && ( nickname != NULL ) ) { - /* copy nickname into the entry */ - nnlen = PORT_Strlen(nickname) + 1; - entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena, - nnlen); - if ( entry->nickname == NULL ) { - return(SECFailure); - } - PORT_Memcpy(entry->nickname, nickname, nnlen); - } - - /* a DB entry already exists, so add this cert */ - newCertKeys = (SECItem *)PORT_ArenaAlloc(entry->common.arena, - sizeof(SECItem) * - ( ncerts + 1 ) ); - newKeyIDs = (SECItem *)PORT_ArenaAlloc(entry->common.arena, - sizeof(SECItem) * - ( ncerts + 1 ) ); - - if ( ( newCertKeys == NULL ) || ( newKeyIDs == NULL ) ) { - return(SECFailure); - } - - for ( i = 0; i < ncerts; i++ ) { - cmpcert = CERT_FindCertByKeyNoLocking(cert->dbhandle, - &entry->certKeys[i]); - PORT_Assert(cmpcert); - - if ( CERT_IsNewer(cert, cmpcert) ) { - /* insert before cmpcert */ - rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[i], - &cert->certKey); - if ( rv != SECSuccess ) { - return(SECFailure); - } - rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[i], - &cert->subjectKeyID); - if ( rv != SECSuccess ) { - return(SECFailure); - } - /* copy the rest of the entry */ - for ( ; i < ncerts; i++ ) { - newCertKeys[i+1] = entry->certKeys[i]; - newKeyIDs[i+1] = entry->keyIDs[i]; - } - - /* update certKeys and keyIDs */ - entry->certKeys = newCertKeys; - entry->keyIDs = newKeyIDs; - - /* increment count */ - entry->ncerts++; - break; - } - /* copy this cert entry */ - newCertKeys[i] = entry->certKeys[i]; - newKeyIDs[i] = entry->keyIDs[i]; - } - - if ( entry->ncerts == ncerts ) { - /* insert new one at end */ - rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[ncerts], - &cert->certKey); - if ( rv != SECSuccess ) { - return(SECFailure); - } - rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[ncerts], - &cert->subjectKeyID); - if ( rv != SECSuccess ) { - return(SECFailure); - } - - /* update certKeys and keyIDs */ - entry->certKeys = newCertKeys; - entry->keyIDs = newKeyIDs; - - /* increment count */ - entry->ncerts++; - } - } else { - /* need to make a new DB entry */ - entry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey, - &cert->subjectKeyID, nickname, - NULL, 0); - cert->subjectList->entry = entry; - } - if ( entry ) { - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - rv = WriteDBSubjectEntry(cert->dbhandle, entry); - } else { - rv = SECFailure; - } - - return(rv); -} - - - -SECStatus -CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject, - CERTCertCallback cb, void *cbarg) -{ - certDBEntrySubject *entry; - int i; - CERTCertificate *cert; - SECStatus rv = SECSuccess; - - entry = ReadDBSubjectEntry(handle, derSubject); - - if ( entry == NULL ) { - return(SECFailure); - } - - for( i = 0; i < entry->ncerts; i++ ) { - cert = CERT_FindCertByKey(handle, &entry->certKeys[i]); - rv = (* cb)(cert, cbarg); - CERT_DestroyCertificate(cert); - if ( rv == SECFailure ) { - break; - } - } - - DestroyDBEntry((certDBEntry *)entry); - - return(rv); -} - -int -CERT_NumPermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject) -{ - certDBEntrySubject *entry; - int ret; - - entry = ReadDBSubjectEntry(handle, derSubject); - - if ( entry == NULL ) { - return(SECFailure); - } - - ret = entry->ncerts; - - DestroyDBEntry((certDBEntry *)entry); - - return(ret); -} - -SECStatus -CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname, - CERTCertCallback cb, void *cbarg) -{ - certDBEntryNickname *nnentry = NULL; - certDBEntrySMime *smentry = NULL; - SECStatus rv; - SECItem *derSubject = NULL; - - nnentry = ReadDBNicknameEntry(handle, nickname); - if ( nnentry ) { - derSubject = &nnentry->subjectName; - } else { - smentry = ReadDBSMimeEntry(handle, nickname); - if ( smentry ) { - derSubject = &smentry->subjectName; - } - } - - if ( derSubject ) { - rv = CERT_TraversePermCertsForSubject(handle, derSubject, - cb, cbarg); - } else { - rv = SECFailure; - } - - if ( nnentry ) { - DestroyDBEntry((certDBEntry *)nnentry); - } - if ( smentry ) { - DestroyDBEntry((certDBEntry *)smentry); - } - - return(rv); -} - -int -CERT_NumPermCertsForNickname(CERTCertDBHandle *handle, char *nickname) -{ - certDBEntryNickname *entry; - int ret; - - entry = ReadDBNicknameEntry(handle, nickname); - - if ( entry ) { - ret = CERT_NumPermCertsForSubject(handle, &entry->subjectName); - DestroyDBEntry((certDBEntry *)entry); - } else { - ret = 0; - } - return(ret); -} - -int -CERT_NumCertsForCertSubject(CERTCertificate *cert) -{ - int ret = 0; - - if ( cert->subjectList ) { - ret = cert->subjectList->ncerts; - } - return(ret); -} - -int -CERT_NumPermCertsForCertSubject(CERTCertificate *cert) -{ - int ret = 0; - - if ( cert->subjectList ) { - if ( cert->subjectList->entry ) { - ret = cert->subjectList->entry->ncerts; - } - } - return(ret); -} - -SECStatus -CERT_TraverseCertsForSubject(CERTCertDBHandle *handle, - CERTSubjectList *subjectList, - CERTCertCallback cb, void *cbarg) -{ - CERTSubjectNode *node; - CERTCertificate *cert; - SECStatus rv = SECSuccess; - - CERT_LockDB(handle); - - node = subjectList->head; - while ( node ) { - - cert = CERT_FindCertByKeyNoLocking(handle, &node->certKey); - - PORT_Assert(cert != NULL); - - if ( cert != NULL ) { - rv = (* cb)(cert, cbarg); - CERT_DestroyCertificateNoLocking(cert); - if ( rv == SECFailure ) { - break; - } - } - - node = node->next; - } - - CERT_UnlockDB(handle); - - return(rv); -} - - -/* - * Given a cert, find the cert with the same subject name that - * has the given key usage. If the given cert has the correct keyUsage, then - * return it, otherwise search the list in order. - */ -CERTCertificate * -CERT_FindCertByUsage(CERTCertificate *basecert, unsigned int requiredKeyUsage) -{ - CERTSubjectNode *node; - CERTCertificate *cert; - CERTSubjectList *subjectList; - - if ( ( basecert->keyUsage & requiredKeyUsage ) == requiredKeyUsage ) { - return(CERT_DupCertificate(basecert)); - } - - CERT_LockDB(basecert->dbhandle); - - subjectList = basecert->subjectList; - - node = subjectList->head; - while ( node ) { - - cert = CERT_FindCertByKeyNoLocking(basecert->dbhandle, &node->certKey); - - PORT_Assert(cert != NULL); - - if ( cert != NULL ) { - if ( ( cert->keyUsage & requiredKeyUsage ) == - requiredKeyUsage ) { - CERT_UnlockDB(basecert->dbhandle); - return(cert); - } - - CERT_DestroyCertificateNoLocking(cert); - } - - node = node->next; - } - - CERT_UnlockDB(basecert->dbhandle); - - return(NULL); -} - - -/* - * add a nickname to a cert that doesn't have one - */ -static SECStatus -AddNicknameToPermCert(CERTCertificate *cert, char *nickname) -{ - certDBEntryCert *entry; - int rv; - - PORT_Assert(cert->isperm); - if ( !cert->isperm ) { - goto loser; - } - - entry = cert->dbEntry; - PORT_Assert(entry != NULL); - if ( entry == NULL ) { - goto loser; - } - - entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname); - - rv = WriteDBCertEntry(cert->dbhandle, entry); - if ( rv ) { - goto loser; - } - - cert->nickname = PORT_ArenaStrdup(cert->arena, nickname); - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * add a nickname to a cert that is already in the perm database, but doesn't - * have one yet (it is probably an e-mail cert). - */ -SECStatus -CERT_AddPermNickname(CERTCertificate *cert, char *nickname) -{ - SECStatus rv; - - CERT_LockDB(cert->dbhandle); - - PORT_Assert(cert->nickname == NULL); - PORT_Assert(cert->isperm); - PORT_Assert(cert->subjectList != NULL); - PORT_Assert(cert->subjectList->entry != NULL); - - if ( cert->nickname != NULL ) { - goto done; - } - - if ( cert->subjectList == NULL ) { - goto loser; - } - - if ( cert->subjectList->entry == NULL ) { - goto loser; - } - - if ( cert->subjectList->entry->nickname == NULL ) { - /* no nickname for subject */ - rv = AddNicknameToSubject(cert, nickname); - if ( rv != SECSuccess ) { - goto loser; - } - rv = AddNicknameToPermCert(cert, nickname); - if ( rv != SECSuccess ) { - goto loser; - } - rv = SEC_AddTempNickname(cert->dbhandle, nickname, - &cert->derSubject); - if ( rv != SECSuccess ) { - goto loser; - } - - } else { - /* subject already has a nickname */ - rv = AddNicknameToPermCert(cert, cert->subjectList->entry->nickname); - if ( rv != SECSuccess ) { - goto loser; - } - } - -done: - CERT_UnlockDB(cert->dbhandle); - return(SECSuccess); -loser: - CERT_UnlockDB(cert->dbhandle); - return(SECFailure); -} - -static certDBEntryCert * -AddCertToPermDB(CERTCertDBHandle *handle, CERTCertificate *cert, - char *nickname, CERTCertTrust *trust) -{ - certDBEntryCert *certEntry = NULL; - certDBEntryNickname *nicknameEntry = NULL; - certDBEntrySubject *subjectEntry = NULL; - int state = 0; - SECStatus rv; - PRBool donnentry = PR_FALSE; - - if ( nickname ) { - donnentry = PR_TRUE; - } - - if ( cert->subjectList != NULL ) { - if ( cert->subjectList->entry != NULL ) { - if ( cert->subjectList->entry->ncerts > 0 ) { - /* of other certs with same subject exist, then they already - * have a nickname, so don't add a new one. - */ - donnentry = PR_FALSE; - nickname = cert->subjectList->entry->nickname; - } - } - } - - certEntry = NewDBCertEntry(&cert->derCert, nickname, trust, 0); - if ( certEntry == NULL ) { - goto loser; - } - - if ( donnentry ) { - nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0); - if ( nicknameEntry == NULL ) { - goto loser; - } - } - - rv = WriteDBCertEntry(handle, certEntry); - if ( rv != SECSuccess ) { - goto loser; - } - state = 1; - - if ( nicknameEntry ) { - rv = WriteDBNicknameEntry(handle, nicknameEntry); - if ( rv != SECSuccess ) { - goto loser; - } - } - - state = 2; - - /* add to or create new subject entry */ - if ( cert->subjectList ) { - rv = AddPermSubjectNode(cert, nickname); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - /* make a new subject entry - this case is only used when updating - * an old version of the database. This is OK because the oldnickname - * db format didn't allow multiple certs with the same subject. - */ - subjectEntry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey, - &cert->subjectKeyID, nickname, - NULL, 0); - if ( subjectEntry == NULL ) { - goto loser; - } - rv = WriteDBSubjectEntry(handle, subjectEntry); - if ( rv != SECSuccess ) { - goto loser; - } - } - - state = 3; - - if ( nicknameEntry ) { - DestroyDBEntry((certDBEntry *)nicknameEntry); - } - - if ( subjectEntry ) { - DestroyDBEntry((certDBEntry *)subjectEntry); - } - - return(certEntry); - -loser: - /* don't leave partial entry in the database */ - if ( state > 0 ) { - rv = DeleteDBCertEntry(handle, &cert->certKey); - } - if ( ( state > 1 ) && donnentry ) { - rv = DeleteDBNicknameEntry(handle, nickname); - } - if ( state > 2 ) { - rv = DeleteDBSubjectEntry(handle, &cert->derSubject); - } - if ( certEntry ) { - DestroyDBEntry((certDBEntry *)certEntry); - } - if ( nicknameEntry ) { - DestroyDBEntry((certDBEntry *)nicknameEntry); - } - if ( subjectEntry ) { - DestroyDBEntry((certDBEntry *)subjectEntry); - } - - return(NULL); -} - -/* - * NOTE - Version 6 DB did not go out to the real world in a release, - * so we can remove this function in a later release. - */ -static SECStatus -UpdateV6DB(CERTCertDBHandle *handle, DB *updatedb) -{ - int ret; - DBT key, data; - unsigned char *buf, *tmpbuf = NULL; - certDBEntryType type; - certDBEntryNickname *nnEntry = NULL; - certDBEntrySubject *subjectEntry = NULL; - certDBEntrySMime *emailEntry = NULL; - char *nickname; - char *emailAddr; - SECStatus rv; - - /* - * Sequence through the old database and copy all of the entries - * to the new database. Subject name entries will have the new - * fields inserted into them (with zero length). - */ - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - if ( ret ) { - return(SECFailure); - } - - do { - buf = (unsigned char *)data.data; - - if ( data.size >= 3 ) { - if ( buf[0] == 6 ) { /* version number */ - type = (certDBEntryType)buf[1]; - if ( type == certDBEntryTypeSubject ) { - /* expando subjecto entrieo */ - tmpbuf = (unsigned char *)PORT_Alloc(data.size + 4); - if ( tmpbuf ) { - /* copy header stuff */ - PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN + 2); - /* insert 4 more bytes of zero'd header */ - PORT_Memset(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 2], - 0, 4); - /* copy rest of the data */ - PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6], - &buf[SEC_DB_ENTRY_HEADER_LEN + 2], - data.size - (SEC_DB_ENTRY_HEADER_LEN + 2)); - - data.data = (void *)tmpbuf; - data.size += 4; - buf = tmpbuf; - } - } else if ( type == certDBEntryTypeCert ) { - /* expando certo entrieo */ - tmpbuf = (unsigned char *)PORT_Alloc(data.size + 3); - if ( tmpbuf ) { - /* copy header stuff */ - PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN); - - /* copy trust flage, setting msb's to 0 */ - tmpbuf[SEC_DB_ENTRY_HEADER_LEN] = 0; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+1] = - buf[SEC_DB_ENTRY_HEADER_LEN]; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+2] = 0; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+3] = - buf[SEC_DB_ENTRY_HEADER_LEN+1]; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+4] = 0; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+5] = - buf[SEC_DB_ENTRY_HEADER_LEN+2]; - - /* copy rest of the data */ - PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6], - &buf[SEC_DB_ENTRY_HEADER_LEN + 3], - data.size - (SEC_DB_ENTRY_HEADER_LEN + 3)); - - data.data = (void *)tmpbuf; - data.size += 3; - buf = tmpbuf; - } - - } - - /* update the record version number */ - buf[0] = CERT_DB_FILE_VERSION; - - /* copy to the new database */ - ret = certdb_Put(handle->permCertDB, &key, &data, 0); - if ( tmpbuf ) { - PORT_Free(tmpbuf); - tmpbuf = NULL; - } - } - } - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - ret = certdb_Sync(handle->permCertDB, 0); - - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - if ( ret ) { - return(SECFailure); - } - - do { - buf = (unsigned char *)data.data; - - if ( data.size >= 3 ) { - if ( buf[0] == CERT_DB_FILE_VERSION ) { /* version number */ - type = (certDBEntryType)buf[1]; - if ( type == certDBEntryTypeNickname ) { - nickname = &((char *)key.data)[1]; - - /* get the matching nickname entry in the new DB */ - nnEntry = ReadDBNicknameEntry(handle, nickname); - if ( nnEntry == NULL ) { - goto endloop; - } - - /* find the subject entry pointed to by nickname */ - subjectEntry = ReadDBSubjectEntry(handle, - &nnEntry->subjectName); - if ( subjectEntry == NULL ) { - goto endloop; - } - - subjectEntry->nickname = - (char *)PORT_ArenaAlloc(subjectEntry->common.arena, - key.size - 1); - if ( subjectEntry->nickname ) { - PORT_Memcpy(subjectEntry->nickname, nickname, - key.size - 1); - rv = WriteDBSubjectEntry(handle, subjectEntry); - } - } else if ( type == certDBEntryTypeSMimeProfile ) { - emailAddr = &((char *)key.data)[1]; - - /* get the matching smime entry in the new DB */ - emailEntry = ReadDBSMimeEntry(handle, emailAddr); - if ( emailEntry == NULL ) { - goto endloop; - } - - /* find the subject entry pointed to by nickname */ - subjectEntry = ReadDBSubjectEntry(handle, - &emailEntry->subjectName); - if ( subjectEntry == NULL ) { - goto endloop; - } - - subjectEntry->nickname = - (char *)PORT_ArenaAlloc(subjectEntry->common.arena, - key.size - 1); - if ( subjectEntry->emailAddr ) { - PORT_Memcpy(subjectEntry->emailAddr, emailAddr, - key.size - 1); - rv = WriteDBSubjectEntry(handle, subjectEntry); - } - } - -endloop: - if ( subjectEntry ) { - DestroyDBEntry((certDBEntry *)subjectEntry); - subjectEntry = NULL; - } - if ( nnEntry ) { - DestroyDBEntry((certDBEntry *)nnEntry); - nnEntry = NULL; - } - if ( emailEntry ) { - DestroyDBEntry((certDBEntry *)emailEntry); - emailEntry = NULL; - } - } - } - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - ret = certdb_Sync(handle->permCertDB, 0); - - (* updatedb->close)(updatedb); - return(SECSuccess); -} - - -static SECStatus -updateV5Callback(CERTCertificate *cert, SECItem *k, void *pdata) -{ - CERTCertDBHandle *handle; - certDBEntryCert *entry; - CERTCertTrust *trust; - - handle = (CERTCertDBHandle *)pdata; - trust = &cert->dbEntry->trust; - - /* SSL user certs can be used for email if they have an email addr */ - if ( cert->emailAddr && ( trust->sslFlags & CERTDB_USER ) && - ( trust->emailFlags == 0 ) ) { - trust->emailFlags = CERTDB_USER; - } - - entry = AddCertToPermDB(handle, cert, cert->dbEntry->nickname, - &cert->dbEntry->trust); - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - - return(SECSuccess); -} - -static SECStatus -UpdateV5DB(CERTCertDBHandle *handle, DB *updatedb) -{ - CERTCertDBHandle updatehandle; - SECStatus rv; - - updatehandle.permCertDB = updatedb; - updatehandle.dbMon = PR_NewMonitor(); - - rv = SEC_TraversePermCerts(&updatehandle, updateV5Callback, - (void *)handle); - - PR_DestroyMonitor(updatehandle.dbMon); - - return(rv); -} - -static SECStatus -UpdateV4DB(CERTCertDBHandle *handle, DB *updatedb) -{ - DBT key, data; - certDBEntryCert *entry, *entry2; - SECItem derSubject; - int ret; - PRArenaPool *arena = NULL; - CERTCertificate *cert; - - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - - if ( ret ) { - return(SECFailure); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - return(SECFailure); - } - - do { - if ( data.size != 1 ) { /* skip version number */ - - /* decode the old DB entry */ - entry = (certDBEntryCert *)DecodeV4DBCertEntry((unsigned char*)data.data, data.size); - derSubject.data = NULL; - - if ( entry ) { - cert = CERT_DecodeDERCertificate(&entry->derCert, PR_TRUE, - entry->nickname); - - if ( cert != NULL ) { - /* add to new database */ - entry2 = AddCertToPermDB(handle, cert, entry->nickname, - &entry->trust); - - CERT_DestroyCertificate(cert); - if ( entry2 ) { - DestroyDBEntry((certDBEntry *)entry2); - } - } - DestroyDBEntry((certDBEntry *)entry); - } - } - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - PORT_FreeArena(arena, PR_FALSE); - (* updatedb->close)(updatedb); - return(SECSuccess); -} - -/* - * return true if a database key conflict exists - */ -PRBool -SEC_CertDBKeyConflict(SECItem *derCert, CERTCertDBHandle *handle) -{ - SECStatus rv; - DBT tmpdata; - DBT namekey; - int ret; - SECItem keyitem; - PRArenaPool *arena = NULL; - SECItem derKey; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - /* get the db key of the cert */ - rv = CERT_KeyFromDERCert(arena, derCert, &derKey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBCertKey(&derKey, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - namekey.data = keyitem.data; - namekey.size = keyitem.len; - - /* lookup in the temporary database */ - ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0); - - if ( ret == 0 ) { /* found in temp database */ - goto loser; - } else { /* not found in temporary database */ - ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0); - if ( ret == 0 ) { - goto loser; - } - } - - PORT_FreeArena(arena, PR_FALSE); - - return(PR_FALSE); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(PR_TRUE); -} - -#ifdef NOTDEF -/* - * return true if a subject name conflict exists - * NOTE: caller must have already made sure that this exact cert - * doesn't exist in the DB - */ -PRBool -SEC_CertSubjectConflict(SECItem *derCert, CERTCertDBHandle *handle) -{ - SECStatus rv; - DBT tmpdata; - DBT namekey; - int ret; - SECItem keyitem; - PRArenaPool *arena = NULL; - SECItem derName; - - derName.data = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - /* get the subject name of the cert */ - rv = CERT_NameFromDERCert(derCert, &derName); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBSubjectKey(&derName, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - namekey.data = keyitem.data; - namekey.size = keyitem.len; - - /* lookup in the temporary database */ - ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0); - - if ( ret == 0 ) { /* found in temp database */ - return(PR_TRUE); - } else { /* not found in temporary database */ - ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0); - if ( ret == 0 ) { - return(PR_TRUE); - } - } - - PORT_FreeArena(arena, PR_FALSE); - PORT_Free(derName.data); - - return(PR_FALSE); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - if ( derName.data ) { - PORT_Free(derName.data); - } - - return(PR_TRUE); -} -#endif - -/* - * return true if a nickname conflict exists - * NOTE: caller must have already made sure that this exact cert - * doesn't exist in the DB - */ -PRBool -SEC_CertNicknameConflict(char *nickname, SECItem *derSubject, - CERTCertDBHandle *handle) -{ - PRBool rv; - certDBEntryNickname *entry; - - if ( nickname == NULL ) { - return(PR_FALSE); - } - - entry = ReadDBNicknameEntry(handle, nickname); - - if ( entry == NULL ) { - /* no entry for this nickname, so no conflict */ - return(PR_FALSE); - } - - rv = PR_TRUE; - if ( SECITEM_CompareItem(derSubject, &entry->subjectName) == SECEqual ) { - /* if subject names are the same, then no conflict */ - rv = PR_FALSE; - } - - DestroyDBEntry((certDBEntry *)entry); - return(rv); -} - -/* - * Open the certificate database and index databases. Create them if - * they are not there or bad. - */ -SECStatus -SEC_OpenPermCertDB(CERTCertDBHandle *handle, PRBool readOnly, - CERTDBNameFunc namecb, void *cbarg) -{ - SECStatus rv; - int openflags; - certDBEntryVersion *versionEntry = NULL; - DB *updatedb = NULL; - char *tmpname; - char *certdbname; - PRBool updated = PR_FALSE; - PRBool forceUpdate = PR_FALSE; - - certdbname = (* namecb)(cbarg, CERT_DB_FILE_VERSION); - if ( certdbname == NULL ) { - return(SECFailure); - } - - if ( readOnly ) { - openflags = O_RDONLY; - } else { - openflags = O_RDWR; - } - - /* - * first open the permanent file based database. - */ - handle->permCertDB = dbopen( certdbname, openflags, 0600, DB_HASH, 0 ); - - /* check for correct version number */ - if ( handle->permCertDB ) { - versionEntry = ReadDBVersionEntry(handle); - - if ( versionEntry == NULL ) { - /* no version number */ - certdb_Close(handle->permCertDB); - handle->permCertDB = 0; - } else if ( versionEntry->common.version != CERT_DB_FILE_VERSION ) { - /* wrong version number, can't update in place */ - DestroyDBEntry((certDBEntry *)versionEntry); - return(SECFailure); - } - - } - - - /* if first open fails, try to create a new DB */ - if ( handle->permCertDB == NULL ) { - - /* don't create if readonly */ - if ( readOnly ) { - goto loser; - } - - handle->permCertDB = dbopen(certdbname, - O_RDWR | O_CREAT | O_TRUNC, - 0600, DB_HASH, 0); - - /* if create fails then we lose */ - if ( handle->permCertDB == 0 ) { - goto loser; - } - - versionEntry = NewDBVersionEntry(0); - if ( versionEntry == NULL ) { - goto loser; - } - - rv = WriteDBVersionEntry(handle, versionEntry); - - DestroyDBEntry((certDBEntry *)versionEntry); - - if ( rv != SECSuccess ) { - goto loser; - } - - /* try to upgrade old db here */ - tmpname = (* namecb)(cbarg, 6); /* get v6 db name */ - if ( tmpname ) { - updatedb = dbopen( tmpname, O_RDONLY, 0600, DB_HASH, 0 ); - PORT_Free(tmpname); - if ( updatedb ) { - rv = UpdateV6DB(handle, updatedb); - if ( rv != SECSuccess ) { - goto loser; - } - updated = PR_TRUE; - } else { /* no v6 db, so try v5 db */ - tmpname = (* namecb)(cbarg, 5); /* get v5 db name */ - if ( tmpname ) { - updatedb = dbopen( tmpname, O_RDONLY, 0600, DB_HASH, 0 ); - PORT_Free(tmpname); - if ( updatedb ) { - rv = UpdateV5DB(handle, updatedb); - if ( rv != SECSuccess ) { - goto loser; - } - updated = PR_TRUE; - } else { /* no v5 db, so try v4 db */ - /* try to upgrade v4 db */ - tmpname = (* namecb)(cbarg, 4); /* get v4 db name */ - if ( tmpname ) { - updatedb = dbopen( tmpname, O_RDONLY, 0600, - DB_HASH, 0 ); - PORT_Free(tmpname); - if ( updatedb ) { - rv = UpdateV4DB(handle, updatedb); - if ( rv != SECSuccess ) { - goto loser; - } - forceUpdate = PR_TRUE; - updated = PR_TRUE; - } - } - } - } - } - } - - /* initialize the database with our well known certificates - * or in the case of update, just fall down to CERT_AddNewCerts() - * below. - * Note - if we are updating a really old database, then we try - * to push all of the certs into it. - */ - if ( ( !updated ) || forceUpdate ) { - rv = CERT_InitCertDB(handle); - if ( rv != SECSuccess ) { - goto loser; - } - } - } - - rv = CERT_AddNewCerts(handle); - - return (SECSuccess); - -loser: - - PORT_SetError(SEC_ERROR_BAD_DATABASE); - - if ( handle->permCertDB ) { - certdb_Close(handle->permCertDB); - handle->permCertDB = 0; - } - - return(SECFailure); -} - -/* - * delete all DB records associated with a particular certificate - */ -static SECStatus -DeletePermCert(CERTCertificate *cert) -{ - SECStatus rv; - SECStatus ret; - - ret = SECSuccess; - - rv = DeleteDBCertEntry(cert->dbhandle, &cert->certKey); - if ( rv != SECSuccess ) { - ret = SECFailure; - } - - if ( cert->nickname ) { - rv = DeleteDBNicknameEntry(cert->dbhandle, cert->nickname); - if ( rv != SECSuccess ) { - ret = SECFailure; - } - } - - rv = RemovePermSubjectNode(cert); - - return(ret); -} - -/* - * Delete a certificate from the permanent database. - */ -SECStatus -SEC_DeletePermCertificate(CERTCertificate *cert) -{ - SECStatus rv; - - if ( !cert->isperm ) { - return(SECSuccess); - } - CERT_LockDB(cert->dbhandle); - /* delete the records from the permanent database */ - rv = DeletePermCert(cert); - - /* no longer permanent */ - cert->isperm = PR_FALSE; - - /* get rid of dbcert and stuff pointing to it */ - DestroyDBEntry((certDBEntry *)cert->dbEntry); - cert->dbEntry = NULL; - cert->trust = NULL; - - /* delete it from the temporary database too. It will remain in - * memory until all references go away. - */ - if (cert->slot) { - /* If it's owned by a PKCS #11 slot, don't deleted if from the temp DB just - * yet... rv inherited from DeletePermCert (as if anyone checks the return - * code from this function anyway. */ - CERT_DestroyCertificateNoLocking(cert); - rv = SECSuccess; - } else { - rv = CERT_DeleteTempCertificate(cert); - } - - CERT_UnlockDB(cert->dbhandle); - return(rv); -} - -/* - * Lookup a certificate in the databases. - */ -certDBEntryCert * -SEC_FindPermCertByKey(CERTCertDBHandle *handle, SECItem *key) -{ - return(ReadDBCertEntry(handle, key)); -} - -/* - * Lookup a certificate in the database by name - */ -certDBEntryCert * -SEC_FindPermCertByName(CERTCertDBHandle *handle, SECItem *derSubject) -{ - certDBEntrySubject *subjectEntry; - certDBEntryCert *certEntry; - - subjectEntry = ReadDBSubjectEntry(handle, derSubject); - - if ( subjectEntry == NULL ) { - goto loser; - } - - certEntry = ReadDBCertEntry(handle, &subjectEntry->certKeys[0]); - DestroyDBEntry((certDBEntry *)subjectEntry); - - return(certEntry); - -loser: - return(NULL); -} - -/* - * Lookup a certificate in the database by nickname - */ -certDBEntryCert * -SEC_FindPermCertByNickname(CERTCertDBHandle *handle, char *nickname) -{ - certDBEntryNickname *nicknameEntry; - certDBEntryCert *certEntry; - - nicknameEntry = ReadDBNicknameEntry(handle, nickname); - - if ( nicknameEntry == NULL ) { - goto loser; - } - - certEntry = SEC_FindPermCertByName(handle, &nicknameEntry->subjectName); - DestroyDBEntry((certDBEntry *)nicknameEntry); - - return(certEntry); - -loser: - return(NULL); -} - -/* - * Traverse all of the entries in the database of a particular type - * call the given function for each one. - */ -SECStatus -SEC_TraverseDBEntries(CERTCertDBHandle *handle, - certDBEntryType type, - SECStatus (* callback)(SECItem *data, SECItem *key, - certDBEntryType type, void *pdata), - void *udata ) -{ - DBT data; - DBT key; - SECStatus rv; - int ret; - SECItem dataitem; - SECItem keyitem; - unsigned char *buf; - unsigned char *keybuf; - - ret = certdb_Seq(handle->permCertDB, &key, &data, R_FIRST); - - if ( ret ) { - return(SECFailure); - } - - do { - buf = (unsigned char *)data.data; - - if ( buf[1] == (unsigned char)type ) { - dataitem.len = data.size; - dataitem.data = buf; - dataitem.type = siBuffer; - keyitem.len = key.size - SEC_DB_KEY_HEADER_LEN; - keybuf = (unsigned char *)key.data; - keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN]; - keyitem.type = siBuffer; - - rv = (* callback)(&dataitem, &keyitem, type, udata); - if ( rv != SECSuccess ) { - return(rv); - } - } - } while ( certdb_Seq(handle->permCertDB, &key, &data, R_NEXT) == 0 ); - - return(SECSuccess); -} - -typedef struct { - PermCertCallback certfunc; - CERTCertDBHandle *handle; - void *data; -} PermCertCallbackState; - -/* - * traversal callback to decode certs and call callers callback - */ -static SECStatus -certcallback(SECItem *dbdata, SECItem *dbkey, certDBEntryType type, void *data) -{ - PermCertCallbackState *mystate; - SECStatus rv; - certDBEntryCert entry; - SECItem entryitem; - CERTCertificate *cert; - PRArenaPool *arena = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - mystate = (PermCertCallbackState *)data; - entry.common.version = (unsigned int)dbdata->data[0]; - entry.common.type = (certDBEntryType)dbdata->data[1]; - entry.common.flags = (unsigned int)dbdata->data[2]; - entry.common.arena = arena; - - entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN; - entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN]; - - rv = DecodeDBCertEntry(&entry, &entryitem); - if (rv != SECSuccess ) { - goto loser; - } - entry.derCert.type = siBuffer; - - cert = CERT_DecodeDERCertificate(&entry.derCert, PR_FALSE, - entry.nickname); - cert->dbEntry = &entry; - cert->trust = &entry.trust; - cert->dbhandle = mystate->handle; - - if ( CERT_IsCACert(cert, NULL) || - (( cert->trust->sslFlags & CERTDB_VALID_CA ) || - ( cert->trust->emailFlags & CERTDB_VALID_CA ) || - ( cert->trust->objectSigningFlags & CERTDB_VALID_CA)) ) { - cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } - - rv = (* mystate->certfunc)(cert, dbkey, mystate->data); - - /* arena destroyed by SEC_DestroyCert */ - CERT_DestroyCertificateNoLocking(cert); - - return(rv); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - return(SECFailure); -} - -/* - * Traverse all of the certificates in the permanent database and - * call the given function for each one; expect the caller to have lock. - */ -static SECStatus -TraversePermCertsNoLocking(CERTCertDBHandle *handle, - SECStatus (* certfunc)(CERTCertificate *cert, - SECItem *k, - void *pdata), - void *udata ) -{ - SECStatus rv; - PermCertCallbackState mystate; - - mystate.certfunc = certfunc; - mystate.handle = handle; - mystate.data = udata; - rv = SEC_TraverseDBEntries(handle, certDBEntryTypeCert, certcallback, - (void *)&mystate); - - return(rv); -} - -/* - * Traverse all of the certificates in the permanent database and - * call the given function for each one. - */ -SECStatus -SEC_TraversePermCerts(CERTCertDBHandle *handle, - SECStatus (* certfunc)(CERTCertificate *cert, SECItem *k, - void *pdata), - void *udata ) -{ - SECStatus rv; - - CERT_LockDB(handle); - rv = TraversePermCertsNoLocking(handle, certfunc, udata); - CERT_UnlockDB(handle); - - return(rv); -} - - - -/* - * Close the database - */ -void -CERT_ClosePermCertDB(CERTCertDBHandle *handle) -{ - if ( handle ) { - if ( handle->permCertDB ) { - if ( handle->statusConfig ) { - PORT_Assert(handle->statusConfig->statusDestroy != NULL); - (void) (* handle->statusConfig->statusDestroy)(handle->statusConfig); - handle->statusConfig = NULL; /* Destroy frees the structure */ - PORT_Assert(handle->statusConfig == NULL); - } - certdb_Close( handle->permCertDB ); - handle->permCertDB = 0; - } - } - return; -} - -/* - * Get the trust attributes from a certificate - */ -SECStatus -CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust) -{ - SECStatus rv; - - CERT_LockCertTrust(cert); - - if ( cert->trust == NULL ) { - rv = SECFailure; - } else { - *trust = *cert->trust; - rv = SECSuccess; - } - - CERT_UnlockCertTrust(cert); - return(rv); -} - -/* - * Change the trust attributes of a certificate and make them permanent - * in the database. - */ -SECStatus -CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert, - CERTCertTrust *trust) -{ - certDBEntryCert *entry; - int rv; - SECStatus ret; - - CERT_LockDB(handle); - CERT_LockCertTrust(cert); - /* only set the trust on permanent certs */ - if ( cert->trust == NULL ) { - ret = SECFailure; - goto done; - } - - *cert->trust = *trust; - if ( cert->dbEntry == NULL ) { - ret = SECSuccess; /* not in permanent database */ - goto done; - } - - entry = cert->dbEntry; - entry->trust = *trust; - - rv = WriteDBCertEntry(handle, entry); - if ( rv ) { - ret = SECFailure; - goto done; - } - - ret = SECSuccess; - -done: - CERT_UnlockCertTrust(cert); - CERT_UnlockDB(handle); - return(ret); -} - - -SECStatus -CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, - CERTCertTrust *trust) -{ - char *oldnn; - certDBEntryCert *entry; - SECStatus rv; - PRBool conflict; - SECStatus ret; - - PORT_Assert(cert->dbhandle); - - CERT_LockDB(cert->dbhandle); - - PORT_Assert(cert->istemp); - PORT_Assert(!cert->isperm); - PORT_Assert(!cert->dbEntry); - - /* don't add a conflicting nickname */ - conflict = SEC_CertNicknameConflict(nickname, &cert->derSubject, - cert->dbhandle); - if ( conflict ) { - ret = SECFailure; - goto done; - } - - /* save old nickname so that we can delete it */ - oldnn = cert->nickname; - - entry = AddCertToPermDB(cert->dbhandle, cert, nickname, trust); - - if ( entry == NULL ) { - ret = SECFailure; - goto done; - } - - cert->nickname = (entry->nickname) ? PORT_ArenaStrdup(cert->arena,entry->nickname) : NULL; - cert->trust = &entry->trust; - cert->isperm = PR_TRUE; - cert->dbEntry = entry; - - if ( nickname && oldnn && ( PORT_Strcmp(nickname, oldnn) != 0 ) ) { - /* only delete the old one if they are not the same */ - /* delete old nickname from temp database */ - rv = SEC_DeleteTempNickname(cert->dbhandle, oldnn); - if ( rv != SECSuccess ) { - /* do we care?? */ - } - } - /* add new nickname to temp database */ - if ( cert->nickname ) { - rv = SEC_AddTempNickname(cert->dbhandle, cert->nickname, - &cert->derSubject); - if ( rv != SECSuccess ) { - ret = SECFailure; - goto done; - } - } - - ret = SECSuccess; -done: - CERT_UnlockDB(cert->dbhandle); - return(ret); -} - -/* - * Open the certificate database and index databases. Create them if - * they are not there or bad. - */ -SECStatus -CERT_OpenCertDB(CERTCertDBHandle *handle, PRBool readOnly, - CERTDBNameFunc namecb, void *cbarg) -{ - int rv; - - certdb_InitDBLock(); - - handle->dbMon = PR_NewMonitor(); - PORT_Assert(handle->dbMon != NULL); - - handle->spkDigestInfo = NULL; - handle->statusConfig = NULL; - - /* - * Open the memory resident decoded cert database. - */ - handle->tempCertDB = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 ); - if ( !handle->tempCertDB ) { - goto loser; - } - - rv = SEC_OpenPermCertDB(handle, readOnly, namecb, cbarg); - if ( rv ) { - goto loser; - } - - return (SECSuccess); - -loser: - - PORT_SetError(SEC_ERROR_BAD_DATABASE); - - if ( handle->tempCertDB ) { - certdb_Close(handle->tempCertDB); - handle->tempCertDB = 0; - } - - return(SECFailure); -} - -static char * -certDBFilenameCallback(void *arg, int dbVersion) -{ - return((char *)arg); -} - -SECStatus -CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname, - PRBool readOnly) -{ - return(CERT_OpenCertDB(handle, readOnly, certDBFilenameCallback, - (void *)certdbname)); -} - -/* - * Add a nickname to the temp database - */ -SECStatus -SEC_AddTempNickname(CERTCertDBHandle *handle, char *nickname, - SECItem *subjectName) -{ - DBT namekey; - int ret; - SECItem nameitem; - SECStatus rv; - DBT keydata; - PRArenaPool *arena = NULL; - SECItem tmpitem; - - PORT_Assert(nickname != NULL); - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - rv = EncodeDBNicknameKey(nickname, arena, &nameitem); - if ( rv != SECSuccess ) { - goto loser; - } - - namekey.data = nameitem.data; - namekey.size = nameitem.len; - - /* see if an entry already exists */ - ret = certdb_Get(handle->tempCertDB, &namekey, &keydata, 0); - - if ( ret == 0 ) { - /* found in temp database */ - tmpitem.data = (unsigned char*)keydata.data; - tmpitem.len = keydata.size; - - if ( SECITEM_CompareItem(subjectName, &tmpitem) == SECEqual ) { - /* same subject name */ - goto done; - } else { - /* different subject name is an error */ - goto loser; - } - } - - keydata.data = subjectName->data; - keydata.size = subjectName->len; - - /* put into temp byname index */ - ret = certdb_Put(handle->tempCertDB, &namekey, &keydata, R_NOOVERWRITE); - - if ( ret ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - -done: - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - return(SECFailure); -} - -SECStatus -SEC_DeleteTempNickname(CERTCertDBHandle *handle, char *nickname) -{ - DBT namekey; - SECStatus rv; - PRArenaPool *arena = NULL; - SECItem nameitem; - int ret; - - PORT_Assert(nickname != NULL); - if ( nickname == NULL ) { - return(SECSuccess); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* format a database key based on the nickname */ - if ( nickname ) { - rv = EncodeDBNicknameKey(nickname, arena, &nameitem); - if ( rv != SECSuccess ) { - goto loser; - } - - namekey.data = nameitem.data; - namekey.size = nameitem.len; - - ret = certdb_Del(handle->tempCertDB, &namekey, 0); - if ( ret ) { - goto loser; - } - } - - PORT_FreeArena(arena, PR_FALSE); - - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - return(SECFailure); -} - -/* - * Decode a certificate and enter it into the temporary certificate database. - * Deal with nicknames correctly - * - * nickname is only used if isperm == PR_TRUE - * - * This is the private entry point, and locking is optional - */ -static CERTCertificate * -NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, char *nickname, - PRBool isperm, PRBool copyDER, PRBool lockdb) - -{ - DBT key; - DBT data; - int status; - CERTCertificate *cert = NULL; - PRBool promoteError = PR_TRUE; - PRArenaPool *arena = NULL; - SECItem keyitem; - SECStatus rv; - - if ( isperm == PR_FALSE ) { - cert = CERT_FindCertByDERCert(handle, derCert); - if ( cert ) { - return(cert); - } - - nickname = NULL; - } - - if ( lockdb ) { - CERT_LockDB(handle); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - cert = CERT_DecodeDERCertificate(derCert, copyDER, nickname ); - - if ( cert == NULL ) { - /* We want to save the decoding error here */ - promoteError = PR_FALSE; - goto loser; - } - - cert->dbhandle = handle; - - /* only save pointer to cert in database */ - data.data = &cert; - data.size = sizeof(cert); - - /* if this is a perm cert, then it is already in the subject db */ - if ( isperm == PR_FALSE ) { - /* enter into the subject index */ - rv = AddTempCertToSubjectList(cert); - if ( rv != SECSuccess ) { - goto loser; - } - /* - * Since it's not a perm cert, add it to the key hash lookup; if it - * is permanent it will either already be there or will get put there - * later along with the rest of the perm certs. A failure of the - * addition does not seem to warrant failing this whole function, - * so we intentionally ignore the returned status. - */ - (void) AddCertToSPKDigestTable(handle, cert); - } else { - cert->subjectList = FindSubjectList(cert->dbhandle, &cert->derSubject, - PR_FALSE); - } - - rv = EncodeDBCertKey(&cert->certKey, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - key.data = keyitem.data; - key.size = keyitem.len; - - /* enter into main db */ - status = certdb_Put(handle->tempCertDB, &key, &data, R_NOOVERWRITE); - if ( status ) { - goto loser; - } - - if ( cert->nickname ) { - status = SEC_AddTempNickname(handle, cert->nickname, - &cert->derSubject); - if ( status ) { - promoteError = PR_FALSE; - goto loser; - } - } - - cert->isperm = isperm; - cert->istemp = PR_TRUE; - - PORT_FreeArena(arena, PR_FALSE); - - if ( lockdb ) { - CERT_UnlockDB(handle); - } - - return(cert); - -loser: - if ( cert ) { - CERT_DestroyCertificateNoLocking(cert); - } - - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - if ( promoteError ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - } - - if ( lockdb ) { - CERT_UnlockDB(handle); - } - - return(0); -} - -/* - * Decode a certificate and enter it into the temporary certificate database. - * Deal with nicknames correctly - * - * nickname is only used if isperm == PR_TRUE - * - * This is the public entry point and does locking. - */ -CERTCertificate * -CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER) -{ - return( NewTempCertificate(handle, derCert, nickname, isperm, copyDER, - PR_TRUE) ); -} - -/* - * Decode a permanent certificate and enter it into the temporary certificate - * database. - */ -static CERTCertificate * -SEC_AddPermCertToTemp(CERTCertDBHandle *handle, certDBEntryCert *entry) -{ - CERTCertificate *cert; - - /* we already hold the lock */ - cert = NewTempCertificate(handle, &entry->derCert, entry->nickname, - PR_TRUE, PR_TRUE, PR_FALSE); - if ( !cert ) { - return(0); - } - - cert->dbEntry = entry; - - cert->trust = &entry->trust; - - return(cert); -} - -SECStatus -CERT_DeleteTempCertificate(CERTCertificate *cert) -{ - SECStatus rv; - DBT nameKey; - CERTCertDBHandle *handle; - SECItem keyitem; - PRArenaPool *arena; - int ret; - - handle = cert->dbhandle; - - if ( !cert->istemp ) { - return(SECSuccess); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - if (cert->slot) { - PK11_FreeSlot(cert->slot); - cert->slot = NULL; - cert->pkcs11ID = CK_INVALID_KEY; - } - - /* delete from subject list (also takes care of nickname) */ - rv = RemoveTempCertFromSubjectList(cert); - if ( rv != SECSuccess ) { - goto loser; - } - - if ( !cert->isperm ) { - /* - * Remove the cert from the subject public key digest table, - * though we do not care if the removal fails (perhaps meaning - * the cert wasn't even there). - */ - (void) RemoveCertFromSPKDigestTable(handle, cert); - } - - rv = EncodeDBCertKey(&cert->certKey, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - nameKey.data = keyitem.data; - nameKey.size = keyitem.len; - /* delete the cert */ - ret = certdb_Del(handle->tempCertDB, &nameKey, 0); - if ( ret ) { - goto loser; - } - - cert->istemp = PR_FALSE; - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Lookup a certificate in the databases. - */ -static CERTCertificate * -FindCertByKey(CERTCertDBHandle *handle, SECItem *certKey, PRBool lockdb) -{ - DBT tmpdata; - int ret; - SECItem keyitem; - DBT key; - SECStatus rv; - CERTCertificate *cert = NULL; - PRArenaPool *arena = NULL; - certDBEntryCert *entry; - PRBool locked = PR_FALSE; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBCertKey(certKey, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - key.data = keyitem.data; - key.size = keyitem.len; - - if ( lockdb ) { - locked = PR_TRUE; - CERT_LockDB(handle); - } - - /* lookup in the temporary database */ - ret = certdb_Get( handle->tempCertDB, &key, &tmpdata, 0 ); - - /* error accessing the database */ - if ( ret < 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - if ( ret == 0 ) { /* found in temp database */ - if ( tmpdata.size != sizeof(CERTCertificate *) ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - PORT_Memcpy(&cert, tmpdata.data, tmpdata.size); - CERT_LockCertRefCount(cert); - cert->referenceCount++; - CERT_UnlockCertRefCount(cert); - } - if ( ret != 0 ) { - /* not found in temporary database */ - - /* find in perm database */ - entry = SEC_FindPermCertByKey(handle, certKey); - - if ( entry == NULL ) { - goto loser; - } - - cert = SEC_AddPermCertToTemp(handle, entry); - } - -loser: - if ( locked ) { - CERT_UnlockDB(handle); - } - - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(cert); -} - -/* - * Lookup a certificate in the databases, with locking - */ -CERTCertificate * -CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *certKey) -{ - return(FindCertByKey(handle, certKey, PR_TRUE)); -} - -/* - * Lookup a certificate in the databases without locking - */ -CERTCertificate * -CERT_FindCertByKeyNoLocking(CERTCertDBHandle *handle, SECItem *certKey) -{ - return(FindCertByKey(handle, certKey, PR_FALSE)); -} - -/* - * Generate a key from an issuerAndSerialNumber, and find the - * associated cert in the database. - */ -CERTCertificate * -CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN) -{ - SECItem certKey; - CERTCertificate *cert; - - certKey.len = issuerAndSN->serialNumber.len + issuerAndSN->derIssuer.len; - certKey.data = (unsigned char*)PORT_Alloc(certKey.len); - - if ( certKey.data == NULL ) { - return(0); - } - - /* copy the serialNumber */ - PORT_Memcpy(certKey.data, issuerAndSN->serialNumber.data, - issuerAndSN->serialNumber.len); - - /* copy the issuer */ - PORT_Memcpy( &certKey.data[issuerAndSN->serialNumber.len], - issuerAndSN->derIssuer.data, issuerAndSN->derIssuer.len); - - cert = CERT_FindCertByKey(handle, &certKey); - - PORT_Free(certKey.data); - - return(cert); -} - -/* - * Lookup a certificate in the database by name - */ -CERTCertificate * -CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name) -{ - CERTCertificate *cert = NULL; - CERTSubjectList *subjectList; - - CERT_LockDB(handle); - - subjectList = FindSubjectList(handle, name, PR_FALSE); - - if ( subjectList ) { - PORT_Assert(subjectList->head); - cert = CERT_FindCertByKeyNoLocking(handle, - &subjectList->head->certKey); - } - - CERT_UnlockDB(handle); - - return(cert); -} - -/* - * Lookup a certificate in the database by name and key ID - */ -CERTCertificate * -CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID) -{ - CERTCertificate *cert = NULL; - CERTSubjectList *subjectList; - CERTSubjectNode *node; - - CERT_LockDB(handle); - - /* find the list of certs for the given subject */ - subjectList = FindSubjectList(handle, name, PR_FALSE); - - if ( subjectList ) { - PORT_Assert(subjectList->head); - node = subjectList->head; - - /* walk through the certs until we find one with a matching key ID */ - while ( node ) { - if ( SECITEM_CompareItem(keyID, &node->keyID) == SECEqual ) { - cert = CERT_FindCertByKeyNoLocking(handle, &node->certKey); - break; - } - node = node->next; - } - } - - CERT_UnlockDB(handle); - - return(cert); -} - -/* - * look up a cert by its nickname string - */ -CERTCertificate * -CERT_FindCertByNickname(CERTCertDBHandle *handle, char *nickname) -{ - DBT tmpdata; - DBT namekey; - CERTCertificate *cert; - SECStatus rv; - int ret; - SECItem keyitem; - PRArenaPool *arena = NULL; - certDBEntryCert *entry; - - PORT_Assert(nickname != NULL); - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBNicknameKey(nickname, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - namekey.data = keyitem.data; - namekey.size = keyitem.len; - - /* lookup in the temporary database */ - ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0); - - /* error accessing the database */ - if ( ret < 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - if ( ret == 0 ) { /* found in temp database */ - SECItem nameitem; - - nameitem.len = tmpdata.size; - nameitem.data = (unsigned char *)PORT_Alloc(tmpdata.size); - if ( nameitem.data == NULL ) { - goto loser; - } - PORT_Memcpy(nameitem.data, tmpdata.data, nameitem.len); - cert = CERT_FindCertByName(handle, &nameitem); - PORT_Free(nameitem.data); - } else { /* not found in temporary database */ - - CERT_LockDB(handle); - - entry = SEC_FindPermCertByNickname(handle, nickname); - - if ( entry == NULL ) { - CERT_UnlockDB(handle); - goto loser; - } - - cert = SEC_AddPermCertToTemp(handle, entry); - CERT_UnlockDB(handle); - } - - PORT_FreeArena(arena, PR_FALSE); - - return(cert); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(0); -} - -/* - * look for the given DER certificate in the database - */ -CERTCertificate * -CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert) -{ - PRArenaPool *arena; - SECItem certKey; - SECStatus rv; - CERTCertificate *cert = NULL; - - /* create a scratch arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return(NULL); - } - - /* extract the database key from the cert */ - rv = CERT_KeyFromDERCert(arena, derCert, &certKey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* find the certificate */ - cert = CERT_FindCertByKey(handle, &certKey); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(cert); -} - -/* - * The following is bunch of types and code to allow looking up a certificate - * by a hash of its subject public key. Because the words "hash" and "key" - * are overloaded and thus terribly confusing, I tried to disambiguate things. - * - Where I could, I used "digest" instead of "hash" when referring to - * hashing of the subject public key. The PLHashTable interfaces and - * our own HASH_Foo interfaces had to be left as is, obviously. The latter - * should be thought of as "digest" in this case. - * - There are three keys in use here -- the subject public key, the key - * used to do a lookup in the PLHashTable, and the key used to do a lookup - * in the cert database. As the latter is a fairly pervasive interface, - * I left it alone. The other two uses I changed to "spk" or "SPK" when - * referring to the subject public key, and "index" when referring to the - * key into the PLHashTable. - */ - -typedef struct SPKDigestInfoStr { - PLHashTable *table; - PRBool permPopulated; -} SPKDigestInfo; - -/* - * Since the key hash information is "hidden" (in a void pointer in the handle) - * these macros with the appropriate casts make it easy to get at the parts. - */ -#define SPK_DIGEST_TABLE(handle) \ - (((SPKDigestInfo *)(handle->spkDigestInfo))->table) - -/* -** Hash allocator ops for the SPKDigest hash table. The rules are: -** + The index and value fields are "owned" by the hash table, and are -** freed when the table entry is deleted. -** + Replacing a value in the table is not allowed, since the caller can't -** tell whether the index field was used or not, resulting in a memory -** leak. (This is a bug in the PL_Hash routines. -*/ -static void * PR_CALLBACK -spkAllocTable(void *pool, PRSize size) -{ -#if defined(XP_MAC) -#pragma unused (pool) -#endif - - return PR_MALLOC(size); -} - -static void PR_CALLBACK -spkFreeTable(void *pool, void *item) -{ -#if defined(XP_MAC) -#pragma unused (pool) -#endif - - PR_Free(item); -} - -/* NOTE: the key argument here appears to be useless, since the RawAdd - * routine in PL_Hash just uses the original anyway. - */ -static PLHashEntry * PR_CALLBACK -spkAllocEntry(void *pool, const void *key) -{ -#if defined(XP_MAC) -#pragma unused (pool,key) -#endif - - return PR_NEW(PLHashEntry); -} - -static void PR_CALLBACK -spkFreeEntry(void *pool, PLHashEntry *he, PRUintn flag) -{ -#if defined(XP_MAC) -#pragma unused (pool) -#endif - - SECItem *value = (SECItem *)he->value; - - /* The flag should always be to free the whole entry. Otherwise the - * index field gets leaked because the caller can't tell whether - * the "new" value (which is the same as the old) was used or not. - */ - PORT_Assert(flag == HT_FREE_ENTRY); - - /* We always free the value */ - SECITEM_FreeItem(value, PR_TRUE); - - if (flag == HT_FREE_ENTRY) - { - /* Comes from BTOA, is this the right free call? */ - PORT_Free((char *)he->key); - PR_Free(he); - } -} - -static PLHashAllocOps spkHashAllocOps = { - spkAllocTable, spkFreeTable, - spkAllocEntry, spkFreeEntry -}; - - -/* - * Create the key hash lookup table. Note that the table, and the - * structure which holds it and a little more information, is never freed. - * This is because the temporary database is never actually closed out, - * so there is no safe/obvious place to free the whole thing. - * - * The database must be locked already. - */ -static SECStatus -InitDBspkDigestInfo(CERTCertDBHandle *handle) -{ - SPKDigestInfo *spkDigestInfo; - PLHashTable *table; - - PORT_Assert(handle != NULL); - PORT_Assert(handle->spkDigestInfo == NULL); - - spkDigestInfo = PORT_ZAlloc(sizeof(SPKDigestInfo)); - if ( spkDigestInfo == NULL ) { - return(SECFailure); - } - - table = PL_NewHashTable(128, PL_HashString, PL_CompareStrings, - (PLHashComparator) SECITEM_ItemsAreEqual, - &spkHashAllocOps, NULL); - if ( table == NULL ) { - PORT_Free(spkDigestInfo); - return(SECFailure); - } - - spkDigestInfo->table = table; - handle->spkDigestInfo = spkDigestInfo; - return(SECSuccess); -} - -static SECHashObject * -OidTagToRawDigestObject(SECOidTag digestAlg) -{ - SECHashObject *rawDigestObject; - - switch (digestAlg) { - case SEC_OID_MD2: - rawDigestObject = &SECRawHashObjects[HASH_AlgMD2]; - break; - case SEC_OID_MD5: - rawDigestObject = &SECRawHashObjects[HASH_AlgMD5]; - break; - case SEC_OID_SHA1: - rawDigestObject = &SECRawHashObjects[HASH_AlgSHA1]; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rawDigestObject = NULL; - break; - } - return(rawDigestObject); -} - -/* - * Digest the cert's subject public key using the specified algorithm. - * The necessary storage for the digest data is allocated. If "fill" is - * non-null, the data is put there, otherwise a SECItem is allocated. - * Allocation from "arena" if it is non-null, heap otherwise. Any problem - * results in a NULL being returned (and an appropriate error set). - */ -SECItem * -CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert, - SECOidTag digestAlg, SECItem *fill) -{ - SECHashObject *digestObject; - void *digestContext; - SECItem *result = NULL; - void *mark = NULL; - SECItem spk; - - if ( arena != NULL ) { - mark = PORT_ArenaMark(arena); - } - - /* - * This can end up being called before PKCS #11 is initialized, - * so we have to use the raw digest functions. - */ - digestObject = OidTagToRawDigestObject(digestAlg); - if ( digestObject == NULL ) { - goto loser; - } - - result = SECITEM_AllocItem(arena, fill, digestObject->length); - if ( result == NULL ) { - goto loser; - } - - /* - * Copy just the length and data pointer (nothing needs to be freed) - * of the subject public key so we can convert the length from bits - * to bytes, which is what the digest function expects. - */ - spk = cert->subjectPublicKeyInfo.subjectPublicKey; - DER_ConvertBitString(&spk); - - /* - * Now digest the value, using the specified algorithm. - */ - digestContext = digestObject->create(); - if ( digestContext == NULL ) { - goto loser; - } - digestObject->begin(digestContext); - digestObject->update(digestContext, spk.data, spk.len); - digestObject->end(digestContext, result->data, &(result->len), result->len); - digestObject->destroy(digestContext, PR_TRUE); - - if ( arena != NULL ) { - PORT_ArenaUnmark(arena, mark); - } - return(result); - -loser: - if ( arena != NULL ) { - PORT_ArenaRelease(arena, mark); - } else { - if ( result != NULL ) { - SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE); - } - } - return(NULL); -} - -/* - * Return the index for the spk digest lookup table for "spkDigest". - * - * Caller is responsible for freeing the returned string. - */ -static char * -spkDigestIndexFromDigest(SECItem *spkDigest) -{ - return BTOA_ConvertItemToAscii(spkDigest); -} - -/* - * Return the index for the spk digest lookup table for this certificate, - * based on the specified digest algorithm. - * - * Caller is responsible for freeing the returned string. - */ -static char * -spkDigestIndexFromCert(CERTCertificate *cert, SECOidTag digestAlg) -{ - SECItem *spkDigest; - char *index; - - spkDigest = CERT_SPKDigestValueForCert(NULL, cert, digestAlg, NULL); - if ( spkDigest == NULL ) - return(NULL); - - index = spkDigestIndexFromDigest(spkDigest); - - SECITEM_FreeItem(spkDigest, PR_TRUE); - - return(index); -} - -/* - * Remove the spk digest for the given cert from the spk digest table, - * based on the given digest algorithm. - * - * The database must be locked already. - */ -static SECStatus -RemoveCertFromSPKDigestTableForAlg(CERTCertDBHandle *handle, - CERTCertificate *cert, SECOidTag digestAlg) -{ - SECStatus rv = SECSuccess; - char *index = NULL; - PLHashTable *table; - - /* Expect to only be called if there is a table to work with. */ - PORT_Assert(handle->spkDigestInfo != NULL); - - table = SPK_DIGEST_TABLE(handle); - PORT_Assert(table != NULL); - - index = spkDigestIndexFromCert(cert, digestAlg); - if ( index == NULL ) { - rv = SECFailure; - goto done; - } - - if ( PL_HashTableRemove(table, index) != PR_TRUE ) { - /* not found means nothing to remove, which is fine */ - } - -done: - if ( index != NULL ) { - PORT_Free(index); - } - return(rv); -} - -/* - * Remove the spk digests for the given cert from the spk digest table, - * for all known digest algorithms. - * - * The database must be locked already. - */ -static SECStatus -RemoveCertFromSPKDigestTable(CERTCertDBHandle *handle, CERTCertificate *cert) -{ - /* - * If no certs have been added yet, then nothing to do. - */ - if ( handle->spkDigestInfo == NULL ) { - return(SECSuccess); - } - - (void) RemoveCertFromSPKDigestTableForAlg(handle, cert, SEC_OID_MD2); - (void) RemoveCertFromSPKDigestTableForAlg(handle, cert, SEC_OID_MD5); - return RemoveCertFromSPKDigestTableForAlg(handle, cert, SEC_OID_SHA1); -} - -/* - * Add the spk digest for the given cert to the spk digest table, - * based on the given digest algorithm. - * - * If a cert for the same spk digest is already in the table, choose whichever - * cert is "newer". (The other cert cannot be found via spk digest.) - * - * The database must be locked already. - * - * XXX Note that this implementation results in leaking the index value. - * Fixing that did not seem worth the trouble, given we will only leak - * once per cert. This whole thing should be done differently in the - * new rewrite (Stan), and then the problem will go away. - */ -static SECStatus -AddCertToSPKDigestTableForAlg(CERTCertDBHandle *handle, CERTCertificate *cert, - SECItem *certDBKey, SECOidTag digestAlg) -{ - SECStatus rv = SECFailure; - SECItem *oldCertDBKey; - PRBool addit = PR_TRUE; - CERTCertificate *oldCert = NULL; - char *index = NULL; - PLHashTable *table; - - /* - * After running some testing doing key hash lookups (like using OCSP), - * if these are never hit, they can probably be removed. - */ - PORT_Assert(handle != NULL); - PORT_Assert(handle == cert->dbhandle); - PORT_Assert(handle->spkDigestInfo != NULL); - PORT_Assert((certDBKey == &cert->certKey) - || (SECITEM_CompareItem(certDBKey, - &cert->certKey) == SECEqual)); - - table = SPK_DIGEST_TABLE(handle); - PORT_Assert(table != NULL); - - index = spkDigestIndexFromCert(cert, digestAlg); - if ( index == NULL ) { - goto loser; - } - - /* - * See if this cert's spk digest is already in the table. - */ - oldCertDBKey = PL_HashTableLookup(table, index); - if ( oldCertDBKey != NULL ) { - /* - * The spk digest *is* already in the table. We need to find that - * cert and see -- if it is the same, then we can just leave as is. - * Otherwise we have to choose which cert we want represented; - * in that case the best plan I can think of is to hang onto the - * most recent one. - */ - oldCert = CERT_FindCertByKey(handle, oldCertDBKey); - if ( oldCert != NULL ) { - if ( cert == oldCert ) { - /* They are the same cert, so we are done. */ - addit = PR_FALSE; - } else if ( CERT_IsNewer(cert, oldCert) ) { - if ( PL_HashTableRemove(table, index) != PR_TRUE ) { - goto loser; - } - } else { - /* oldCert is "newer", so we are done. */ - addit = PR_FALSE; - } - } - } - - if ( addit ) { - certDBKey = SECITEM_DupItem(certDBKey); - if ( certDBKey == NULL ) { - goto loser; - } - if ( PL_HashTableAdd(table, index, certDBKey) == NULL ) { - SECITEM_FreeItem(certDBKey, PR_TRUE); - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - index = NULL; /* don't want to free it */ - } - - rv = SECSuccess; - -loser: - if ( index != NULL ) { - PORT_Free(index); - } - if ( oldCert != NULL ) { - CERT_DestroyCertificate(oldCert); - } - return(rv); -} - -/* - * Add the spk digest for the given cert to the spk digest table, - * for all known digest algorithms. - * - * The database must be locked already, and the digest table already created. - */ -static SECStatus -AddCertToSPKDigestTableForAllAlgs(CERTCertDBHandle *handle, - CERTCertificate *cert, SECItem *certDBKey) -{ - (void) AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_MD2); - (void) AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_MD5); - return AddCertToSPKDigestTableForAlg(handle, cert, certDBKey, SEC_OID_SHA1); -} - -/* - * Add the spk digests for the given cert to the spk digest table, - * for all known digest algorithms. (This function is called when a - * new cert is added to the temporary database.) - * - * If the spk digest table does not yet exist, create it. - * - * In an ideal world, we would not hardwire the digest algorithms. - * But it is the case that we do not currently support any digest - * algorithms outside of these three. In the newer, cleaned-up world, - * this may be done differently. - * - * The database must be locked already. - */ -static SECStatus -AddCertToSPKDigestTable(CERTCertDBHandle *handle, CERTCertificate *cert) -{ - SECStatus rv; - - if ( handle->spkDigestInfo == NULL ) { - rv = InitDBspkDigestInfo(handle); - if ( rv != SECSuccess ) { - return(rv); - } - } - - return AddCertToSPKDigestTableForAllAlgs(handle, cert, &cert->certKey); -} - -/* - * Add the spk digest for the given cert to the spk digest table, - * for all known digest algorithms. This function is called while - * traversing all of the certs in the permanent database -- since - * that imposes some constraints on its arguments this routine is a - * simple cover for the "real" interface. - * - * The database must be locked already, and the digest table already created. - */ -static SECStatus -AddCertToSPKDigestTableInTraversal(CERTCertificate *cert, SECItem *certDBKey, - void *data) -{ - CERTCertDBHandle *handle = data; - - return AddCertToSPKDigestTableForAllAlgs(handle, cert, certDBKey); -} - -/* - * Add the spk digests for the all permanent certs to the spk digest table, - * for all known digest algorithms. - * - * This locks the database, and then checks to make sure that the work - * actually needs to get done. - * - * If the spk digest table does not yet exist, it is created. - */ -static SECStatus -PopulateSPKDigestTable(CERTCertDBHandle *handle) -{ - SPKDigestInfo *spkDigestInfo; - SECStatus rv = SECSuccess; - - CERT_LockDB(handle); - - spkDigestInfo = handle->spkDigestInfo; - if ( spkDigestInfo == NULL ) { - rv = InitDBspkDigestInfo(handle); - if ( rv != SECSuccess ) { - return(rv); - } - spkDigestInfo = handle->spkDigestInfo; - PORT_Assert(spkDigestInfo != NULL); - } else { - /* - * Check to see if someone already did it; it is important to do - * this after getting the lock. - */ - if ( spkDigestInfo->permPopulated == PR_TRUE ) { - goto done; - } - } - - rv = TraversePermCertsNoLocking(handle, AddCertToSPKDigestTableInTraversal, - handle); - - if ( rv != SECSuccess ) { - goto done; - } - - spkDigestInfo->permPopulated = PR_TRUE; - -done: - CERT_UnlockDB(handle); - - return(rv); -} - -/* - * Lookup a certificate by a digest of a subject public key. If it is - * found, it is returned (and must then be destroyed by the caller). - * NULL is returned otherwise -- if there was a problem performing the - * lookup, an appropriate error is set (e.g. SEC_ERROR_NO_MEMORY); - * if the cert simply was not found, the error is SEC_ERROR_UNKNOWN_CERT. - * - * If the lookup table has not yet been created or populated, do that first. - */ -CERTCertificate * -CERT_FindCertBySPKDigest(CERTCertDBHandle *handle, SECItem *spkDigest) -{ - SPKDigestInfo *spkDigestInfo; - char *index = NULL; - SECItem *certDBKey; - CERTCertificate *cert = NULL; - - PORT_Assert(handle != NULL); - spkDigestInfo = handle->spkDigestInfo; - - if ( spkDigestInfo == NULL || spkDigestInfo->permPopulated != PR_TRUE ) { - if ( PopulateSPKDigestTable(handle) != SECSuccess ) { - goto loser; - } - } - - index = spkDigestIndexFromDigest(spkDigest); - if ( index == NULL ) { - goto loser; - } - - certDBKey = PL_HashTableLookup(SPK_DIGEST_TABLE(handle), index); - if ( certDBKey != NULL ) { - cert = CERT_FindCertByKey(handle, certDBKey); - } - - if ( cert == NULL ) { - PORT_SetError(SEC_ERROR_UNKNOWN_CERT); - } - -loser: - if ( index != NULL ) { - PORT_Free(index); - } - return(cert); -} - -static void -DestroyCertificate(CERTCertificate *cert, PRBool lockdb) -{ - int refCount; - CERTCertDBHandle *handle; - - if ( cert ) { - - handle = cert->dbhandle; - - /* - * handle may be NULL, for example if the cert was created with - * CERT_DecodeDERCertificate. - */ - if ( lockdb && handle ) { - CERT_LockDB(handle); - } - - CERT_LockCertRefCount(cert); - PORT_Assert(cert->referenceCount > 0); - refCount = --cert->referenceCount; - CERT_UnlockCertRefCount(cert); - - if ( ( refCount == 0 ) && !cert->keepSession ) { - certDBEntryCert *entry = cert->dbEntry; - PRArenaPool * arena = cert->arena; - - if ( cert->istemp ) { - CERT_DeleteTempCertificate(cert); - } - - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - - /* zero cert before freeing. Any stale references to this cert - * after this point will probably cause an exception. */ - PORT_Memset(cert, 0, sizeof *cert); - - cert = NULL; - - /* free the arena that contains the cert. */ - PORT_FreeArena(arena, PR_FALSE); - } - if ( lockdb && handle ) { - CERT_UnlockDB(handle); - } - } - - return; -} - -void -CERT_DestroyCertificate(CERTCertificate *cert) -{ - DestroyCertificate(cert, PR_TRUE); - return; -} - -void -CERT_DestroyCertificateNoLocking(CERTCertificate *cert) -{ - DestroyCertificate(cert, PR_FALSE); - return; -} - -/* - * cache a CRL from the permanent database into the temporary database - */ -CERTSignedCrl * -SEC_AddPermCrlToTemp(CERTCertDBHandle *handle, certDBEntryRevocation *entry) -{ - CERTSignedCrl *crl = NULL; - DBT key; - DBT data; - int status; - PRArenaPool *arena = NULL; - SECItem keyitem; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - crl = CERT_DecodeDERCrl(NULL, &entry->derCrl, - entry->common.type == certDBEntryTypeRevocation ? - SEC_CRL_TYPE : SEC_KRL_TYPE); - - if ( crl == NULL ) { - goto loser; - } - - /* only save pointer to cert in database */ - data.data = &crl; - data.size = sizeof(crl); - - - rv = EncodeDBGenericKey(&(crl->crl.derName), arena, - &keyitem, entry->common.type); - if ( rv != SECSuccess ) { - goto loser; - } - - if (entry->url) { - int nnlen = PORT_Strlen(entry->url) + 1; - crl->url = (char *)PORT_ArenaAlloc(crl->arena, nnlen); - if ( !crl->url ) { - goto loser; - } - PORT_Memcpy(crl->url, entry->url, nnlen); - } else { - crl->url = NULL; - } - - key.data = keyitem.data; - key.size = keyitem.len; - - /* enter into main db */ - status = certdb_Put(handle->tempCertDB, &key, &data, R_NOOVERWRITE); - if ( status ) { - goto loser; - } - - crl->istemp = PR_TRUE; - crl->isperm = PR_TRUE; - crl->dbhandle = handle; - crl->dbEntry = entry; - - - PORT_FreeArena(arena, PR_FALSE); - - crl->keep = PR_TRUE; - return(crl); - -loser: - if ( crl ) { - SEC_DestroyCrl(crl); - } - - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(0); -} - -SECStatus -SEC_DeleteTempCrl(CERTSignedCrl *crl) -{ - SECStatus rv; - DBT nameKey; - CERTCertDBHandle *handle; - SECItem keyitem; - PRArenaPool *arena; - int ret; - - handle = crl->dbhandle; - - if ( !crl->istemp ) { - return(SECSuccess); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBGenericKey - (&crl->crl.derName, arena, &keyitem, crl->dbEntry->common.type); - if ( rv != SECSuccess ) { - goto loser; - } - - nameKey.data = keyitem.data; - nameKey.size = keyitem.len; - - /* delete the cert */ - ret = certdb_Del(handle->tempCertDB, &nameKey, 0); - if ( ret ) { - goto loser; - } - - crl->istemp = PR_FALSE; - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Lookup a CRL in the databases. We mirror the same fast caching data base - * caching stuff used by certificates....? - */ -CERTSignedCrl * -SEC_FindCrlByKey(CERTCertDBHandle *handle, SECItem *crlKey, int type) -{ - DBT tmpdata; - int ret; - SECItem keyitem; - DBT key; - SECStatus rv; - CERTSignedCrl *crl = NULL; - PRArenaPool *arena = NULL; - certDBEntryRevocation *entry; - certDBEntryType crlType = (type == SEC_CRL_TYPE) ? - certDBEntryTypeRevocation : certDBEntryTypeKeyRevocation; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBGenericKey(crlKey, arena, &keyitem, crlType); - if ( rv != SECSuccess ) { - goto loser; - } - - key.data = keyitem.data; - key.size = keyitem.len; - - /* lookup in the temporary database */ - ret = certdb_Get( handle->tempCertDB, &key, &tmpdata, 0 ); - - /* error accessing the database */ - if ( ret < 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - if ( ret == 0 ) { /* found in temp database */ - if ( tmpdata.size != sizeof(CERTSignedCrl *) ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - PORT_Memcpy(&crl, tmpdata.data, tmpdata.size); - crl->referenceCount++; - } else { /* not found in temporary database */ - - /* find in perm database */ - entry = ReadDBCrlEntry(handle, crlKey, crlType); - - if ( entry == NULL ) { - goto loser; - } - - crl = SEC_AddPermCrlToTemp(handle, entry); - } - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(crl); -} - - -CERTSignedCrl * -SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type) -{ - return SEC_FindCrlByKey(handle,crlKey,type); -} - -CERTSignedCrl * -SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type) -{ - PRArenaPool *arena; - SECItem crlKey; - SECStatus rv; - CERTSignedCrl *crl = NULL; - - /* create a scratch arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return(NULL); - } - - /* extract the database key from the cert */ - rv = CERT_KeyFromDERCrl(arena, derCrl, &crlKey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* find the crl */ - crl = SEC_FindCrlByKey(handle, &crlKey, type); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(crl); -} - - -SECStatus -SEC_DestroyCrl(CERTSignedCrl *crl) -{ - if (crl) { - if (crl->referenceCount-- <= 1) { - if (!crl->keep) { - SEC_DeleteTempCrl(crl); - if (crl->dbEntry) { - DestroyDBEntry((certDBEntry *)crl->dbEntry); - } - PORT_FreeArena(crl->arena, PR_FALSE); - } - } - } - return SECSuccess; -} - -CERTSignedCrl * -cert_DBInsertCRL (CERTCertDBHandle *handle, char *url, - CERTSignedCrl *newCrl, SECItem *derCrl, int type) -{ - CERTSignedCrl *oldCrl = NULL, *crl = NULL; - certDBEntryRevocation *entry = NULL; - PRArenaPool *arena = NULL; - SECCertTimeValidity validity; - certDBEntryType crlType = (type == SEC_CRL_TYPE) ? - certDBEntryTypeRevocation : certDBEntryTypeKeyRevocation; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) goto done; - - validity = SEC_CheckCrlTimes(&newCrl->crl,PR_Now()); - if ( validity == secCertTimeExpired) { - if (type == SEC_CRL_TYPE) { - PORT_SetError(SEC_ERROR_CRL_EXPIRED); - } else { - PORT_SetError(SEC_ERROR_KRL_EXPIRED); - } - goto done; - } else if (validity == secCertTimeNotValidYet) { - if (type == SEC_CRL_TYPE) { - PORT_SetError(SEC_ERROR_CRL_NOT_YET_VALID); - } else { - PORT_SetError(SEC_ERROR_KRL_NOT_YET_VALID); - } - goto done; - } - - oldCrl = SEC_FindCrlByKey(handle, &newCrl->crl.derName, type); - - /* if there is an old crl, make sure the one we are installing - * is newer. If not, exit out, otherwise delete the old crl. - */ - if (oldCrl != NULL) { - if (!SEC_CrlIsNewer(&newCrl->crl,&oldCrl->crl)) { - - if (type == SEC_CRL_TYPE) { - PORT_SetError(SEC_ERROR_OLD_CRL); - } else { - PORT_SetError(SEC_ERROR_OLD_KRL); - } - - goto done; - } - - if ((SECITEM_CompareItem(&newCrl->crl.derName, - &oldCrl->crl.derName) != SECEqual) && - (type == SEC_KRL_TYPE) ) { - - PORT_SetError(SEC_ERROR_CKL_CONFLICT); - goto done; - } - - /* if we have a url in the database, use that one */ - if (oldCrl->url) { - int nnlen = PORT_Strlen(oldCrl->url) + 1; - url = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( url != NULL ) { - PORT_Memcpy(url, oldCrl->url, nnlen); - } - } - - - /* really destroy this crl */ - /* first drum it out of the permanment Data base */ - SEC_DeletePermCRL(oldCrl); - /* then get rid of our reference to it... */ - SEC_DestroyCrl(oldCrl); - oldCrl = NULL; - - } - - /* Write the new entry into the data base */ - entry = NewDBCrlEntry(derCrl, url, crlType, 0); - if (entry == NULL) goto done; - - rv = WriteDBCrlEntry(handle, entry); - if (rv != SECSuccess) goto done; - - crl = SEC_AddPermCrlToTemp(handle, entry); - if (crl) entry = NULL; /*crl->dbEntry now points to entry data */ - crl->isperm = PR_TRUE; - -done: - if (entry) DestroyDBEntry((certDBEntry *)entry); - if (arena) PORT_FreeArena(arena, PR_FALSE); - if (oldCrl) SEC_DestroyCrl(oldCrl); - - return crl; -} - - -/* - * create a new CRL from DER material. - * - * The signature on this CRL must be checked before you - * load it. ??? - */ -CERTSignedCrl * -SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type) -{ - CERTSignedCrl *newCrl = NULL, *crl = NULL; - - /* make this decode dates! */ - newCrl = CERT_DecodeDERCrl(NULL, derCrl, type); - if (newCrl == NULL) { - if (type == SEC_CRL_TYPE) { - PORT_SetError(SEC_ERROR_CRL_INVALID); - } else { - PORT_SetError(SEC_ERROR_KRL_INVALID); - } - goto done; - } - - crl = cert_DBInsertCRL (handle, url, newCrl, derCrl, type); - - -done: - if (newCrl) PORT_FreeArena(newCrl->arena, PR_FALSE); - - return crl; -} - - -/* - * replace the existing URL in the data base with a new one - */ -SECStatus -SEC_CrlReplaceUrl(CERTSignedCrl *crl,char *url) { - SECStatus rv = SECFailure; - certDBEntryRevocation *entry = NULL; - int nnlen=0; - - SEC_DeletePermCRL(crl); - - /* Write the new entry into the data base */ - entry = NewDBCrlEntry(&crl->dbEntry->derCrl, url, crl->dbEntry->common.type, 0); - if (entry == NULL) goto done; - - rv = WriteDBCrlEntry(crl->dbhandle, entry); - if (rv != SECSuccess) goto done; - - if (url) { - nnlen = PORT_Strlen(url) + 1; - crl->url = (char *)PORT_ArenaAlloc(crl->arena, nnlen); - if ( !crl->url ) { - goto done; - } - PORT_Memcpy(crl->url, url, nnlen); - } else { - crl->url = NULL; - } -done: - return rv; -} - - -/* - * collect a linked list of CRL's - */ -static SECStatus CollectCrls(SECItem *dbdata, SECItem *dbkey, - certDBEntryType type, void *data) { - SECStatus rv; - certDBEntryRevocation entry; - SECItem entryitem; - PRArenaPool *arena = NULL; - CERTCrlHeadNode *head; - CERTCrlNode *new_node; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - head = (CERTCrlHeadNode *)data; - entry.common.version = (unsigned int)dbdata->data[0]; - entry.common.type = (certDBEntryType)dbdata->data[1]; - entry.common.flags = (unsigned int)dbdata->data[2]; - entry.common.arena = arena; - - entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN; - entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN]; - - rv = DecodeDBCrlEntry(&entry, &entryitem); - if (rv != SECSuccess ) { - goto loser; - } - - new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode)); - if (new_node == NULL) { - goto loser; - } - - new_node->type = (entry.common.type == certDBEntryTypeRevocation) ? - SEC_CRL_TYPE : SEC_KRL_TYPE; - new_node->crl=CERT_DecodeDERCrl(head->arena,&entry.derCrl,new_node->type); - - if (entry.url) { - int nnlen = PORT_Strlen(entry.url) + 1; - new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen); - if ( !new_node->crl->url ) { - goto loser; - } - PORT_Memcpy(new_node->crl->url, entry.url, nnlen); - } else { - new_node->crl->url = NULL; - } - - - new_node->next = NULL; - if (head->last) { - head->last->next = new_node; - head->last = new_node; - } else { - head->first = head->last = new_node; - } - return (SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - return(SECFailure); -} - - -SECStatus -SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type) -{ - CERTCrlHeadNode *head; - PRArenaPool *arena = NULL; - SECStatus rv; - - *nodes = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return SECFailure; - } - - /* build a head structure */ - head = (CERTCrlHeadNode *)PORT_ArenaAlloc(arena, sizeof(CERTCrlHeadNode)); - head->arena = arena; - head->first = NULL; - head->last = NULL; - head->dbhandle = handle; - - /* Look up the proper crl types */ - *nodes = head; - - CERT_LockDB(handle); - - switch (type) { - case SEC_CRL_TYPE: - rv = SEC_TraverseDBEntries(handle, certDBEntryTypeRevocation, - CollectCrls, (void *)head); - break; - case SEC_KRL_TYPE: - rv = SEC_TraverseDBEntries(handle, certDBEntryTypeKeyRevocation, - CollectCrls, (void *)head); - break; - case -1: - rv = SEC_TraverseDBEntries(handle, certDBEntryTypeKeyRevocation, - CollectCrls, (void *)head); - if (rv != SECSuccess) break; - rv = SEC_TraverseDBEntries(handle, certDBEntryTypeRevocation, - CollectCrls, (void *)head); - break; - default: - rv = SECFailure; - break; - } - - CERT_UnlockDB(handle); - - if (rv != SECSuccess) { - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - *nodes = NULL; - } - } - - return rv; -} - - -SECStatus -SEC_DeletePermCRL(CERTSignedCrl *crl) { - SECStatus rv; - - if (crl == NULL) { - return SECFailure; - } - - rv = DeleteDBCrlEntry(crl->dbhandle, &crl->crl.derName, - crl->dbEntry->common.type); - if (rv != SECSuccess) goto done; - - /* now force it to be freed when all the reference counts go */ - crl->keep = PR_FALSE; - /* force it out of the temporary data base */ - SEC_DeleteTempCrl(crl); - -done: - return rv; -} - -/* - * find a cert by email address - * - * pick one that is a valid recipient, meaning that it is an encryption - * cert. - * - */ -static CERTCertificate* -find_smime_recipient_cert(CERTCertDBHandle* handle, const char* email_addr) -{ - CERTCertificate* cert = NULL; - CERTCertList* certList = NULL; - SECStatus rv; - - certList = CERT_CreateEmailAddrCertList(NULL, handle, (char*)email_addr, - PR_Now(), PR_TRUE); - if (certList == NULL) { - return NULL; - } - - rv = CERT_FilterCertListByUsage(certList, certUsageEmailRecipient, - PR_FALSE); - - if (!CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) { - cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert); - } - - CERT_DestroyCertList(certList); - - return cert; /* cert may point to a cert or may be NULL */ -} - -/* - * This function has the logic that decides if another person's cert and - * email profile from an S/MIME message should be saved. It can deal with - * the case when there is no profile. - */ -SECStatus -CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, - SECItem *profileTime) -{ - certDBEntrySMime *entry = NULL, *oldentry = NULL; - int64 oldtime; - int64 newtime; - SECStatus rv; - CERTCertificate *oldcert = NULL; - PRBool saveit; - CERTCertTrust trust; - CERTCertTrust tmptrust; - char *emailAddr; - - emailAddr = cert->emailAddr; - - PORT_Assert(emailAddr); - if ( emailAddr == NULL ) { - goto loser; - } - - saveit = PR_FALSE; - - oldcert = find_smime_recipient_cert(cert->dbhandle, emailAddr); - if (oldcert) { - /* see if there is an entry already */ - oldentry = ReadDBSMimeEntry(cert->dbhandle, emailAddr); - } - - /* both profileTime and emailProfile have to exist or not exist */ - if ( emailProfile == NULL ) { - profileTime = NULL; - } else if ( profileTime == NULL ) { - emailProfile = NULL; - } - - if ( oldentry == NULL ) { - /* no old entry for this address */ - PORT_Assert(oldcert == NULL); - saveit = PR_TRUE; - } else { - /* there was already a profile for this email addr */ - if ( profileTime ) { - /* we have an old and new profile - save whichever is more recent*/ - if ( oldentry->optionsDate.len == 0 ) { - /* always replace if old entry doesn't have a time */ - oldtime = LL_MININT; - } else { - rv = DER_UTCTimeToTime(&oldtime, &oldentry->optionsDate); - if ( rv != SECSuccess ) { - goto loser; - } - } - - rv = DER_UTCTimeToTime(&newtime, profileTime); - if ( rv != SECSuccess ) { - goto loser; - } - - if ( LL_CMP(newtime, >, oldtime ) ) { - /* this is a newer profile, save it and cert */ - saveit = PR_TRUE; - } - } else { - /* we don't have a new profile or time */ - if ( oldentry->optionsDate.len == 0 ) { - /* the old entry doesn't have a time either, so compare certs*/ - if ( CERT_IsNewer(cert, oldcert) ) { - /* new cert is newer, use it instead */ - saveit = PR_TRUE; - } - } else { - if (oldcert) { - if (CERT_IsNewer(cert, oldcert)) { - saveit = PR_TRUE; - } - } else { - saveit = PR_TRUE; - } - } - } - } - - if ( saveit ) { - if ( oldcert && ( oldcert != cert ) ) { - /* old cert is different from new cert */ - if ( PORT_Memcmp(oldcert->trust, &trust, sizeof(trust)) == 0 ) { - /* old cert is only for e-mail, so delete it */ - SEC_DeletePermCertificate(oldcert); - } else { - /* old cert is for other things too, so just change trust */ - tmptrust = *oldcert->trust; - tmptrust.emailFlags &= ( ~CERTDB_VALID_PEER ); - rv = CERT_ChangeCertTrust(oldcert->dbhandle, oldcert, - &tmptrust); - if ( rv != SECSuccess ) { - goto loser; - } - } - } - -/* Subroutine */ - /* now save the entry */ - entry = NewDBSMimeEntry(emailAddr, &cert->derSubject, emailProfile, - profileTime, 0); - if ( entry == NULL ) { - goto loser; - } - - CERT_LockDB(cert->dbhandle); - - rv = DeleteDBSMimeEntry(cert->dbhandle, emailAddr); - /* if delete fails, try to write new entry anyway... */ - - rv = WriteDBSMimeEntry(cert->dbhandle, entry); - if ( rv != SECSuccess ) { - CERT_UnlockDB(cert->dbhandle); - goto loser; - } - - /* link subject entry back here */ - rv = UpdateSubjectWithEmailAddr(cert, emailAddr); - if ( rv != SECSuccess ) { - CERT_UnlockDB(cert->dbhandle); - goto loser; - } - - CERT_UnlockDB(cert->dbhandle); -/* End Subroutine */ - } - - rv = SECSuccess; - goto done; - -loser: - rv = SECFailure; - -done: - if ( oldcert ) { - CERT_DestroyCertificate(oldcert); - } - - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - if ( oldentry ) { - DestroyDBEntry((certDBEntry *)oldentry); - } - - return(rv); -} - -CERTCertificate * -CERT_FindCertByEmailAddr(CERTCertDBHandle *handle, char *emailAddr) -{ - certDBEntrySMime *entry; - CERTCertificate *cert = NULL; - - emailAddr = CERT_FixupEmailAddr(emailAddr); - if ( emailAddr == NULL ) { - return(NULL); - } - - entry = ReadDBSMimeEntry(handle, emailAddr); - - /* XXX - this will have to change when multiple certs per subject - * are allowed - */ - if ( entry != NULL ) { - cert = CERT_FindCertByName(handle, &entry->subjectName); - } - - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - - PORT_Free(emailAddr); - - return(cert); -} - -/* - * find the smime symmetric capabilities profile for a given cert - */ -SECItem * -CERT_FindSMimeProfile(CERTCertificate *cert) -{ - certDBEntrySMime *entry; - SECItem *retitem = NULL; - - PORT_Assert(cert->emailAddr != NULL); - - if ( cert->emailAddr == NULL ) { - return(NULL); - } - - entry = ReadDBSMimeEntry(cert->dbhandle, cert->emailAddr); - - if ( entry ) { - retitem = SECITEM_DupItem(&entry->smimeOptions); - DestroyDBEntry((certDBEntry *)entry); - } - - return(retitem); -} - -CERTCertificate * -CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, char *name) -{ - CERTCertificate *cert; - cert = CERT_FindCertByNickname(handle, name); - if ( cert == NULL ) { - cert = CERT_FindCertByEmailAddr(handle, name); - } - - return(cert); -} - -PRBool -CERT_IsCertRevoked(CERTCertificate *cert) -{ - return(PR_FALSE); -} - -CERTCertificate * -CERT_NextSubjectCert(CERTCertificate *cert) -{ - CERTSubjectNode *node; - CERTCertificate *retcert = NULL; - - CERT_LockDB(cert->dbhandle); - - node = FindCertSubjectNode(cert); - PORT_Assert(node != NULL); - - if ( node->next != NULL ) { - retcert = CERT_FindCertByKeyNoLocking(cert->dbhandle, - &node->next->certKey); - } - - CERT_UnlockDB(cert->dbhandle); - - return(retcert); -} - -CERTCertificate * -CERT_PrevSubjectCert(CERTCertificate *cert) -{ - CERTSubjectNode *node; - CERTCertificate *retcert = NULL; - - CERT_LockDB(cert->dbhandle); - node = FindCertSubjectNode(cert); - PORT_Assert(node != NULL); - - if ( node->prev != NULL ) { - retcert = CERT_FindCertByKeyNoLocking(cert->dbhandle, - &node->prev->certKey); - } - CERT_UnlockDB(cert->dbhandle); - - return(retcert); -} - -SECStatus -CERT_SaveImportedCert(CERTCertificate *cert, SECCertUsage usage, - PRBool caOnly, char *nickname) -{ - SECStatus rv; - PRBool saveit; - CERTCertTrust trust; - CERTCertTrust tmptrust; - PRBool isCA; - unsigned int certtype; - PRBool freeNickname = PR_FALSE; - - isCA = CERT_IsCACert(cert, NULL); - if ( caOnly && ( !isCA ) ) { - return(SECSuccess); - } - - saveit = PR_TRUE; - - PORT_Memset((void *)&trust, 0, sizeof(trust)); - - certtype = cert->nsCertType; - - /* if no CA bits in cert type, then set all CA bits */ - if ( isCA && ( ! ( certtype & NS_CERT_TYPE_CA ) ) ) { - certtype |= NS_CERT_TYPE_CA; - } - - /* if no app bits in cert type, then set all app bits */ - if ( ( !isCA ) && ( ! ( certtype & NS_CERT_TYPE_APP ) ) ) { - certtype |= NS_CERT_TYPE_APP; - } - - if ( isCA && !nickname ) { - nickname = CERT_MakeCANickname(cert); - if ( nickname != NULL ) { - freeNickname = PR_TRUE; - } - } - - switch ( usage ) { - case certUsageEmailSigner: - case certUsageEmailRecipient: - if ( isCA ) { - if ( certtype & NS_CERT_TYPE_EMAIL_CA ) { - trust.emailFlags = CERTDB_VALID_CA; - } - } else { - PORT_Assert(nickname == NULL); - - if ( cert->emailAddr == NULL ) { - saveit = PR_FALSE; - } - - if ( certtype & NS_CERT_TYPE_EMAIL ) { - trust.emailFlags = CERTDB_VALID_PEER; - if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) { - /* don't save it if KeyEncipherment is not allowed */ - saveit = PR_FALSE; - } - } - } - break; - case certUsageUserCertImport: - if ( isCA ) { - if ( certtype & NS_CERT_TYPE_SSL_CA ) { - trust.sslFlags = CERTDB_VALID_CA; - } - - if ( certtype & NS_CERT_TYPE_EMAIL_CA ) { - trust.emailFlags = CERTDB_VALID_CA; - } - - if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) { - trust.objectSigningFlags = CERTDB_VALID_CA; - } - - } else { - if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) { - trust.sslFlags = CERTDB_VALID_PEER; - } - - if ( certtype & NS_CERT_TYPE_EMAIL ) { - trust.emailFlags = CERTDB_VALID_PEER; - } - - if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) { - trust.objectSigningFlags = CERTDB_VALID_PEER; - } - } - break; - default: /* XXX added to quiet warnings; no other cases needed? */ - break; - } - - if ( (trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) == 0 ){ - saveit = PR_FALSE; - } - - if ( saveit ) { - if ( cert->isperm ) { - /* Cert already in the DB. Just adjust flags */ - tmptrust = *cert->trust; - tmptrust.sslFlags |= trust.sslFlags; - tmptrust.emailFlags |= trust.emailFlags; - tmptrust.objectSigningFlags |= trust.objectSigningFlags; - - rv = CERT_ChangeCertTrust(cert->dbhandle, cert, - &tmptrust); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - /* Cert not already in the DB. Add it */ - rv = CERT_AddTempCertToPerm(cert, nickname, &trust); - if ( rv != SECSuccess ) { - goto loser; - } - } - } - - rv = SECSuccess; - goto done; - -loser: - rv = SECFailure; -done: - - if ( freeNickname ) { - PORT_Free(nickname); - } - - return(rv); -} - -SECStatus -CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb, - CERTCertificate *cert, SECCertUsage usage) -{ - SECStatus rv; - CERTCertTrust trust; - CERTCertTrust tmptrust; - unsigned int certtype; - PRBool saveit; - - saveit = PR_TRUE; - - PORT_Memset((void *)&trust, 0, sizeof(trust)); - - certtype = cert->nsCertType; - - /* if no app bits in cert type, then set all app bits */ - if ( ! ( certtype & NS_CERT_TYPE_APP ) ) { - certtype |= NS_CERT_TYPE_APP; - } - - switch ( usage ) { - case certUsageEmailSigner: - case certUsageEmailRecipient: - if ( certtype & NS_CERT_TYPE_EMAIL ) { - trust.emailFlags = CERTDB_VALID_PEER; - if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) { - /* don't save it if KeyEncipherment is not allowed */ - saveit = PR_FALSE; - } - } - break; - case certUsageUserCertImport: - if ( certtype & NS_CERT_TYPE_EMAIL ) { - trust.emailFlags = CERTDB_VALID_PEER; - } - /* VALID_USER is already set if the cert was imported, - * in the case that the cert was already in the database - * through SMIME or other means, we should set the USER - * flags, if they are not already set. - */ - if( cert->isperm ) { - if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) { - if( !(cert->trust->sslFlags & CERTDB_USER) ) { - trust.sslFlags |= CERTDB_USER; - } - } - - if ( certtype & NS_CERT_TYPE_EMAIL ) { - if( !(cert->trust->emailFlags & CERTDB_USER) ) { - trust.emailFlags |= CERTDB_USER; - } - } - - if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) { - if( !(cert->trust->objectSigningFlags & CERTDB_USER) ) { - trust.objectSigningFlags |= CERTDB_USER; - } - } - } - break; - default: /* XXX added to quiet warnings; no other cases needed? */ - break; - } - - if ( (trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) == 0 ){ - saveit = PR_FALSE; - } - - if ( saveit && cert->isperm ) { - /* Cert already in the DB. Just adjust flags */ - tmptrust = *cert->trust; - tmptrust.sslFlags |= trust.sslFlags; - tmptrust.emailFlags |= trust.emailFlags; - tmptrust.objectSigningFlags |= trust.objectSigningFlags; - - rv = CERT_ChangeCertTrust(cert->dbhandle, cert, - &tmptrust); - if ( rv != SECSuccess ) { - goto loser; - } - } - - rv = SECSuccess; - goto done; - -loser: - rv = SECFailure; -done: - - return(rv); -} - -int -CERT_GetDBContentVersion(CERTCertDBHandle *handle) -{ - certDBEntryContentVersion *entry; - int ret; - - entry = ReadDBContentVersionEntry(handle); - - if ( entry == NULL ) { - return(0); - } - - ret = entry->contentVersion; - - DestroyDBEntry((certDBEntry *)entry); - - return(ret); -} - -void -CERT_SetDBContentVersion(int version, CERTCertDBHandle *handle) -{ - SECStatus rv; - certDBEntryContentVersion *entry; - - entry = NewDBContentVersionEntry(0); - - if ( entry == NULL ) { - return; - } - - rv = DeleteDBContentVersionEntry(handle); - rv = WriteDBContentVersionEntry(handle, entry); - - DestroyDBEntry((certDBEntry *)entry); - - return; -} - -/* - * Creates or adds to a list of all certs with a give subject name, sorted by - * validity time, newest first. Invalid certs are considered older than - * valid certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle, - SECItem *name, int64 sorttime, PRBool validOnly) -{ - CERTCertificate *cert = NULL; - CERTSubjectList *subjectList = NULL; - CERTSubjectNode *node; - SECStatus rv; - - if ( certList == NULL ) { - certList = CERT_NewCertList(); - } - - if ( certList == NULL ) { - goto loser; - } - - subjectList = FindSubjectList(handle, name, PR_FALSE); - - if ( subjectList != NULL ) { - node = subjectList->head; - PORT_Assert(node); - while (node) { - cert = CERT_FindCertByKey(handle, &node->certKey); - - /* if validOnly, then check validity period before adding to list*/ - if ( ( !validOnly ) || - ( CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE) - == secCertTimeValid ) ) { - rv = CERT_AddCertToListSorted(certList, cert, - CERT_SortCBValidity, - (void *)&sorttime); - if ( rv != SECSuccess ) { - CERT_DestroyCertificate(cert); - goto loser; - } - } else { - CERT_DestroyCertificate(cert); - } - - node = node->next; - } - } - - return(certList); - -loser: - if ( certList != NULL ) { - CERT_DestroyCertList(certList); - } - - return(NULL); -} - -/* - * Creates or adds to a list of all certs with a give nickname, sorted by - * validity time, newest first. Invalid certs are considered older than valid - * certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateNicknameCertList(CERTCertList *certList, CERTCertDBHandle *handle, - char *nickname, int64 sorttime, PRBool validOnly) -{ - CERTCertificate *cert; - CERTCertList *ret; - - cert = CERT_FindCertByNickname(handle, nickname); - if ( cert == NULL ) { - return(NULL); - } - - ret = CERT_CreateSubjectCertList(certList, handle, &cert->derSubject, - sorttime, validOnly); - - CERT_DestroyCertificate(cert); - - return(ret); -} - -/* - * Creates or adds to a list of all certs with a give email addr, sorted by - * validity time, newest first. Invalid certs are considered older than valid - * certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateEmailAddrCertList(CERTCertList *certList, CERTCertDBHandle *handle, - char *emailAddr, int64 sorttime, PRBool validOnly) -{ - CERTCertificate *cert; - CERTCertList *ret; - - cert = CERT_FindCertByEmailAddr(handle, emailAddr); - if ( cert == NULL ) { - return(NULL); - } - - ret = CERT_CreateSubjectCertList(certList, handle, &cert->derSubject, - sorttime, validOnly); - - CERT_DestroyCertificate(cert); - - return(ret); -} diff --git a/security/nss/lib/certdb/polcyxtn.c b/security/nss/lib/certdb/polcyxtn.c deleted file mode 100644 index 7f3dd3a78..000000000 --- a/security/nss/lib/certdb/polcyxtn.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Support for various policy related extensions - * - * $Id$ - */ - -#include "seccomon.h" -#include "secport.h" -#include "secder.h" -#include "cert.h" -#include "secoid.h" -#include "secasn1.h" -#include "secerr.h" -#include "nspr.h" - -const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTNoticeReference) }, -/* NOTE: this should be a choice */ - { SEC_ASN1_IA5_STRING, - offsetof(CERTNoticeReference, organization) }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTNoticeReference, noticeNumbers), - SEC_IntegerTemplate }, - { 0 } -}; - -/* this template can not be encoded because of the option inline */ -const SEC_ASN1Template CERT_UserNoticeTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTUserNotice) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED, - offsetof(CERTUserNotice, derNoticeReference) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, - offsetof(CERTUserNotice, displayText) }, - { 0 } -}; - -const SEC_ASN1Template CERT_PolicyQualifierTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTPolicyQualifier) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTPolicyQualifier, qualifierID) }, - { SEC_ASN1_ANY, - offsetof(CERTPolicyQualifier, qualifierValue) }, - { 0 } -}; - -const SEC_ASN1Template CERT_PolicyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTPolicyInfo) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTPolicyInfo, policyID) }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTPolicyInfo, policyQualifiers), - CERT_PolicyQualifierTemplate }, - { 0 } -}; - -const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCertificatePolicies, policyInfos), - CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) } -}; - -static void -breakLines(char *string) -{ - char *tmpstr; - char *lastspace = NULL; - int curlen = 0; - int c; - - tmpstr = string; - - while ( ( c = *tmpstr ) != '\0' ) { - switch ( c ) { - case ' ': - lastspace = tmpstr; - break; - case '\n': - lastspace = NULL; - curlen = 0; - break; - } - - if ( ( curlen >= 55 ) && ( lastspace != NULL ) ) { - *lastspace = '\n'; - curlen = ( tmpstr - lastspace ); - lastspace = NULL; - } - - curlen++; - tmpstr++; - } - - return; -} - -CERTCertificatePolicies * -CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - CERTCertificatePolicies *policies; - CERTPolicyInfo **policyInfos, *policyInfo; - CERTPolicyQualifier **policyQualifiers, *policyQualifier; - - /* make a new arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - goto loser; - } - - /* allocate the certifiate policies structure */ - policies = (CERTCertificatePolicies *) - PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies)); - - if ( policies == NULL ) { - goto loser; - } - - policies->arena = arena; - - /* decode the policy info */ - rv = SEC_ASN1DecodeItem(arena, policies, CERT_CertificatePoliciesTemplate, - extnValue); - - if ( rv != SECSuccess ) { - goto loser; - } - - /* initialize the oid tags */ - policyInfos = policies->policyInfos; - while (*policyInfos != NULL ) { - policyInfo = *policyInfos; - policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID); - policyQualifiers = policyInfo->policyQualifiers; - while ( *policyQualifiers != NULL ) { - policyQualifier = *policyQualifiers; - policyQualifier->oid = - SECOID_FindOIDTag(&policyQualifier->qualifierID); - policyQualifiers++; - } - policyInfos++; - } - - return(policies); - -loser: - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -void -CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies) -{ - if ( policies != NULL ) { - PORT_FreeArena(policies->arena, PR_FALSE); - } - return; -} - - -CERTUserNotice * -CERT_DecodeUserNotice(SECItem *noticeItem) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - CERTUserNotice *userNotice; - - /* make a new arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - goto loser; - } - - /* allocate the userNotice structure */ - userNotice = (CERTUserNotice *)PORT_ArenaZAlloc(arena, - sizeof(CERTUserNotice)); - - if ( userNotice == NULL ) { - goto loser; - } - - userNotice->arena = arena; - - /* decode the user notice */ - rv = SEC_ASN1DecodeItem(arena, userNotice, CERT_UserNoticeTemplate, - noticeItem); - - if ( rv != SECSuccess ) { - goto loser; - } - - if (userNotice->derNoticeReference.data != NULL) { - /* sigh, the asn1 parser stripped the sequence encoding, re add it - * before we decode. - */ - SECItem tmpbuf; - int newBytes; - - newBytes = SEC_ASN1LengthLength(userNotice->derNoticeReference.len)+1; - tmpbuf.len = newBytes + userNotice->derNoticeReference.len; - tmpbuf.data = PORT_ZAlloc(tmpbuf.len); - if (tmpbuf.data == NULL) { - goto loser; - } - tmpbuf.data[0] = SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED; - SEC_ASN1EncodeLength(&tmpbuf.data[1],userNotice->derNoticeReference.len); - PORT_Memcpy(&tmpbuf.data[newBytes],userNotice->derNoticeReference.data, - userNotice->derNoticeReference.len); - - /* OK, no decode it */ - rv = SEC_ASN1DecodeItem(arena, &userNotice->noticeReference, - CERT_NoticeReferenceTemplate, &tmpbuf); - - PORT_Free(tmpbuf.data); tmpbuf.data = NULL; - if ( rv != SECSuccess ) { - goto loser; - } - } - - return(userNotice); - -loser: - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -void -CERT_DestroyUserNotice(CERTUserNotice *userNotice) -{ - if ( userNotice != NULL ) { - PORT_FreeArena(userNotice->arena, PR_FALSE); - } - return; -} - -static CERTPolicyStringCallback policyStringCB = NULL; -static void *policyStringCBArg = NULL; - -void -CERT_SetCAPolicyStringCallback(CERTPolicyStringCallback cb, void *cbarg) -{ - policyStringCB = cb; - policyStringCBArg = cbarg; - return; -} - -char * -stringFromUserNotice(SECItem *noticeItem) -{ - SECItem *org; - unsigned int len, headerlen; - char *stringbuf; - CERTUserNotice *userNotice; - char *policystr; - char *retstr = NULL; - SECItem *displayText; - SECItem **noticeNumbers; - unsigned int strnum; - - /* decode the user notice */ - userNotice = CERT_DecodeUserNotice(noticeItem); - if ( userNotice == NULL ) { - return(NULL); - } - - org = &userNotice->noticeReference.organization; - if ( (org->len != 0 ) && ( policyStringCB != NULL ) ) { - /* has a noticeReference */ - - /* extract the org string */ - len = org->len; - stringbuf = (char*)PORT_Alloc(len + 1); - if ( stringbuf != NULL ) { - PORT_Memcpy(stringbuf, org->data, len); - stringbuf[len] = '\0'; - - noticeNumbers = userNotice->noticeReference.noticeNumbers; - while ( *noticeNumbers != NULL ) { - /* XXX - only one byte integers right now*/ - strnum = (*noticeNumbers)->data[0]; - policystr = (* policyStringCB)(stringbuf, - strnum, - policyStringCBArg); - if ( policystr != NULL ) { - if ( retstr != NULL ) { - retstr = PR_sprintf_append(retstr, "\n%s", policystr); - } else { - retstr = PR_sprintf_append(retstr, "%s", policystr); - } - - PORT_Free(policystr); - } - - noticeNumbers++; - } - - PORT_Free(stringbuf); - } - } - - if ( retstr == NULL ) { - if ( userNotice->displayText.len != 0 ) { - displayText = &userNotice->displayText; - - if ( displayText->len > 2 ) { - if ( displayText->data[0] == SEC_ASN1_VISIBLE_STRING ) { - headerlen = 2; - if ( displayText->data[1] & 0x80 ) { - /* multibyte length */ - headerlen += ( displayText->data[1] & 0x7f ); - } - - len = displayText->len - headerlen; - retstr = (char*)PORT_Alloc(len + 1); - if ( retstr != NULL ) { - PORT_Memcpy(retstr, &displayText->data[headerlen],len); - retstr[len] = '\0'; - } - } - } - } - } - - CERT_DestroyUserNotice(userNotice); - - return(retstr); -} - -char * -CERT_GetCertCommentString(CERTCertificate *cert) -{ - char *retstring = NULL; - SECStatus rv; - SECItem policyItem; - CERTCertificatePolicies *policies = NULL; - CERTPolicyInfo **policyInfos; - CERTPolicyQualifier **policyQualifiers, *qualifier; - - policyItem.data = NULL; - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_CERTIFICATE_POLICIES, - &policyItem); - if ( rv != SECSuccess ) { - goto nopolicy; - } - - policies = CERT_DecodeCertificatePoliciesExtension(&policyItem); - if ( policies == NULL ) { - goto nopolicy; - } - - policyInfos = policies->policyInfos; - /* search through policyInfos looking for the verisign policy */ - while (*policyInfos != NULL ) { - if ( (*policyInfos)->oid == SEC_OID_VERISIGN_USER_NOTICES ) { - policyQualifiers = (*policyInfos)->policyQualifiers; - /* search through the policy qualifiers looking for user notice */ - while ( *policyQualifiers != NULL ) { - qualifier = *policyQualifiers; - if ( qualifier->oid == SEC_OID_PKIX_USER_NOTICE_QUALIFIER ) { - retstring = - stringFromUserNotice(&qualifier->qualifierValue); - break; - } - - policyQualifiers++; - } - break; - } - policyInfos++; - } - -nopolicy: - if ( policyItem.data != NULL ) { - PORT_Free(policyItem.data); - } - - if ( policies != NULL ) { - CERT_DestroyCertificatePoliciesExtension(policies); - } - - if ( retstring == NULL ) { - retstring = CERT_FindNSStringExtension(cert, - SEC_OID_NS_CERT_EXT_COMMENT); - } - - if ( retstring != NULL ) { - breakLines(retstring); - } - - return(retstring); -} - - -const SEC_ASN1Template CERT_OidSeqTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTOidSequence, oids), - SEC_ObjectIDTemplate } -}; - -CERTOidSequence * -CERT_DecodeOidSequence(SECItem *seqItem) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - CERTOidSequence *oidSeq; - - /* make a new arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - goto loser; - } - - /* allocate the userNotice structure */ - oidSeq = (CERTOidSequence *)PORT_ArenaZAlloc(arena, - sizeof(CERTOidSequence)); - - if ( oidSeq == NULL ) { - goto loser; - } - - oidSeq->arena = arena; - - /* decode the user notice */ - rv = SEC_ASN1DecodeItem(arena, oidSeq, CERT_OidSeqTemplate, seqItem); - - if ( rv != SECSuccess ) { - goto loser; - } - - return(oidSeq); - -loser: - return(NULL); -} - - -void -CERT_DestroyOidSequence(CERTOidSequence *oidSeq) -{ - if ( oidSeq != NULL ) { - PORT_FreeArena(oidSeq->arena, PR_FALSE); - } - return; -} - -PRBool -CERT_GovtApprovedBitSet(CERTCertificate *cert) -{ - SECStatus rv; - SECItem extItem; - CERTOidSequence *oidSeq = NULL; - PRBool ret; - SECItem **oids; - SECItem *oid; - SECOidTag oidTag; - - extItem.data = NULL; - rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem); - if ( rv != SECSuccess ) { - goto loser; - } - - oidSeq = CERT_DecodeOidSequence(&extItem); - if ( oidSeq == NULL ) { - goto loser; - } - - oids = oidSeq->oids; - while ( oids != NULL && *oids != NULL ) { - oid = *oids; - - oidTag = SECOID_FindOIDTag(oid); - - if ( oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED ) { - goto success; - } - - oids++; - } - -loser: - ret = PR_FALSE; - goto done; -success: - ret = PR_TRUE; -done: - if ( oidSeq != NULL ) { - CERT_DestroyOidSequence(oidSeq); - } - if (extItem.data != NULL) { - PORT_Free(extItem.data); - } - return(ret); -} diff --git a/security/nss/lib/certdb/secname.c b/security/nss/lib/certdb/secname.c deleted file mode 100644 index 4bef4b6d9..000000000 --- a/security/nss/lib/certdb/secname.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "cert.h" -#include "secoid.h" -#include "secder.h" /* XXX remove this when remove the DERTemplates */ -#include "secasn1.h" -#include "secitem.h" -#include -#include "secerr.h" - -static const SEC_ASN1Template cert_AVATemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTAVA) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTAVA,type), }, - { SEC_ASN1_ANY, - offsetof(CERTAVA,value), }, - { 0, } -}; - -const SEC_ASN1Template CERT_RDNTemplate[] = { - { SEC_ASN1_SET_OF, - offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) } -}; - - -static int -CountArray(void **array) -{ - int count = 0; - if (array) { - while (*array++) { - count++; - } - } - return count; -} - -static void -**AddToArray(PRArenaPool *arena, void **array, void *element) -{ - unsigned count; - void **ap; - - /* Count up number of slots already in use in the array */ - count = 0; - ap = array; - if (ap) { - while (*ap++) { - count++; - } - } - - if (array) { - array = (void**) PORT_ArenaGrow(arena, array, - (count + 1) * sizeof(void *), - (count + 2) * sizeof(void *)); - } else { - array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *)); - } - if (array) { - array[count] = element; - array[count+1] = 0; - } - return array; -} - -#if 0 -static void -**RemoveFromArray(void **array, void *element) -{ - unsigned count; - void **ap; - int slot; - - /* Look for element */ - ap = array; - if (ap) { - count = 1; /* count the null at the end */ - slot = -1; - for (; *ap; ap++, count++) { - if (*ap == element) { - /* Found it */ - slot = ap - array; - } - } - if (slot >= 0) { - /* Found it. Squish array down */ - PORT_Memmove((void*) (array + slot), (void*) (array + slot + 1), - (count - slot - 1) * sizeof(void*)); - /* Don't bother reallocing the memory */ - } - } - return array; -} -#endif /* 0 */ - -SECOidTag -CERT_GetAVATag(CERTAVA *ava) -{ - SECOidData *oid; - if (!ava->type.data) return (SECOidTag)-1; - - oid = SECOID_FindOID(&ava->type); - - if ( oid ) { - return(oid->offset); - } - return (SECOidTag)-1; -} - -static SECStatus -SetupAVAType(PRArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp) -{ - unsigned char *oid; - unsigned oidLen; - unsigned char *cp; - unsigned maxLen; - SECOidData *oidrec; - - oidrec = SECOID_FindOIDByTag(type); - if (oidrec == NULL) - return SECFailure; - - oid = oidrec->oid.data; - oidLen = oidrec->oid.len; - - switch (type) { - case SEC_OID_AVA_COUNTRY_NAME: - maxLen = 2; - break; - case SEC_OID_AVA_ORGANIZATION_NAME: - maxLen = 64; - break; - case SEC_OID_AVA_COMMON_NAME: - maxLen = 64; - break; - case SEC_OID_AVA_LOCALITY: - maxLen = 128; - break; - case SEC_OID_AVA_STATE_OR_PROVINCE: - maxLen = 128; - break; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - maxLen = 64; - break; - case SEC_OID_AVA_DC: - maxLen = 128; - break; - case SEC_OID_AVA_DN_QUALIFIER: - maxLen = 0x7fff; - break; - case SEC_OID_PKCS9_EMAIL_ADDRESS: - maxLen = 128; - break; - case SEC_OID_RFC1274_UID: - maxLen = 256; /* RFC 1274 specifies 256 */ - break; - case SEC_OID_RFC1274_MAIL: - maxLen = 256; /* RFC 1274 specifies 256 */ - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen); - if (cp == NULL) { - return SECFailure; - } - it->len = oidLen; - PORT_Memcpy(cp, oid, oidLen); - *maxLenp = maxLen; - return SECSuccess; -} - -static SECStatus -SetupAVAValue(PRArenaPool *arena, int valueType, char *value, SECItem *it, - unsigned maxLen) -{ - unsigned valueLen, valueLenLen, total; - unsigned ucs4Len = 0, ucs4MaxLen; - unsigned char *cp, *ucs4Val; - - switch (valueType) { - case SEC_ASN1_PRINTABLE_STRING: - case SEC_ASN1_IA5_STRING: - case SEC_ASN1_T61_STRING: - valueLen = PORT_Strlen(value); - break; - case SEC_ASN1_UNIVERSAL_STRING: - valueLen = PORT_Strlen(value); - ucs4Val = (unsigned char *)PORT_ArenaZAlloc(arena, - PORT_Strlen(value) * 6); - ucs4MaxLen = PORT_Strlen(value) * 6; - if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, (unsigned char *)value, valueLen, - ucs4Val, ucs4MaxLen, &ucs4Len)) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - value = (char *)ucs4Val; - valueLen = ucs4Len; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (((valueType != SEC_ASN1_UNIVERSAL_STRING) && (valueLen > maxLen)) || - (valueType == SEC_ASN1_UNIVERSAL_STRING) && (valueLen > (maxLen * 4))) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - valueLenLen = DER_LengthLength(valueLen); - total = 1 + valueLenLen + valueLen; - it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, total); - if (!cp) { - return SECFailure; - } - it->len = total; - cp = (unsigned char*) DER_StoreHeader(cp, valueType, valueLen); - PORT_Memcpy(cp, value, valueLen); - return SECSuccess; -} - -CERTAVA * -CERT_CreateAVA(PRArenaPool *arena, SECOidTag kind, int valueType, char *value) -{ - CERTAVA *ava; - int rv; - unsigned maxLen; - - ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); - if (ava) { - rv = SetupAVAType(arena, kind, &ava->type, &maxLen); - if (rv) { - /* Illegal AVA type */ - return 0; - } - rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen); - if (rv) { - /* Illegal value type */ - return 0; - } - } - return ava; -} - -CERTAVA * -CERT_CopyAVA(PRArenaPool *arena, CERTAVA *from) -{ - CERTAVA *ava; - int rv; - - ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); - if (ava) { - rv = SECITEM_CopyItem(arena, &ava->type, &from->type); - if (rv) goto loser; - rv = SECITEM_CopyItem(arena, &ava->value, &from->value); - if (rv) goto loser; - } - return ava; - - loser: - return 0; -} - -/************************************************************************/ -/* XXX This template needs to go away in favor of the new SEC_ASN1 version. */ -static const SEC_ASN1Template cert_RDNTemplate[] = { - { SEC_ASN1_SET_OF, - offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) } -}; - - -CERTRDN * -CERT_CreateRDN(PRArenaPool *arena, CERTAVA *ava0, ...) -{ - CERTAVA *ava; - CERTRDN *rdn; - va_list ap; - unsigned count; - CERTAVA **avap; - - rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN)); - if (rdn) { - /* Count number of avas going into the rdn */ - count = 1; - va_start(ap, ava0); - while ((ava = va_arg(ap, CERTAVA*)) != 0) { - count++; - } - va_end(ap); - - /* Now fill in the pointers */ - rdn->avas = avap = - (CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*)); - if (!avap) { - return 0; - } - *avap++ = ava0; - va_start(ap, ava0); - while ((ava = va_arg(ap, CERTAVA*)) != 0) { - *avap++ = ava; - } - va_end(ap); - *avap++ = 0; - } - return rdn; -} - -SECStatus -CERT_AddAVA(PRArenaPool *arena, CERTRDN *rdn, CERTAVA *ava) -{ - rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava); - return rdn->avas ? SECSuccess : SECFailure; -} - -SECStatus -CERT_CopyRDN(PRArenaPool *arena, CERTRDN *to, CERTRDN *from) -{ - CERTAVA **avas, *fava, *tava; - SECStatus rv; - - /* Copy each ava from from */ - avas = from->avas; - while ((fava = *avas++) != 0) { - tava = CERT_CopyAVA(arena, fava); - if (!tava) return SECFailure; - rv = CERT_AddAVA(arena, to, tava); - if (rv) return rv; - } - return SECSuccess; -} - -/************************************************************************/ - -const SEC_ASN1Template CERT_NameTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) } -}; - -CERTName * -CERT_CreateName(CERTRDN *rdn0, ...) -{ - CERTRDN *rdn; - CERTName *name; - va_list ap; - unsigned count; - CERTRDN **rdnp; - PRArenaPool *arena; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( !arena ) { - return(0); - } - - name = (CERTName*) PORT_ArenaAlloc(arena, sizeof(CERTName)); - if (name) { - name->arena = arena; - - /* Count number of RDNs going into the Name */ - count = 1; - va_start(ap, rdn0); - while ((rdn = va_arg(ap, CERTRDN*)) != 0) { - count++; - } - va_end(ap); - - /* Now fill in the pointers */ - name->rdns = rdnp = - (CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*)); - if (!name->rdns) { - goto loser; - } - *rdnp++ = rdn0; - va_start(ap, rdn0); - while ((rdn = va_arg(ap, CERTRDN*)) != 0) { - *rdnp++ = rdn; - } - va_end(ap); - *rdnp++ = 0; - } - return name; - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(0); -} - -void -CERT_DestroyName(CERTName *name) -{ - if (name) - { - PRArenaPool *arena = name->arena; - name->rdns = NULL; - name->arena = NULL; - if (arena) PORT_FreeArena(arena, PR_FALSE); - } -} - -SECStatus -CERT_AddRDN(CERTName *name, CERTRDN *rdn) -{ - name->rdns = (CERTRDN**) AddToArray(name->arena, (void**) name->rdns, rdn); - return name->rdns ? SECSuccess : SECFailure; -} - -SECStatus -CERT_CopyName(PRArenaPool *arena, CERTName *to, CERTName *from) -{ - CERTRDN **rdns, *frdn, *trdn; - SECStatus rv; - - CERT_DestroyName(to); - to->arena = arena; - - /* Copy each rdn from from */ - rdns = from->rdns; - while ((frdn = *rdns++) != 0) { - trdn = CERT_CreateRDN(arena, 0); - if ( trdn == NULL ) { - return(SECFailure); - } - rv = CERT_CopyRDN(arena, trdn, frdn); - if (rv) return rv; - rv = CERT_AddRDN(to, trdn); - if (rv) return rv; - } - return SECSuccess; -} - -/************************************************************************/ - -SECComparison -CERT_CompareAVA(CERTAVA *a, CERTAVA *b) -{ - SECComparison rv; - - rv = SECITEM_CompareItem(&a->type, &b->type); - if (rv) { - /* - ** XXX for now we are going to just assume that a bitwise - ** comparison of the value codes will do the trick. - */ - } - rv = SECITEM_CompareItem(&a->value, &b->value); - return rv; -} - -SECComparison -CERT_CompareRDN(CERTRDN *a, CERTRDN *b) -{ - CERTAVA **aavas, *aava; - CERTAVA **bavas, *bava; - int ac, bc; - SECComparison rv = SECEqual; - - aavas = a->avas; - bavas = b->avas; - - /* - ** Make sure array of ava's are the same length. If not, then we are - ** not equal - */ - ac = CountArray((void**) aavas); - bc = CountArray((void**) bavas); - if (ac < bc) return SECLessThan; - if (ac > bc) return SECGreaterThan; - - for (;;) { - aava = *aavas++; - bava = *bavas++; - if (!aava) { - break; - } - rv = CERT_CompareAVA(aava, bava); - if (rv) return rv; - } - return rv; -} - -SECComparison -CERT_CompareName(CERTName *a, CERTName *b) -{ - CERTRDN **ardns, *ardn; - CERTRDN **brdns, *brdn; - int ac, bc; - SECComparison rv = SECEqual; - - ardns = a->rdns; - brdns = b->rdns; - - /* - ** Make sure array of rdn's are the same length. If not, then we are - ** not equal - */ - ac = CountArray((void**) ardns); - bc = CountArray((void**) brdns); - if (ac < bc) return SECLessThan; - if (ac > bc) return SECGreaterThan; - - for (;;) { - ardn = *ardns++; - brdn = *brdns++; - if (!ardn) { - break; - } - rv = CERT_CompareRDN(ardn, brdn); - if (rv) return rv; - } - return rv; -} - -/* Moved from certhtml.c */ -SECItem * -CERT_DecodeAVAValue(SECItem *derAVAValue) -{ - SECItem *retItem; - const SEC_ASN1Template *theTemplate = NULL; - PRBool convertUCS4toUTF8 = PR_FALSE; - PRBool convertUCS2toUTF8 = PR_FALSE; - SECItem avaValue = {siBuffer, 0}; - - if(!derAVAValue) { - return NULL; - } - - switch(derAVAValue->data[0]) { - case SEC_ASN1_UNIVERSAL_STRING: - convertUCS4toUTF8 = PR_TRUE; - theTemplate = SEC_UniversalStringTemplate; - break; - case SEC_ASN1_IA5_STRING: - theTemplate = SEC_IA5StringTemplate; - break; - case SEC_ASN1_PRINTABLE_STRING: - theTemplate = SEC_PrintableStringTemplate; - break; - case SEC_ASN1_T61_STRING: - theTemplate = SEC_T61StringTemplate; - break; - case SEC_ASN1_BMP_STRING: - convertUCS2toUTF8 = PR_TRUE; - theTemplate = SEC_BMPStringTemplate; - break; - default: - return NULL; - } - - PORT_Memset(&avaValue, 0, sizeof(SECItem)); - if(SEC_ASN1DecodeItem(NULL, &avaValue, theTemplate, derAVAValue) - != SECSuccess) { - return NULL; - } - - if (convertUCS4toUTF8) { - unsigned int utf8ValLen = avaValue.len * 3; - unsigned char *utf8Val = (unsigned char*)PORT_ZAlloc(utf8ValLen); - - if(!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, - utf8Val, utf8ValLen, &utf8ValLen)) { - PORT_Free(utf8Val); - PORT_Free(avaValue.data); - return NULL; - } - - PORT_Free(avaValue.data); - avaValue.data = utf8Val; - avaValue.len = utf8ValLen; - - } else if (convertUCS2toUTF8) { - - unsigned int utf8ValLen = avaValue.len * 3; - unsigned char *utf8Val = (unsigned char*)PORT_ZAlloc(utf8ValLen); - - if(!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, - utf8Val, utf8ValLen, &utf8ValLen)) { - PORT_Free(utf8Val); - PORT_Free(avaValue.data); - return NULL; - } - - PORT_Free(avaValue.data); - avaValue.data = utf8Val; - avaValue.len = utf8ValLen; - } - - retItem = SECITEM_DupItem(&avaValue); - PORT_Free(avaValue.data); - return retItem; -} diff --git a/security/nss/lib/certdb/xauthkid.c b/security/nss/lib/certdb/xauthkid.c deleted file mode 100644 index 8b7ac4a92..000000000 --- a/security/nss/lib/certdb/xauthkid.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * X.509 v3 Subject Key Usage Extension - * - */ - -#include "prtypes.h" -#include "mcom_db.h" -#include "seccomon.h" -#include "secdert.h" -#include "secoidt.h" -#include "secasn1t.h" -#include "secasn1.h" -#include "secport.h" -#include "certt.h" -#include "genname.h" -#include "secerr.h" - - -const SEC_ASN1Template CERTAuthKeyIDTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTAuthKeyID,keyID), SEC_OctetStringTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(CERTAuthKeyID,authCertSerialNumber), SEC_IntegerTemplate}, - { 0 } -}; - - - -SECStatus CERT_EncodeAuthKeyID (PRArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue) -{ - SECStatus rv = SECFailure; - - PORT_Assert (value); - PORT_Assert (arena); - PORT_Assert (value->DERAuthCertIssuer == NULL); - PORT_Assert (encodedValue); - - do { - - /* If both of the authCertIssuer and the serial number exist, encode - the name first. Otherwise, it is an error if one exist and the other - is not. - */ - if (value->authCertIssuer) { - if (!value->authCertSerialNumber.data) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - - value->DERAuthCertIssuer = cert_EncodeGeneralNames - (arena, value->authCertIssuer); - if (!value->DERAuthCertIssuer) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - } - else if (value->authCertSerialNumber.data) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - - if (SEC_ASN1EncodeItem (arena, encodedValue, value, - CERTAuthKeyIDTemplate) == NULL) - break; - rv = SECSuccess; - - } while (0); - return(rv); -} - -CERTAuthKeyID * -CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue) -{ - CERTAuthKeyID * value = NULL; - SECStatus rv = SECFailure; - void * mark; - - PORT_Assert (arena); - - do { - mark = PORT_ArenaMark (arena); - value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); - value->DERAuthCertIssuer = NULL; - if (value == NULL) - break; - rv = SEC_ASN1DecodeItem - (arena, value, CERTAuthKeyIDTemplate, encodedValue); - if (rv != SECSuccess) - break; - - value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer); - if (value->authCertIssuer == NULL) - break; - - /* what if the general name contains other format but not URI ? - hl - */ - if ((value->authCertSerialNumber.data && !value->authCertIssuer) || - (!value->authCertSerialNumber.data && value->authCertIssuer)){ - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - } while (0); - - if (rv != SECSuccess) { - PORT_ArenaRelease (arena, mark); - return ((CERTAuthKeyID *)NULL); - } - PORT_ArenaUnmark(arena, mark); - return (value); -} diff --git a/security/nss/lib/certdb/xbsconst.c b/security/nss/lib/certdb/xbsconst.c deleted file mode 100644 index f03595cb7..000000000 --- a/security/nss/lib/certdb/xbsconst.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * X.509 v3 Basic Constraints Extension - */ - -#include "prtypes.h" -#include "mcom_db.h" -#include "seccomon.h" -#include "secdert.h" -#include "secoidt.h" -#include "secasn1t.h" -#include "secasn1.h" -#include "certt.h" -#include "secder.h" -#include "prprf.h" -#include "secerr.h" - -typedef struct EncodedContext{ - SECItem isCA; - SECItem pathLenConstraint; - SECItem encodedValue; - PRArenaPool *arena; -}EncodedContext; - -static const SEC_ASN1Template CERTBasicConstraintsTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(EncodedContext) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ - offsetof(EncodedContext,isCA)}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, - offsetof(EncodedContext,pathLenConstraint) }, - { 0, } -}; - -static unsigned char hexTrue = 0xff; -static unsigned char hexFalse = 0x00; - -#define GEN_BREAK(status) rv = status; break; - -SECStatus CERT_EncodeBasicConstraintValue - (PRArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue) -{ - EncodedContext encodeContext; - PRArenaPool *our_pool = NULL; - SECStatus rv = SECSuccess; - - do { - PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); - if (!value->isCA && value->pathLenConstraint >= 0) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - GEN_BREAK (SECFailure); - } - - encodeContext.arena = arena; - if (value->isCA == PR_TRUE) { - encodeContext.isCA.data = &hexTrue ; - encodeContext.isCA.len = 1; - } - - /* If the pathLenConstraint is less than 0, then it should be - * omitted from the encoding. - */ - if (value->isCA && value->pathLenConstraint >= 0) { - our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); - if (our_pool == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - GEN_BREAK (SECFailure); - } - if (SEC_ASN1EncodeUnsignedInteger - (our_pool, &encodeContext.pathLenConstraint, - (unsigned long)value->pathLenConstraint) == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - GEN_BREAK (SECFailure); - } - } - if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, - CERTBasicConstraintsTemplate) == NULL) - GEN_BREAK (SECFailure); - } while (0); - if (our_pool) - PORT_FreeArena (our_pool, PR_FALSE); - return(rv); - -} - -SECStatus CERT_DecodeBasicConstraintValue - (CERTBasicConstraints *value, SECItem *encodedValue) -{ - EncodedContext decodeContext; - PRArenaPool *our_pool; - SECStatus rv = SECSuccess; - - do { - PORT_Memset (&decodeContext, 0, sizeof (decodeContext)); - /* initialize the value just in case we got "0x30 00", or when the - pathLenConstraint is omitted. - */ - decodeContext.isCA.data =&hexFalse; - decodeContext.isCA.len = 1; - - our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); - if (our_pool == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - GEN_BREAK (SECFailure); - } - - rv = SEC_ASN1DecodeItem - (our_pool, &decodeContext, CERTBasicConstraintsTemplate, encodedValue); - if (rv == SECFailure) - break; - - value->isCA = (PRBool)(*decodeContext.isCA.data); - if (decodeContext.pathLenConstraint.data == NULL) { - /* if the pathLenConstraint is not encoded, and the current setting - is CA, then the pathLenConstraint should be set to a negative number - for unlimited certificate path. - */ - if (value->isCA) - value->pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT; - } - else if (value->isCA) - value->pathLenConstraint = DER_GetUInteger (&decodeContext.pathLenConstraint); - else { - /* here we get an error where the subject is not a CA, but - the pathLenConstraint is set */ - PORT_SetError (SEC_ERROR_BAD_DER); - GEN_BREAK (SECFailure); - break; - } - - } while (0); - PORT_FreeArena (our_pool, PR_FALSE); - return (rv); - -} diff --git a/security/nss/lib/certdb/xconst.c b/security/nss/lib/certdb/xconst.c deleted file mode 100644 index 0f404f958..000000000 --- a/security/nss/lib/certdb/xconst.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * X.509 Extension Encoding - */ - -#include "prtypes.h" -#include "mcom_db.h" -#include "seccomon.h" -#include "secdert.h" -#include "secoidt.h" -#include "secasn1t.h" -#include "secasn1.h" -#include "certt.h" -#include "secder.h" -#include "prprf.h" -#include "xconst.h" -#include "genname.h" -#include "secasn1.h" - - - -static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = { -{ SEC_ASN1_OCTET_STRING } -}; - - -static const SEC_ASN1Template CERTIA5TypeTemplate[] = { -{ SEC_ASN1_IA5_STRING } -}; - - -static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(PKUPEncodedContext) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(PKUPEncodedContext, notBefore), SEC_GeneralizedTimeTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(PKUPEncodedContext, notAfter), SEC_GeneralizedTimeTemplate}, - { 0, } -}; - - -const SEC_ASN1Template CERTAltNameTemplate[] = { - { SEC_ASN1_CONSTRUCTED, offsetof(AltNameEncodedContext, encodedGenName), - CERT_GeneralNamesTemplate} -}; - -const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTAuthInfoAccess) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTAuthInfoAccess, method) }, - { SEC_ASN1_ANY, - offsetof(CERTAuthInfoAccess, derLocation) }, - { 0, } -}; - -const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate } -}; - - -SECStatus -CERT_EncodeSubjectKeyID(PRArenaPool *arena, char *value, int len, SECItem *encodedValue) -{ - SECItem encodeContext; - SECStatus rv = SECSuccess; - - - PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); - - if (value != NULL) { - encodeContext.data = (unsigned char *)value; - encodeContext.len = len; - } - if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, - CERTSubjectKeyIDTemplate) == NULL) { - rv = SECFailure; - } - - return(rv); -} - - -SECStatus -CERT_EncodePublicKeyUsagePeriod(PRArenaPool *arena, PKUPEncodedContext *pkup, SECItem *encodedValue) -{ - SECStatus rv = SECSuccess; - - if (SEC_ASN1EncodeItem (arena, encodedValue, pkup, - CERTPrivateKeyUsagePeriodTemplate) == NULL) { - rv = SECFailure; - } - return(rv); -} - - -SECStatus -CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedValue) -{ - SECItem encodeContext; - SECStatus rv = SECSuccess; - - - PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); - - if (value != NULL) { - encodeContext.data = (unsigned char *)value; - encodeContext.len = strlen(value); - } - if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, - CERTIA5TypeTemplate) == NULL) { - rv = SECFailure; - } - - return(rv); -} - -SECStatus -CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue) -{ - SECItem **encodedGenName; - SECStatus rv = SECSuccess; - - encodedGenName = cert_EncodeGeneralNames(arena, value); - if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName, - CERT_GeneralNamesTemplate) == NULL) { - rv = SECFailure; - } - - return rv; -} - -CERTGeneralName * -CERT_DecodeAltNameExtension(PRArenaPool *arena, SECItem *EncodedAltName) -{ - SECStatus rv = SECSuccess; - AltNameEncodedContext encodedContext; - - encodedContext.encodedGenName = NULL; - PORT_Memset(&encodedContext, 0, sizeof(AltNameEncodedContext)); - rv = SEC_ASN1DecodeItem (arena, &encodedContext, CERT_GeneralNamesTemplate, - EncodedAltName); - if (rv == SECFailure) { - goto loser; - } - return cert_DecodeGeneralNames(arena, encodedContext.encodedGenName); -loser: - return NULL; -} - - -SECStatus -CERT_EncodeNameConstraintsExtension(PRArenaPool *arena, - CERTNameConstraints *value, - SECItem *encodedValue) -{ - SECStatus rv = SECSuccess; - - rv = cert_EncodeNameConstraints(value, arena, encodedValue); - return rv; -} - - -CERTNameConstraints * -CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, - SECItem *encodedConstraints) -{ - return cert_DecodeNameConstraints(arena, encodedConstraints); -} - - -CERTAuthInfoAccess ** -cert_DecodeAuthInfoAccessExtension(PRArenaPool *arena, - SECItem *encodedExtension) -{ - CERTAuthInfoAccess **info = NULL; - SECStatus rv; - int i; - - rv = SEC_ASN1DecodeItem(arena, &info, CERTAuthInfoAccessTemplate, - encodedExtension); - if (rv != SECSuccess || info == NULL) { - return NULL; - } - - for (i = 0; info[i] != NULL; i++) { - info[i]->location = cert_DecodeGeneralName(arena, - &(info[i]->derLocation), - NULL); - } - return info; -} - -SECStatus -cert_EncodeAuthInfoAccessExtension(PRArenaPool *arena, - CERTAuthInfoAccess **info, - SECItem *dest) -{ - SECItem *dummy; - int i; - - PORT_Assert(info != NULL); - PORT_Assert(dest != NULL); - if (info == NULL || dest == NULL) { - return SECFailure; - } - - for (i = 0; info[i] != NULL; i++) { - if (cert_EncodeGeneralName(info[i]->location, &(info[i]->derLocation), - arena) == NULL) - /* Note that this may leave some of the locations filled in. */ - return SECFailure; - } - dummy = SEC_ASN1EncodeItem(arena, dest, &info, - CERTAuthInfoAccessTemplate); - if (dummy == NULL) { - return SECFailure; - } - return SECSuccess; -} diff --git a/security/nss/lib/certdb/xconst.h b/security/nss/lib/certdb/xconst.h deleted file mode 100644 index 42c49f2e4..000000000 --- a/security/nss/lib/certdb/xconst.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "certt.h" - -typedef struct PKUPEncodedContext{ - SECItem notBefore; - SECItem notAfter; - /* SECItem encodedValue; */ - PRArenaPool *arena; -}PKUPEncodedContext; - -typedef struct AltNameEncodedContext{ - SECItem **encodedGenName; -}AltNameEncodedContext; - - -typedef struct NameConstraint{ - CERTGeneralName generalName; - int min; - int max; -}NameConstraint; - - - -extern SECStatus -CERT_EncodePublicKeyUsagePeriod(PRArenaPool *arena, PKUPEncodedContext *pkup, - SECItem *encodedValue); - -extern SECStatus -CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue); - -extern SECStatus -CERT_EncodeNameConstraintsExtension(PRArenaPool *arena, CERTNameConstraints *value, - SECItem *encodedValue); -extern CERTGeneralName * -CERT_DecodeAltNameExtension(PRArenaPool *arena, SECItem *EncodedAltName); - -extern CERTNameConstraints * -CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, SECItem *encodedConstraints); - -extern SECStatus -CERT_EncodeSubjectKeyID(PRArenaPool *arena, char *value, int len, SECItem *encodedValue); - -extern SECStatus -CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedValue); - -CERTAuthInfoAccess ** -cert_DecodeAuthInfoAccessExtension(PRArenaPool *arena, - SECItem *encodedExtension); - -SECStatus -cert_EncodeAuthInfoAccessExtension(PRArenaPool *arena, - CERTAuthInfoAccess **info, - SECItem *dest); -- cgit v1.2.1