diff options
Diffstat (limited to 'security/nss/lib/certdb')
23 files changed, 0 insertions, 14732 deletions
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 916f09cbe..000000000 --- a/security/nss/lib/certdb/alg1485.c +++ /dev/null @@ -1,1159 +0,0 @@ -/* alg1485.c - implementation of RFCs 1485, 1779 and 2253. - * - * 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 "prprf.h" -#include "cert.h" -#include "xconst.h" -#include "genname.h" -#include "secitem.h" -#include "secerr.h" - -/* for better RFC 2253 compliance. */ -#define NSS_STRICT_RFC_2253_VALUES_ONLY 1 - -struct NameToKind { - const char * name; - unsigned int maxLen; /* max bytes in UTF8 encoded string value */ - SECOidTag kind; -}; - -/* Add new entries to this table, and maybe to function CERT_ParseRFC1485AVA */ -static const struct NameToKind name2kinds[] = { -/* keywords given in RFC 2253 */ - { "CN", 64, SEC_OID_AVA_COMMON_NAME }, - { "L", 128, SEC_OID_AVA_LOCALITY }, - { "ST", 128, SEC_OID_AVA_STATE_OR_PROVINCE }, - { "O", 64, SEC_OID_AVA_ORGANIZATION_NAME }, - { "OU", 64, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME }, - { "C", 2, SEC_OID_AVA_COUNTRY_NAME }, - { "STREET", 128, SEC_OID_AVA_STREET_ADDRESS }, - { "DC", 128, SEC_OID_AVA_DC }, - { "UID", 256, SEC_OID_RFC1274_UID }, - -#ifndef NSS_STRICT_RFC_2253_KEYWORDS_ONLY -/* NSS legacy keywords */ - { "dnQualifier", 32767, SEC_OID_AVA_DN_QUALIFIER }, - { "E", 128, SEC_OID_PKCS9_EMAIL_ADDRESS }, - { "MAIL", 256, SEC_OID_RFC1274_MAIL }, - -#ifndef NSS_LEGACY_KEYWORDS_ONLY -/* values from draft-ietf-ldapbis-user-schema-05 */ - { "SN", 64, SEC_OID_AVA_SURNAME }, - { "serialNumber", 64, SEC_OID_AVA_SERIAL_NUMBER }, - { "title", 64, SEC_OID_AVA_TITLE }, - { "postalAddress", 128, SEC_OID_AVA_POSTAL_ADDRESS }, - { "postalCode", 40, SEC_OID_AVA_POSTAL_CODE }, - { "postOfficeBox", 40, SEC_OID_AVA_POST_OFFICE_BOX }, - { "givenName", 64, SEC_OID_AVA_GIVEN_NAME }, - { "initials", 64, SEC_OID_AVA_INITIALS }, - { "generationQualifier", 64, SEC_OID_AVA_GENERATION_QUALIFIER }, - { "houseIdentifier", 64, SEC_OID_AVA_HOUSE_IDENTIFIER }, -#if 0 /* removed. Not yet in any IETF draft or RFC. */ - { "pseudonym", 64, SEC_OID_AVA_PSEUDONYM }, -#endif -#endif -#endif - { 0, 256, 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)) - - -#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) == '?')) - -int -cert_AVAOidTagToMaxLen(SECOidTag tag) -{ - const struct NameToKind *n2k = name2kinds; - - while (n2k->kind != tag && n2k->kind != SEC_OID_UNKNOWN) { - ++n2k; - } - return (n2k->kind != SEC_OID_UNKNOWN) ? n2k->maxLen : -1; -} - -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 PRBool -Is7Bit(unsigned char *data, unsigned len) -{ - unsigned char ch, *end; - - end = data + len; - while (data < end) { - ch = *data++; - if ((ch & 0x80)) { - 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; - const 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 if (Is7Bit((unsigned char *)valBuf, valLen)) { - vt = SEC_ASN1_T61_STRING; - } else { - /* according to RFC3280, UTF8String is preferred encoding */ - vt = SEC_ASN1_UTF8_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; -} - -/************************************************************************/ - -typedef struct stringBufStr { - char *buffer; - unsigned offset; - unsigned size; -} stringBuf; - -#define DEFAULT_BUFFER_SIZE 200 - -static SECStatus -AppendStr(stringBuf *bufp, char *str) -{ - char *buf; - unsigned bufLen, bufSize, len; - int size = 0; - - /* Figure out how much to grow buf by (add in the '\0') */ - buf = bufp->buffer; - bufLen = bufp->offset; - len = PORT_Strlen(str); - bufSize = bufLen + len; - if (!buf) { - bufSize++; - size = PR_MAX(DEFAULT_BUFFER_SIZE,bufSize*2); - buf = (char *) PORT_Alloc(size); - bufp->size = size; - } else if (bufp->size < bufSize) { - size = bufSize*2; - buf =(char *) PORT_Realloc(buf,size); - bufp->size = size; - } - if (!buf) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - bufp->buffer = buf; - bufp->offset = 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; - char lastC = 0; - - /* need to make an initial pass to determine if quoting is needed */ - for (i = 0; i < srclen; i++) { - char c = src[i]; - reqLen++; - if (!needsQuoting && (SPECIAL_CHAR(c) || - (OPTIONAL_SPACE(c) && OPTIONAL_SPACE(lastC)))) { - /* entirety will need quoting */ - needsQuoting = PR_TRUE; - } - if (c == C_DOUBLE_QUOTE || c == C_BACKSLASH) { - /* this char will need escaping */ - reqLen++; - } - lastC = c; - } - /* if it begins or ends in optional space it needs quoting */ - if (!needsQuoting && 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; -} - -/* convert an OID to dotted-decimal representation */ -/* Returns a string that must be freed with PR_smprintf_free(), */ -char * -CERT_GetOidString(const SECItem *oid) -{ - PRUint8 *end; - PRUint8 *d; - PRUint8 *e; - char *a = NULL; - char *b; - -#define MAX_OID_LEN 1024 /* bytes */ - - if (oid->len > MAX_OID_LEN) { - PORT_SetError(SEC_ERROR_INPUT_LEN); - return NULL; - } - - /* d will point to the next sequence of bytes to decode */ - d = (PRUint8 *)oid->data; - /* end points to one past the legitimate data */ - end = &d[ oid->len ]; - - /* - * Check for our pseudo-encoded single-digit OIDs - */ - if( (*d == 0x80) && (2 == oid->len) ) { - /* Funky encoding. The second byte is the number */ - a = PR_smprintf("%lu", (PRUint32)d[1]); - if( (char *)NULL == a ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return (char *)NULL; - } - return a; - } - - for( ; d < end; d = &e[1] ) { - - for( e = d; e < end; e++ ) { - if( 0 == (*e & 0x80) ) { - break; - } - } - - if( ((e-d) > 4) || (((e-d) == 4) && (*d & 0x70)) ) { - /* More than a 32-bit number */ - } else { - PRUint32 n = 0; - - switch( e-d ) { - case 4: - n |= ((PRUint32)(e[-4] & 0x0f)) << 28; - case 3: - n |= ((PRUint32)(e[-3] & 0x7f)) << 21; - case 2: - n |= ((PRUint32)(e[-2] & 0x7f)) << 14; - case 1: - n |= ((PRUint32)(e[-1] & 0x7f)) << 7; - case 0: - n |= ((PRUint32)(e[-0] & 0x7f)) ; - } - - if( (char *)NULL == a ) { - /* This is the first number.. decompose it */ - PRUint32 one = PR_MIN(n/40, 2); /* never > 2 */ - PRUint32 two = n - one * 40; - - a = PR_smprintf("OID.%lu.%lu", one, two); - if( (char *)NULL == a ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return (char *)NULL; - } - } else { - b = PR_smprintf("%s.%lu", a, n); - if( (char *)NULL == b ) { - PR_smprintf_free(a); - PORT_SetError(SEC_ERROR_NO_MEMORY); - return (char *)NULL; - } - - PR_smprintf_free(a); - a = b; - } - } - } - - return a; -} - -/* convert DER-encoded hex to a string */ -static SECItem * -get_hex_string(SECItem *data) -{ - SECItem *rv; - unsigned int i, j; - static const char hex[] = { "0123456789ABCDEF" }; - - /* '#' + 2 chars per octet + terminator */ - rv = SECITEM_AllocItem(NULL, NULL, data->len*2 + 2); - if (!rv) { - return NULL; - } - rv->data[0] = '#'; - rv->len = 1 + 2 * data->len; - for (i=0; i<data->len; i++) { - j = data->data[i]; - rv->data[2*i+1] = hex[j >> 4]; - rv->data[2*i+2] = hex[j & 15]; - } - rv->data[rv->len] = 0; - return rv; -} - -static SECStatus -AppendAVA(stringBuf *bufp, CERTAVA *ava) -{ - const struct NameToKind *n2k = name2kinds; - const char *tagName; - unsigned len, maxLen; - int tag; - SECStatus rv; - SECItem *avaValue = NULL; - char *unknownTag = NULL; - PRBool hexValue = PR_FALSE; - char tmpBuf[384]; - - tag = CERT_GetAVATag(ava); - while (n2k->kind != tag && n2k->kind != SEC_OID_UNKNOWN) { - ++n2k; - } - if (n2k->kind != SEC_OID_UNKNOWN) { - tagName = n2k->name; - } else { - /* handle unknown attribute types per RFC 2253 */ - tagName = unknownTag = CERT_GetOidString(&ava->type); - if (!tagName) - return SECFailure; - } - maxLen = n2k->maxLen; - -#ifdef NSS_STRICT_RFC_2253_VALUES_ONLY - if (!unknownTag) -#endif - avaValue = CERT_DecodeAVAValue(&ava->value); - if(!avaValue) { - /* the attribute value is not recognized, get the hex value */ - avaValue = get_hex_string(&ava->value); - if(!avaValue) { - if (unknownTag) PR_smprintf_free(unknownTag); - return SECFailure; - } - hexValue = PR_TRUE; - } - - /* Check value length */ - if (avaValue->len > maxLen) { - if (unknownTag) PR_smprintf_free(unknownTag); - SECITEM_FreeItem(avaValue, PR_TRUE); - PORT_SetError(SEC_ERROR_INVALID_AVA); - return SECFailure; - } - - len = PORT_Strlen(tagName); - if (len+1 > sizeof(tmpBuf)) { - if (unknownTag) PR_smprintf_free(unknownTag); - SECITEM_FreeItem(avaValue, PR_TRUE); - PORT_SetError(SEC_ERROR_OUTPUT_LEN); - return SECFailure; - } - PORT_Memcpy(tmpBuf, tagName, len); - if (unknownTag) PR_smprintf_free(unknownTag); - tmpBuf[len++] = '='; - - /* escape and quote as necessary - don't quote hex strings */ - if (hexValue) { - /* appent avaValue to tmpBuf */ - if (avaValue->len + len + 1 > sizeof tmpBuf) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - rv = SECFailure; - } else { - PORT_Strcpy(tmpBuf+len, (char *)avaValue->data); - rv = SECSuccess; - } - } else - 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, tmpBuf); - return rv; -} - -char * -CERT_NameToAscii(CERTName *name) -{ - CERTRDN** rdns; - CERTRDN** lastRdn; - CERTRDN** rdn; - PRBool first = PR_TRUE; - stringBuf strBuf = { NULL, 0, 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--) { - CERTAVA** avas = (*rdn)->avas; - CERTAVA* ava; - PRBool newRDN = PR_TRUE; - - /* - * XXX Do we need to traverse the AVAs in reverse order, too? - */ - while (avas && (ava = *avas++) != NULL) { - SECStatus rv; - /* Put in comma or plus separator */ - if (!first) { - /* Use of spaces is deprecated in RFC 2253. */ - rv = AppendStr(&strBuf, newRDN ? "," : "+"); - if (rv) goto loser; - } else { - first = PR_FALSE; - } - - /* Add in tag type plus value into buf */ - rv = AppendAVA(&strBuf, ava); - if (rv) goto loser; - newRDN = PR_FALSE; - } - } - return strBuf.buffer; -loser: - if (strBuf.buffer) { - PORT_Free(strBuf.buffer); - } - 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_QuickDERDecodeItem(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(PRArenaPool *arena, CERTName *name, int wantedTag) -{ - CERTRDN** rdns; - CERTRDN *rdn; - char *buf = 0; - - rdns = name->rdns; - while (rdns && (rdn = *rdns++) != 0) { - CERTAVA** avas = rdn->avas; - CERTAVA* ava; - while (avas && (ava = *avas++) != 0) { - int tag = CERT_GetAVATag(ava); - if ( tag == wantedTag ) { - SECItem *decodeItem = CERT_DecodeAVAValue(&ava->value); - if(!decodeItem) { - return NULL; - } - if (arena) { - buf = (char *)PORT_ArenaZAlloc(arena,decodeItem->len + 1); - } else { - 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; - SECItem subAltName; - SECStatus rv; - CERTGeneralName *nameList = NULL; - CERTGeneralName *current; - PRArenaPool *arena = NULL; - int i; - - subAltName.data = NULL; - - rawEmailAddr = CERT_GetNameElement(cert->arena, &(cert->subject), - SEC_OID_PKCS9_EMAIL_ADDRESS); - if ( rawEmailAddr == NULL ) { - rawEmailAddr = CERT_GetNameElement(cert->arena, &(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(cert->arena, - &(current->name.directoryName), - SEC_OID_PKCS9_EMAIL_ADDRESS); - if ( rawEmailAddr == NULL ) { - rawEmailAddr = CERT_GetNameElement(cert->arena, - &(current->name.directoryName), SEC_OID_RFC1274_MAIL); - } - } else if (current->type == certRFC822Name) { - rawEmailAddr = (char*)PORT_ArenaZAlloc(cert->arena, - 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) { - for (i = 0; i <= (int) PORT_Strlen(rawEmailAddr); i++) { - rawEmailAddr[i] = tolower(rawEmailAddr[i]); - } - } - -finish: - - /* 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(rawEmailAddr); -} - -static char * -appendStringToBuf(char *dest, char *src, PRUint32 *pRemaining) -{ - PRUint32 len; - if (dest && src && src[0] && *pRemaining > (len = PL_strlen(src))) { - PRUint32 i; - for (i = 0; i < len; ++i) - dest[i] = tolower(src[i]); - dest[len] = 0; - dest += len + 1; - *pRemaining -= len + 1; - } - return dest; -} - -static char * -appendItemToBuf(char *dest, SECItem *src, PRUint32 *pRemaining) -{ - if (dest && src && src->data && src->len && src->data[0] && - *pRemaining > src->len + 1 ) { - PRUint32 len = src->len; - PRUint32 i; - for (i = 0; i < len && src->data[i] ; ++i) - dest[i] = tolower(src->data[i]); - dest[len] = 0; - dest += len + 1; - *pRemaining -= len + 1; - } - return dest; -} - -/* Returns a pointer to an environment-like string, a series of -** null-terminated strings, terminated by a zero-length string. -** This function is intended to be internal to NSS. -*/ -char * -cert_GetCertificateEmailAddresses(CERTCertificate *cert) -{ - char * rawEmailAddr = NULL; - char * addrBuf = NULL; - char * pBuf = NULL; - PRArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - PRUint32 maxLen = 0; - PRInt32 finalLen = 0; - SECStatus rv; - SECItem subAltName; - - if (!tmpArena) - return addrBuf; - - subAltName.data = NULL; - maxLen = cert->derCert.len; - PORT_Assert(maxLen); - if (!maxLen) - maxLen = 2000; /* a guess, should never happen */ - - pBuf = addrBuf = (char *)PORT_ArenaZAlloc(tmpArena, maxLen + 1); - if (!addrBuf) - goto loser; - - rawEmailAddr = CERT_GetNameElement(tmpArena, &cert->subject, - SEC_OID_PKCS9_EMAIL_ADDRESS); - pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen); - - rawEmailAddr = CERT_GetNameElement(tmpArena, &cert->subject, - SEC_OID_RFC1274_MAIL); - pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen); - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, - &subAltName); - if (rv == SECSuccess && subAltName.data) { - CERTGeneralName *nameList = NULL; - - if (!!(nameList = CERT_DecodeAltNameExtension(tmpArena, &subAltName))) { - CERTGeneralName *current = nameList; - do { - if (current->type == certDirectoryName) { - rawEmailAddr = CERT_GetNameElement(tmpArena, - ¤t->name.directoryName, - SEC_OID_PKCS9_EMAIL_ADDRESS); - pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen); - - rawEmailAddr = CERT_GetNameElement(tmpArena, - ¤t->name.directoryName, - SEC_OID_RFC1274_MAIL); - pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen); - } else if (current->type == certRFC822Name) { - pBuf = appendItemToBuf(pBuf, ¤t->name.other, &maxLen); - } - current = cert_get_next_general_name(current); - } while (current != nameList); - } - SECITEM_FreeItem(&subAltName, PR_FALSE); - /* Don't free nameList, it's part of the tmpArena. */ - } - /* now copy superstring to cert's arena */ - finalLen = (pBuf - addrBuf) + 1; - pBuf = NULL; - if (finalLen > 1) { - pBuf = PORT_ArenaAlloc(cert->arena, finalLen); - if (pBuf) { - PORT_Memcpy(pBuf, addrBuf, finalLen); - } - } -loser: - if (tmpArena) - PORT_FreeArena(tmpArena, PR_FALSE); - - return pBuf; -} - -/* returns pointer to storage in cert's arena. Storage remains valid -** as long as cert's reference count doesn't go to zero. -** Caller should strdup or otherwise copy. -*/ -const char * /* const so caller won't muck with it. */ -CERT_GetFirstEmailAddress(CERTCertificate * cert) -{ - if (cert && cert->emailAddr && cert->emailAddr[0]) - return (const char *)cert->emailAddr; - return NULL; -} - -/* returns pointer to storage in cert's arena. Storage remains valid -** as long as cert's reference count doesn't go to zero. -** Caller should strdup or otherwise copy. -*/ -const char * /* const so caller won't muck with it. */ -CERT_GetNextEmailAddress(CERTCertificate * cert, const char * prev) -{ - if (cert && prev && prev[0]) { - PRUint32 len = PL_strlen(prev); - prev += len + 1; - if (prev && prev[0]) - return prev; - } - return NULL; -} - -/* This is seriously bogus, now that certs store their email addresses in -** subject Alternative Name extensions. -** Returns a string allocated by PORT_StrDup, which the caller must free. -*/ -char * -CERT_GetCertEmailAddress(CERTName *name) -{ - char *rawEmailAddr; - char *emailAddr; - - - rawEmailAddr = CERT_GetNameElement(NULL, name, SEC_OID_PKCS9_EMAIL_ADDRESS); - if ( rawEmailAddr == NULL ) { - rawEmailAddr = CERT_GetNameElement(NULL, name, SEC_OID_RFC1274_MAIL); - } - emailAddr = CERT_FixupEmailAddr(rawEmailAddr); - if ( rawEmailAddr ) { - PORT_Free(rawEmailAddr); - } - return(emailAddr); -} - -/* The return value must be freed with PORT_Free. */ -char * -CERT_GetCommonName(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_COMMON_NAME)); -} - -char * -CERT_GetCountryName(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_COUNTRY_NAME)); -} - -char * -CERT_GetLocalityName(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_LOCALITY)); -} - -char * -CERT_GetStateName(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_STATE_OR_PROVINCE)); -} - -char * -CERT_GetOrgName(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATION_NAME)); -} - -char * -CERT_GetDomainComponentName(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_DC)); -} - -char * -CERT_GetOrgUnitName(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME)); -} - -char * -CERT_GetDnQualifier(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_AVA_DN_QUALIFIER)); -} - -char * -CERT_GetCertUid(CERTName *name) -{ - return(CERT_GetNameElement(NULL, name, SEC_OID_RFC1274_UID)); -} - diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h deleted file mode 100644 index a154cba78..000000000 --- a/security/nss/lib/certdb/cert.h +++ /dev/null @@ -1,1448 +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. -** Returns a string that must be freed with PORT_Free(). -*/ -extern char *CERT_NameToAscii(CERTName *name); - -extern CERTAVA *CERT_CopyAVA(PRArenaPool *arena, CERTAVA *src); - -/* convert an OID to dotted-decimal representation */ -/* Returns a string that must be freed with PR_smprintf_free(). */ -extern char * CERT_GetOidString(const SECItem *oid); - -/* -** 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(const CERTAVA *a, const 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); - -/* -** The cert lib considers a cert or CRL valid if the "notBefore" time is -** in the not-too-distant future, e.g. within the next 24 hours. This -** prevents freshly issued certificates from being considered invalid -** because the local system's time zone is incorrectly set. -** The amount of "pending slop time" is adjustable by the application. -** Units of SlopTime are seconds. Default is 86400 (24 hours). -** Negative SlopTime values are not allowed. -*/ -PRInt32 CERT_GetSlopTime(void); - -SECStatus CERT_SetSlopTime(PRInt32 slop); - -/* -** 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 certificate -*/ -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); - -extern int CERT_GetDBContentVersion(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); -extern CERTCertificate * -CERT_NewTempCertificate (CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER); - - -/****************************************************************************** - * - * 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); - -extern SECStatus CERT_SerialNumberFromDERCert(SECItem *derCert, - SECItem *derName); - - -/* -** 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); - -/* - * same as CERT_DecodeDERCrl, plus allow options to be passed in - */ - -extern CERTSignedCrl * -CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl, - int type, PRInt32 options); - -/* CRL options to pass */ - -#define CRL_DECODE_DEFAULT_OPTIONS 0x00000000 - -/* when CRL_DECODE_DONT_COPY_DER is set, the DER is not copied . The - application must then keep derSignedCrl until it destroys the - CRL . Ideally, it should allocate derSignedCrl in an arena - and pass that arena in as the first argument to - CERT_DecodeDERCrlWithFlags */ - -#define CRL_DECODE_DONT_COPY_DER 0x00000001 -#define CRL_DECODE_SKIP_ENTRIES 0x00000002 -#define CRL_DECODE_KEEP_BAD_CRL 0x00000004 - -/* complete the decoding of a partially decoded CRL, ie. decode the - entries. Note that entries is an optional field in a CRL, so the - "entries" pointer in CERTCrlStr may still be NULL even after - function returns SECSuccess */ - -extern SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl); - -/* 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); - -/* this is a hint to flush the CRL cache. crlKey is the DER subject of - the issuer (CA). */ -void CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey); - -/* -** Decode a certificate and put it into the temporary certificate database -*/ -extern CERTCertificate * -CERT_DecodeCertificate (SECItem *derCert, char *nickname,PRBool copyDER); - -/* -** Find a certificate in the database -** "key" is the database key to look for -*/ -extern CERTCertificate *CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *key); - -/* -** 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 subject key ID -** "subjKeyID" is the subject Key ID to look for -*/ -extern CERTCertificate * -CERT_FindCertBySubjectKeyID (CERTCertDBHandle *handle, SECItem *subjKeyID); - -/* -** 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); - -/* -** 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, - PRTime 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, PRTime *notBefore, PRTime *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 the signature of a signed data object with the given DER publickey -*/ -extern SECStatus -CERT_VerifySignedDataWithPublicKeyInfo(CERTSignedData *sd, - CERTSubjectPublicKeyInfo *pubKeyInfo, - void *wincx); - -/* -** verify the signature of a signed data object with a SECKEYPublicKey. -*/ -extern SECStatus -CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd, - SECKEYPublicKey *pubKey, void *wincx); - -/* -** NEW FUNCTIONS with new bit-field-FIELD SECCertificateUsage - please use -** 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_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertificateUsage requiredUsages, - int64 t, void *wincx, CERTVerifyLog *log, - SECCertificateUsage* returnedUsages); - -/* same as above, but uses current time */ -extern SECStatus -CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertificateUsage requiredUsages, - void *wincx, SECCertificateUsage* returnedUsages); - -/* -** Verify that a CA cert can certify some (unspecified) leaf cert for a given -** purpose. This is used by UI code to help identify where a chain may be -** broken and why. This takes identical parameters to CERT_VerifyCert -*/ -extern SECStatus -CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, int64 t, - void *wincx, CERTVerifyLog *log); - -/* -** OLD OBSOLETE FUNCTIONS with enum SECCertUsage - DO NOT USE FOR NEW CODE -** 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); - -SECStatus -CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, int64 t, - void *wincx, CERTVerifyLog *log); - -/* -** 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); - -extern SECStatus -CERT_ImportCAChainTrusted(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 (PR_CALLBACK *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(const SECItem *derAVAValue); - -/* - * take a DER certificate and decode it into a certificate structure - */ -CERTCertificate * -CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, - char *nickname); - - - -/* -** extract various element strings from a distinguished name. -** "name" the distinguished name -*/ - -extern char *CERT_GetCertificateEmailAddress(CERTCertificate *cert); - -extern char *CERT_GetCertEmailAddress(CERTName *name); - -extern const char * CERT_GetFirstEmailAddress(CERTCertificate * cert); - -extern const char * CERT_GetNextEmailAddress(CERTCertificate * cert, - const char * prev); - -/* The return value must be freed with PORT_Free. */ -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); - - -extern SECStatus -CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue); - - -/* -** 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_FindSubjectKeyIDExtension (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 CERTCertificateList * -CERT_DupCertList(CERTCertificateList * oldList); - -extern void CERT_DestroyCertificateList(CERTCertificateList *list); - -/* -** is cert a user cert? i.e. does it have CERTDB_USER trust, -** i.e. a private key? -*/ -PRBool CERT_IsUserCert(CERTCertificate* cert); - -/* is cert a newer than cert b? */ -PRBool CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb); - -/* 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); - -PRBool -CERT_IsCADERCert(SECItem *derCert, unsigned int *rettype); - -PRBool -CERT_IsRootDERCert(SECItem *derCert); - -SECStatus -CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, - SECItem *profileTime); - -/* - * find the smime symmetric capabilities profile for a given cert - */ -SECItem * -CERT_FindSMimeProfile(CERTCertificate *cert); - -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); - -SECStatus -CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert); - -SECStatus -CERT_AddCertToListTailWithData(CERTCertList *certs, CERTCertificate *cert, - void *appData); - -SECStatus -CERT_AddCertToListHeadWithData(CERTCertList *certs, CERTCertificate *cert, - void *appData); - -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); - - -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); - -/* - * Filter a list of certificates, removing those certs that aren't user certs - */ -SECStatus -CERT_FilterCertListForUserCerts(CERTCertList *certList); - -/* - * 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); - -/* - * 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); - -/* - * fill in nsCertType field of the cert based on the cert extension - */ -extern SECStatus cert_GetCertType(CERTCertificate *cert); - - -SECStatus CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer, - SECItem* dp, int64 t, void* wincx); - - -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 6c19f2605..000000000 --- a/security/nss/lib/certdb/certdb.c +++ /dev/null @@ -1,2914 +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 "nssilock.h" -#include "prmon.h" -#include "prtime.h" -#include "cert.h" -#include "certi.h" -#include "secder.h" -#include "secoid.h" -#include "secasn1.h" -#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 "pk11func.h" -#include "xconst.h" /* for CERT_DecodeAltNameExtension */ - -#ifndef NSS_3_4_CODE -#define NSS_3_4_CODE -#endif /* NSS_3_4_CODE */ -#include "pki.h" -#include "pki3hack.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 subjectName in a DER encoded certificate - */ -const SEC_ASN1Template SEC_CertSerialNumberTemplate[] = { - { 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_ANY, 0, NULL }, /* serial number */ - { 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 } -}; - -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(SEC_SignedCertificateTemplate) - -SECStatus -CERT_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn, - SECItem *key) -{ - key->len = sn->len + issuer->len; - - if ((sn->data == NULL) || (issuer->data == NULL)) { - goto loser; - } - - 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_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); - - if ( rv ) { - goto loser; - } - - PORT_Memset(derName, 0, sizeof(SECItem)); - rv = SEC_QuickDERDecodeItem(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_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); - - if ( rv ) { - goto loser; - } - - PORT_Memset(derName, 0, sizeof(SECItem)); - rv = SEC_QuickDERDecodeItem(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); -} - -SECStatus -CERT_SerialNumberFromDERCert(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_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert); - - if ( rv ) { - goto loser; - } - - PORT_Memset(derName, 0, sizeof(SECItem)); - rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate, &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)); - 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; - unsigned int nsCertType = 0; - - if (cert->nsCertType) { - /* once set, no need to recalculate */ - return SECSuccess; - } - - 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) { - nsCertType = 0; - } else { - 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 ( ( nsCertType & NS_CERT_TYPE_SSL_CLIENT ) && - cert->emailAddr && cert->emailAddr[0]) { - nsCertType |= NS_CERT_TYPE_EMAIL; - } - /* - * for this release, we will allow SSL intermediate CAs to be - * email intermediate CAs too. - */ - if ( nsCertType & NS_CERT_TYPE_SSL_CA ) { - 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)) { - nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } else { - nsCertType |= NS_CERT_TYPE_EMAIL; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) == - SECSuccess){ - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - nsCertType |= NS_CERT_TYPE_SSL_CA; - } else { - nsCertType |= NS_CERT_TYPE_SSL_SERVER; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) == - SECSuccess){ - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - nsCertType |= NS_CERT_TYPE_SSL_CA; - } else { - nsCertType |= NS_CERT_TYPE_SSL_CLIENT; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_CODE_SIGN) == - SECSuccess) { - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA; - } else { - nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_TIME_STAMP) == - SECSuccess) { - nsCertType |= EXT_KEY_USAGE_TIME_STAMP; - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_OCSP_RESPONDER) == - SECSuccess) { - nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } - } else { - /* if no extension, then allow any ssl or email (no ca or object - * signing) - */ - 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)) { - nsCertType |= NS_CERT_TYPE_SSL_CA; - nsCertType |= NS_CERT_TYPE_EMAIL_CA; - nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } else if (CERT_IsCACert(cert, NULL) == PR_TRUE) { - nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } - - /* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */ - if (fortezzaIsCA(cert)) { - nsCertType |= NS_CERT_TYPE_SSL_CA; - nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } - } - - if (extKeyUsage != NULL) { - PORT_Free(encodedExtKeyUsage.data); - CERT_DestroyOidSequence(extKeyUsage); - } - PR_AtomicSet(&cert->nsCertType, nsCertType); - 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_FindSubjectKeyIDExtension(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 = PK11_HashBuf(SEC_OID_SHA1,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); - -} - -static PRBool -cert_IsRootCert(CERTCertificate *cert) -{ - SECStatus rv; - SECItem tmpitem; - - /* cache the authKeyID extension, if present */ - cert->authKeyID = CERT_FindAuthKeyIDExten(cert->arena, cert); - - /* it MUST be self-issued to be a root */ - if (cert->derIssuer.len == 0 || - !SECITEM_ItemsAreEqual(&cert->derIssuer, &cert->derSubject)) - { - return PR_FALSE; - } - - /* check the authKeyID extension */ - if (cert->authKeyID) { - /* authority key identifier is present */ - if (cert->authKeyID->keyID.len > 0) { - /* the keyIdentifier field is set, look for subjectKeyID */ - rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem); - if (rv == SECSuccess) { - PRBool match; - /* also present, they MUST match for it to be a root */ - match = SECITEM_ItemsAreEqual(&cert->authKeyID->keyID, - &tmpitem); - PORT_Free(tmpitem.data); - if (!match) return PR_FALSE; /* else fall through */ - } else { - /* the subject key ID is required when AKI is present */ - return PR_FALSE; - } - } - if (cert->authKeyID->authCertIssuer) { - SECItem *caName; - caName = (SECItem *)CERT_GetGeneralNameByType( - cert->authKeyID->authCertIssuer, - certDirectoryName, PR_TRUE); - if (caName) { - if (!SECITEM_ItemsAreEqual(&cert->derIssuer, caName)) { - return PR_FALSE; - } /* else fall through */ - } /* else ??? could not get general name as directory name? */ - } - if (cert->authKeyID->authCertSerialNumber.len > 0) { - if (!SECITEM_ItemsAreEqual(&cert->serialNumber, - &cert->authKeyID->authCertSerialNumber)) { - return PR_FALSE; - } /* else fall through */ - } - /* all of the AKI fields that were present passed the test */ - return PR_TRUE; - } - /* else the AKI was not present, so this is a root */ - return PR_TRUE; -} - -/* - * 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_QuickDERDecodeItem(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_KeyFromIssuerAndSN(arena, &cert->derIssuer, &cert->serialNumber, - &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_GetCertificateEmailAddresses(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; - } - - /* determine if this is a root cert */ - cert->isRoot = cert_IsRootCert(cert); - - 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_HANDLE; - cert->dbnickname = NULL; - - return(cert); - -loser: - - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(0); -} - -CERTCertificate * -__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, - char *nickname) -{ - return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname); -} - - -/* -** 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) /* seconds per day */ -static PRInt32 pendingSlop = PENDING_SLOP; /* seconds */ - -PRInt32 -CERT_GetSlopTime(void) -{ - return pendingSlop; /* seconds */ -} - -SECStatus -CERT_SetSlopTime(PRInt32 slop) /* seconds */ -{ - if (slop < 0) - return SECFailure; - pendingSlop = slop; - return SECSuccess; -} - -SECStatus -CERT_GetCertTimes(CERTCertificate *c, PRTime *notBefore, PRTime *notAfter) -{ - SECStatus rv; - - if (!c || !notBefore || !notAfter) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* convert DER not-before time */ - rv = CERT_DecodeTimeChoice(notBefore, &c->validity.notBefore); - if (rv) { - return(SECFailure); - } - - /* convert DER not-after time */ - rv = CERT_DecodeTimeChoice(notAfter, &c->validity.notAfter); - if (rv) { - return(SECFailure); - } - - return(SECSuccess); -} - -/* - * Check the validity times of a certificate - */ -SECCertTimeValidity -CERT_CheckCertValidTimes(CERTCertificate *c, PRTime t, PRBool allowOverride) -{ - PRTime notBefore, notAfter, llPendingSlop, tmp1; - 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(llPendingSlop, pendingSlop); - /* convert to micro seconds */ - LL_UI2L(tmp1, PR_USEC_PER_SEC); - LL_MUL(llPendingSlop, llPendingSlop, tmp1); - LL_SUB(notBefore, notBefore, llPendingSlop); - 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, PRTime *notBefore, PRTime *notAfter) -{ - int rv; - - /* convert DER not-before time */ - rv = CERT_DecodeTimeChoice(notBefore, &date->lastUpdate); - if (rv) { - return(SECFailure); - } - - /* convert DER not-after time */ - if (date->nextUpdate.data) { - rv = CERT_DecodeTimeChoice(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, PRTime t) { - PRTime notBefore, notAfter, llPendingSlop, tmp1; - SECStatus rv; - - rv = SEC_GetCrlTimes(crl, ¬Before, ¬After); - - if (rv) { - return(secCertTimeExpired); - } - - LL_I2L(llPendingSlop, pendingSlop); - /* convert to micro seconds */ - LL_I2L(tmp1, PR_USEC_PER_SEC); - LL_MUL(llPendingSlop, llPendingSlop, tmp1); - LL_SUB(notBefore, notBefore, llPendingSlop); - 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) { - PRTime newNotBefore, newNotAfter; - PRTime 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) -{ - if (!cert) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* choose between key agreement or key encipherment based on key - * type in cert - */ - if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) { - SECKEYPublicKey *key = CERT_ExtractPublicKey(cert); - if (!key) - return SECFailure; - 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) { -#ifdef NSS_CLASSIC - CERT_LockCertRefCount(c); - ++c->referenceCount; - CERT_UnlockCertRefCount(c); -#else - NSSCertificate *tmp = STAN_GetNSSCertificate(c); - nssCertificate_AddRef(tmp); -#endif - } - 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); -} - -/* 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; -} - -/* returns SECSuccess if hn matches pattern cn, -** returns SECFailure with SSL_ERROR_BAD_CERT_DOMAIN if no match, -** returns SECFailure with some other error code if another error occurs. -** -** may modify cn, so caller must pass a modifiable copy. -*/ -static SECStatus -cert_TestHostName(char * cn, const char * hn) -{ - char * hndomain; - int regvalid; - - if ((hndomain = PORT_Strchr(hn, '.')) == NULL) { - /* No domain in URI host name */ - char * cndomain; - if ((cndomain = PORT_Strchr(cn, '.')) != NULL && - (cndomain - cn) > 0) { - /* there is a domain in the cn string, so chop it off */ - *cndomain = '\0'; - } - } - - regvalid = PORT_RegExpValid(cn); - if (regvalid != NON_SXP) { - SECStatus rv; - /* cn is a regular expression, try to match the shexp */ - int match = PORT_RegExpCaseSearch(hn, cn); - - if ( match == 0 ) { - rv = SECSuccess; - } else { - PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); - rv = SECFailure; - } - return rv; - } - /* cn is not a regular expression */ - - /* compare entire hn with cert name */ - if (PORT_Strcasecmp(hn, cn) == 0) { - return SECSuccess; - } - - if ( hndomain ) { - /* compare just domain name with cert name */ - if ( PORT_Strcasecmp(hndomain+1, cn) == 0 ) { - return SECSuccess; - } - } - - PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); - return SECFailure; -} - - -SECStatus -cert_VerifySubjectAltName(CERTCertificate *cert, const char *hn) -{ - PRArenaPool * arena = NULL; - CERTGeneralName * nameList = NULL; - CERTGeneralName * current; - char * cn; - int cnBufLen; - unsigned int hnLen; - int DNSextCount = 0; - int IPextCount = 0; - PRBool isIPaddr; - SECStatus rv = SECFailure; - SECItem subAltName; - PRNetAddr netAddr; - char cnbuf[128]; - - subAltName.data = NULL; - hnLen = strlen(hn); - cn = cnbuf; - cnBufLen = sizeof cnbuf; - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, - &subAltName); - if (rv != SECSuccess) { - goto finish; - } - isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr)); - rv = SECFailure; - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!arena) - goto finish; - - nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName); - if (!current) - goto finish; - - do { - switch (current->type) { - case certDNSName: - if (!isIPaddr) { - /* DNS name current->name.other.data is not null terminated. - ** so must copy it. - */ - int cnLen = current->name.other.len; - if (cnLen + 1 > cnBufLen) { - cnBufLen = cnLen + 1; - cn = (char *)PORT_ArenaAlloc(arena, cnBufLen); - if (!cn) - goto finish; - } - PORT_Memcpy(cn, current->name.other.data, cnLen); - cn[cnLen] = 0; - rv = cert_TestHostName(cn ,hn); - if (rv == SECSuccess) - goto finish; - } - DNSextCount++; - break; - case certIPAddress: - if (isIPaddr) { - int match = 0; - PRIPv6Addr v6Addr; - if (current->name.other.len == 4 && /* IP v4 address */ - netAddr.inet.family == PR_AF_INET) { - match = !memcmp(&netAddr.inet.ip, - current->name.other.data, 4); - } else if (current->name.other.len == 16 && /* IP v6 address */ - netAddr.ipv6.family == PR_AF_INET6) { - match = !memcmp(&netAddr.ipv6.ip, - current->name.other.data, 16); - } else if (current->name.other.len == 16 && /* IP v6 address */ - netAddr.inet.family == PR_AF_INET) { - /* convert netAddr to ipv6, then compare. */ - /* ipv4 must be in Network Byte Order on input. */ - PR_ConvertIPv4AddrToIPv6(netAddr.inet.ip, &v6Addr); - match = !memcmp(&v6Addr, current->name.other.data, 16); - } else if (current->name.other.len == 4 && /* IP v4 address */ - netAddr.inet.family == PR_AF_INET6) { - /* convert netAddr to ipv6, then compare. */ - PRUint32 ipv4 = (current->name.other.data[0] << 24) | - (current->name.other.data[1] << 16) | - (current->name.other.data[2] << 8) | - current->name.other.data[3]; - /* ipv4 must be in Network Byte Order on input. */ - PR_ConvertIPv4AddrToIPv6(PR_htonl(ipv4), &v6Addr); - match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16); - } - if (match) { - rv = SECSuccess; - goto finish; - } - } - IPextCount++; - break; - default: - break; - } - current = cert_get_next_general_name(current); - } while (current != nameList); - - if ((!isIPaddr && !DNSextCount) || (isIPaddr && !IPextCount)) { - /* no relevant value in the extension was found. */ - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); - } else { - PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); - } - rv = SECFailure; - -finish: - - /* 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 rv; -} - - -/* 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; - SECStatus rv; - CERTOKDomainName *domainOK; - - if (!hn || !strlen(hn)) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* 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_Strcasecmp(hn, domainOK->name)) { - return SECSuccess; - } - } - - /* Per RFC 2818, if the SubjectAltName extension is present, it must - ** be used as the cert's identity. - */ - rv = cert_VerifySubjectAltName(cert, hn); - if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) - return rv; - - /* try the cert extension first, then the common name */ - cn = CERT_FindNSStringExtension(cert, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME); - if ( !cn ) { - cn = CERT_GetCommonName(&cert->subject); - } - if ( cn ) { - rv = cert_TestHostName(cn, hn); - PORT_Free(cn); - } else - PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); - 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) { - org = CERT_GetDomainComponentName(&cert->issuer); - if (org == NULL) { - if (firstname) { - org = firstname; - firstname = NULL; - } else { - org = PORT_Strdup("Unknown CA"); - } - } - } - - /* can only fail if PORT_Strdup fails, in which case - * we're having memory problems. */ - 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->trust && (cert->trust->sslFlags|cert->trust->emailFlags| - cert->trust->objectSigningFlags)) { - trust = cert->trust; - if ( ( ( trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) || - ( ( trust->sslFlags & CERTDB_TRUSTED_CA ) == CERTDB_TRUSTED_CA ) ) { - ret = PR_TRUE; - type |= NS_CERT_TYPE_SSL_CA; - } - - if ( ( ( trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) || - ( ( trust->emailFlags & CERTDB_TRUSTED_CA ) == CERTDB_TRUSTED_CA ) ) { - ret = PR_TRUE; - type |= NS_CERT_TYPE_EMAIL_CA; - } - - if ( ( ( trust->objectSigningFlags & CERTDB_VALID_CA ) - == CERTDB_VALID_CA ) || - ( ( trust->objectSigningFlags & CERTDB_TRUSTED_CA ) - == CERTDB_TRUSTED_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); - } - } - } - - /* the isRoot flag trumps all */ - if (cert->isRoot) { - ret = PR_TRUE; - /* set only these by default, same as above */ - type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA); - } - - if ( rettype != NULL ) { - *rettype = type; - } - - return(ret); -} - -PRBool -CERT_IsCADERCert(SECItem *derCert, unsigned int *type) { - CERTCertificate *cert; - PRBool isCA; - - /* This is okay -- only looks at extensions */ - cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); - if (cert == NULL) return PR_FALSE; - - isCA = CERT_IsCACert(cert,type); - CERT_DestroyCertificate (cert); - return isCA; -} - -PRBool -CERT_IsRootDERCert(SECItem *derCert) -{ - CERTCertificate *cert; - PRBool isRoot; - - /* This is okay -- only looks at extensions */ - cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); - if (cert == NULL) return PR_FALSE; - - isRoot = cert->isRoot; - CERT_DestroyCertificate (cert); - return isRoot; -} - - -/* - * is certa newer than certb? If one is expired, pick the other one. - */ -PRBool -CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb) -{ - PRTime 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 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) -{ - unsigned 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); -} - -/* in 3.4, this will only set trust */ -SECStatus -CERT_SaveImportedCert(CERTCertificate *cert, SECCertUsage usage, - PRBool caOnly, char *nickname) -{ - SECStatus rv; - PRBool saveit; - CERTCertTrust trust; - PRBool isCA; - unsigned int certtype; - - isCA = CERT_IsCACert(cert, NULL); - if ( caOnly && ( !isCA ) ) { - return(SECSuccess); - } - /* In NSS 3.4, certs are given zero trust upon import. However, this - * function needs to set up default CA trust (CERTDB_VALID_CA), or - * PKCS#12 imported certs will not show up correctly. In the case of a - * CA cert with zero trust, continue with this function. But if the cert - * does already have some trust bits, exit and do not change them. - */ - if (isCA && cert->trust && - (cert->trust->sslFlags | - cert->trust->emailFlags | - cert->trust->objectSigningFlags)) { - 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; - } - - switch ( usage ) { - case certUsageEmailSigner: - case certUsageEmailRecipient: - if ( isCA ) { - if ( certtype & NS_CERT_TYPE_EMAIL_CA ) { - trust.emailFlags = CERTDB_VALID_CA; - } - } else { - if ( !cert->emailAddr || !cert->emailAddr[0] ) { - 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; - case certUsageAnyCA: - trust.sslFlags = CERTDB_VALID_CA; - break; - case certUsageSSLCA: - trust.sslFlags = CERTDB_VALID_CA | - CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; - break; - default: /* XXX added to quiet warnings; no other cases needed? */ - break; - } - - if ( saveit ) { - rv = CERT_ChangeCertTrust(cert->dbhandle, cert, &trust); - if ( rv != SECSuccess ) { - goto loser; - } - } - - rv = SECSuccess; - goto done; - -loser: - rv = SECFailure; -done: - - return(rv); -} - -SECStatus -CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage, - unsigned int ncerts, SECItem **derCerts, - CERTCertificate ***retCerts, PRBool keepCerts, - PRBool caOnly, char *nickname) -{ - unsigned int i; - CERTCertificate **certs = NULL; - SECStatus rv; - unsigned int fcerts = 0; - - if ( ncerts ) { - certs = PORT_ZNewArray(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++ ) { - char* canickname = NULL; - PRBool freeNickname = PR_FALSE; - - SECKEY_UpdateCertPQG(certs[i]); - - if ( CERT_IsCACert(certs[i], NULL) ) { - canickname = CERT_MakeCANickname(certs[i]); - if ( canickname != NULL ) { - freeNickname = PR_TRUE; - } - } - - 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. But we still may try - * the individual canickname from the cert itself. - */ - rv = CERT_AddTempCertToPerm(certs[i], canickname, NULL); - } else { - rv = CERT_AddTempCertToPerm(certs[i], - nickname?nickname:canickname, NULL); - } - if (rv == SECSuccess) { - CERT_SaveImportedCert(certs[i], usage, caOnly, NULL); - } - - if (PR_TRUE == freeNickname) { - PORT_Free(canickname); - } - /* don't care if it fails - keep going */ - } - } - } - - if ( retCerts ) { - *retCerts = certs; - } else { - if (certs) { - CERT_DestroyCertArray(certs, fcerts); - } - } - - return (fcerts ? SECSuccess : SECFailure); -} - -/* - * 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_AddCertToListTailWithData(CERTCertList *certs, - CERTCertificate *cert, void *appData) -{ - 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; - node->appData = appData; - return(SECSuccess); - -loser: - return(SECFailure); -} - -SECStatus -CERT_AddCertToListTail(CERTCertList *certs, CERTCertificate *cert) -{ - return CERT_AddCertToListTailWithData(certs, cert, NULL); -} - -SECStatus -CERT_AddCertToListHeadWithData(CERTCertList *certs, - CERTCertificate *cert, void *appData) -{ - CERTCertListNode *node; - CERTCertListNode *head; - - head = CERT_LIST_HEAD(certs); - - if (head == NULL) return CERT_AddCertToListTail(certs,cert); - - node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena, - sizeof(CERTCertListNode)); - if ( node == NULL ) { - goto loser; - } - - PR_INSERT_BEFORE(&node->links, &head->links); - /* certs->count++; */ - node->cert = cert; - node->appData = appData; - return(SECSuccess); - -loser: - return(SECFailure); -} - -SECStatus -CERT_AddCertToListHead(CERTCertList *certs, CERTCertificate *cert) -{ - return CERT_AddCertToListHeadWithData(certs, cert, NULL); -} - -/* - * 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) -{ - PRTime sorttime; - PRTime notBeforeA, notAfterA, notBeforeB, notAfterB; - SECStatus rv; - PRBool newerbefore, newerafter; - PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE; - - sorttime = *(PRTime *)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; - SECStatus rv; - - 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) ) { - - PRBool bad = (PRBool)(!node->cert); - - /* bad key usage ? */ - if ( !bad && - CERT_CheckKeyUsage(node->cert, requiredKeyUsage) != SECSuccess ) { - bad = PR_TRUE; - } - /* bad cert type ? */ - if ( !bad ) { - unsigned int certType = 0; - 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. - */ - (void)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); -} - -PRBool CERT_IsUserCert(CERTCertificate* cert) -{ - if ( cert->trust && - ((cert->trust->sslFlags & CERTDB_USER ) || - (cert->trust->emailFlags & CERTDB_USER ) || - (cert->trust->objectSigningFlags & CERTDB_USER )) ) { - return PR_TRUE; - } else { - return PR_FALSE; - } -} - -SECStatus -CERT_FilterCertListForUserCerts(CERTCertList *certList) -{ - CERTCertListNode *node, *freenode; - CERTCertificate *cert; - - if (!certList) { - return SECFailure; - } - - node = CERT_LIST_HEAD(certList); - - while ( ! CERT_LIST_END(node, certList) ) { - cert = node->cert; - if ( PR_TRUE != CERT_IsUserCert(cert) ) { - /* Not a User Cert, so remove this cert from the list */ - freenode = node; - node = CERT_LIST_NEXT(node); - CERT_RemoveCertListNode(freenode); - } else { - /* Is a User cert, so leave it in the list */ - node = CERT_LIST_NEXT(node); - } - } - - return(SECSuccess); -} - -static PZLock *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, nssILockRefLock); - PORT_Assert(certRefCountLock != NULL); - } - - PZ_Lock(certRefCountLock); - return; -} - -/* - * Free the cert reference count lock - */ -void -CERT_UnlockCertRefCount(CERTCertificate *cert) -{ - PRStatus prstat; - - PORT_Assert(certRefCountLock != NULL); - - prstat = PZ_Unlock(certRefCountLock); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - -static PZLock *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, nssILockCertDB); - PORT_Assert(certTrustLock != NULL); - } - - PZ_Lock(certTrustLock); - return; -} - -/* - * Free the cert trust lock - */ -void -CERT_UnlockCertTrust(CERTCertificate *cert) -{ - PRStatus prstat; - - PORT_Assert(certTrustLock != NULL); - - prstat = PZ_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; -} - -/* - * Code for dealing with subjKeyID to cert mappings. - */ - -static PLHashTable *gSubjKeyIDHash = NULL; -static PRLock *gSubjKeyIDLock = NULL; - -static void *cert_AllocTable(void *pool, PRSize size) -{ - return PORT_Alloc(size); -} - -static void cert_FreeTable(void *pool, void *item) -{ - PORT_Free(item); -} - -static PLHashEntry* cert_AllocEntry(void *pool, const void *key) -{ - return PORT_New(PLHashEntry); -} - -static void cert_FreeEntry(void *pool, PLHashEntry *he, PRUintn flag) -{ - SECITEM_FreeItem((SECItem*)(he->value), PR_TRUE); - if (flag == HT_FREE_ENTRY) { - SECITEM_FreeItem((SECItem*)(he->key), PR_TRUE); - PORT_Free(he); - } -} - -static PLHashAllocOps cert_AllocOps = { - cert_AllocTable, cert_FreeTable, cert_AllocEntry, cert_FreeEntry -}; - -SECStatus -cert_CreateSubjectKeyIDHashTable(void) -{ - gSubjKeyIDHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, - SECITEM_HashCompare, - &cert_AllocOps, NULL); - if (!gSubjKeyIDHash) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - gSubjKeyIDLock = PR_NewLock(); - if (!gSubjKeyIDLock) { - PL_HashTableDestroy(gSubjKeyIDHash); - gSubjKeyIDHash = NULL; - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - return SECSuccess; - -} - -SECStatus -cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert) -{ - SECItem *newKeyID, *oldVal, *newVal; - SECStatus rv = SECFailure; - - if (!gSubjKeyIDLock) { - /* If one is created, then both are there. So only check for one. */ - return SECFailure; - } - - newVal = SECITEM_DupItem(&cert->derCert); - if (!newVal) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto done; - } - newKeyID = SECITEM_DupItem(subjKeyID); - if (!newKeyID) { - SECITEM_FreeItem(newVal, PR_TRUE); - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto done; - } - - PR_Lock(gSubjKeyIDLock); - /* The hash table implementation does not free up the memory - * associated with the key of an already existing entry if we add a - * duplicate, so we would wind up leaking the previously allocated - * key if we don't remove before adding. - */ - oldVal = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID); - if (oldVal) { - PL_HashTableRemove(gSubjKeyIDHash, subjKeyID); - } - - rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess : - SECFailure; - PR_Unlock(gSubjKeyIDLock); -done: - return rv; -} - -SECStatus -cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID) -{ - SECStatus rv; - if (!gSubjKeyIDLock) - return SECFailure; - - PR_Lock(gSubjKeyIDLock); - rv = (PL_HashTableRemove(gSubjKeyIDHash, subjKeyID)) ? SECSuccess : - SECFailure; - PR_Unlock(gSubjKeyIDLock); - return rv; -} - -SECStatus -cert_DestroySubjectKeyIDHashTable(void) -{ - if (gSubjKeyIDHash) { - PR_Lock(gSubjKeyIDLock); - PL_HashTableDestroy(gSubjKeyIDHash); - gSubjKeyIDHash = NULL; - PR_Unlock(gSubjKeyIDLock); - PR_DestroyLock(gSubjKeyIDLock); - gSubjKeyIDLock = NULL; - } - return SECSuccess; -} - -SECItem* -cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID) -{ - SECItem *val; - - if (!gSubjKeyIDLock) - return NULL; - - PR_Lock(gSubjKeyIDLock); - val = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID); - if (val) { - val = SECITEM_DupItem(val); - } - PR_Unlock(gSubjKeyIDLock); - return val; -} - -CERTCertificate* -CERT_FindCertBySubjectKeyID(CERTCertDBHandle *handle, SECItem *subjKeyID) -{ - CERTCertificate *cert = NULL; - SECItem *derCert; - - derCert = cert_FindDERCertBySubjectKeyID(subjKeyID); - if (derCert) { - cert = CERT_FindCertByDERCert(handle, derCert); - SECITEM_FreeItem(derCert, PR_TRUE); - } - return cert; -} diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h deleted file mode 100644 index 6dd7d85b4..000000000 --- a/security/nss/lib/certdb/certdb.h +++ /dev/null @@ -1,161 +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_ - - -/* 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 - -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); - -PRBool -SEC_CertNicknameConflict(char *nickname, SECItem *derSubject, - CERTCertDBHandle *handle); -CERTSignedCrl * -SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type); - -SECStatus -SEC_DeletePermCRL(CERTSignedCrl *crl); - - -SECStatus -SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type); - -SECStatus -SEC_DestroyCrl(CERTSignedCrl *crl); - -CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl); - -SECStatus -CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, - CERTCertTrust *trust); - -SECStatus SEC_DeletePermCertificate(CERTCertificate *cert); - -PRBool -SEC_CrlIsNewer(CERTCrl *inNew, CERTCrl *old); - -SECCertTimeValidity -SEC_CheckCrlTimes(CERTCrl *crl, PRTime t); - -#ifdef notdef -/* -** 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(PCERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PCERTCertTrust *trust); - -certDBEntryCert * -SEC_FindPermCertByKey(PCERTCertDBHandle *handle, SECItem *certKey); - -certDBEntryCert -*SEC_FindPermCertByName(PCERTCertDBHandle *handle, SECItem *name); - -SECStatus SEC_OpenPermCertDB(PCERTCertDBHandle *handle, - PRBool readOnly, - PCERTDBNameFunc namecb, - void *cbarg); - - -typedef SECStatus (PR_CALLBACK * PermCertCallback)(PCERTCertificate *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 -PCERT_TraversePermCerts(PCERTCertDBHandle *handle, - PermCertCallback certfunc, - void *udata ); - -SECStatus -SEC_AddTempNickname(PCERTCertDBHandle *handle, char *nickname, SECItem *certKey); - -SECStatus -SEC_DeleteTempNickname(PCERTCertDBHandle *handle, char *nickname); - - -PRBool -SEC_CertDBKeyConflict(SECItem *derCert, PCERTCertDBHandle *handle); - -SECStatus -SEC_GetCrlTimes(PCERTCrl *dates, PRTime *notBefore, PRTime *notAfter); - -PCERTSignedCrl * -SEC_AddPermCrlToTemp(PCERTCertDBHandle *handle, certDBEntryRevocation *entry); - -SECStatus -SEC_DeleteTempCrl(PCERTSignedCrl *crl); - - -SECStatus -SEC_CheckKRL(PCERTCertDBHandle *handle,SECKEYLowPublicKey *key, - PCERTCertificate *rootCert, int64 t, void *wincx); - -SECStatus -SEC_CheckCRL(PCERTCertDBHandle *handle,PCERTCertificate *cert, - PCERTCertificate *caCert, int64 t, void *wincx); - -SECStatus -SEC_CrlReplaceUrl(PCERTSignedCrl *crl,char *url); -#endif - -SEC_END_PROTOS - -#endif /* _CERTDB_H_ */ diff --git a/security/nss/lib/certdb/certi.h b/security/nss/lib/certdb/certi.h deleted file mode 100644 index 87cf6f8b8..000000000 --- a/security/nss/lib/certdb/certi.h +++ /dev/null @@ -1,216 +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. - */ -/* - * certi.h - private data structures for the certificate library - * - * $Id$ - */ -#ifndef _CERTI_H_ -#define _CERTI_H_ - -#include "certt.h" -#include "nssrwlkt.h" - -#define USE_RWLOCK 1 - -/* all definitions in this file are subject to change */ - -typedef struct OpaqueCRLFieldsStr OpaqueCRLFields; -typedef struct CRLEntryCacheStr CRLEntryCache; -typedef struct CRLDPCacheStr CRLDPCache; -typedef struct CRLIssuerCacheStr CRLIssuerCache; -typedef struct CRLCacheStr CRLCache; - -struct OpaqueCRLFieldsStr { - PRBool partial; - PRBool badEntries; - PRBool bad; - PRBool badDER; - PRBool badExtensions; - PRBool deleted; - PRBool heapDER; - PRBool unverified; -}; - -typedef struct PreAllocatorStr PreAllocator; - -struct PreAllocatorStr -{ - PRSize len; - void* data; - PRSize used; - PRArenaPool* arena; - PRSize extra; -}; - -/* CRL entry cache. - This is the same as an entry plus the next/prev pointers for the hash table -*/ - -struct CRLEntryCacheStr { - CERTCrlEntry entry; - CRLEntryCache *prev, *next; -}; - -#define CRL_CACHE_INVALID_CRLS 0x0001 /* this state will be set - if we have CRL objects with an invalid DER or signature. Can be - cleared if the invalid objects are deleted from the token */ -#define CRL_CACHE_LAST_FETCH_FAILED 0x0002 /* this state will be set - if the last CRL fetch encountered an error. Can be cleared if a - new fetch succeeds */ - -#define CRL_CACHE_OUT_OF_MEMORY 0x0004 /* this state will be set - if we don't have enough memory to build the hash table of entries */ - -/* CRL distribution point cache object - This is a cache of CRL entries for a given distribution point of an issuer - It is built from a collection of one full and 0 or more delta CRLs. -*/ - -struct CRLDPCacheStr { -#ifdef USE_RWLOCK - NSSRWLock* lock; -#else - PRLock* lock; -#endif - CERTCertificate* issuer; /* cert issuer */ - SECItem* subject; /* DER of issuer subject */ - SECItem* distributionPoint; /* DER of distribution point. This may be - NULL when distribution points aren't - in use (ie. the CA has a single CRL) */ - - /* hash table of entries. We use a PLHashTable and pre-allocate the - required amount of memory in one shot, so that our allocator can - simply pass offsets into it when hashing. - - This won't work anymore when we support delta CRLs and iCRLs, because - the size of the hash table will vary over time. At that point, the best - solution will be to allocate large CRLEntry structures by modifying - the DER decoding template. The extra space would be for next/prev - pointers. This would allow entries from different CRLs to be mixed in - the same hash table. - */ - PLHashTable* entries; - PreAllocator* prebuffer; /* big pre-allocated buffer mentioned above */ - - /* array of CRLs matching this distribution point */ - PRUint32 ncrls; /* total number of CRLs in crls */ - CERTSignedCrl** crls; /* array of all matching DER CRLs - from all tokens */ - /* XCRL With iCRLs and multiple DPs, the CRL can be shared accross several - issuers. In the future, we'll need to globally recycle the CRL in a - separate list in order to avoid extra lookups, decodes, and copies */ - - /* pointers to good decoded CRLs used to build the cache */ - CERTSignedCrl* full; /* full CRL used for the cache */ -#if 0 - /* for future use */ - PRInt32 numdeltas; /* number of delta CRLs used for the cache */ - CERTSignedCrl** deltas; /* delta CRLs used for the cache */ -#endif - /* invalidity bitflag */ - PRUint16 invalid; /* this state will be set if either - CRL_CACHE_INVALID_CRLS or CRL_CACHE_LAST_FETCH_FAILED is set. - In those cases, all certs are considered revoked as a - security precaution. The invalid state can only be cleared - during an update if all error states are cleared */ -}; - -/* CRL issuer cache object - This object tracks all the distribution point caches for a given issuer. - XCRL once we support multiple issuing distribution points, this object - will be a hash table. For now, it just holds the single CRL distribution - point cache structure. -*/ - -struct CRLIssuerCacheStr { - SECItem* subject; /* DER of issuer subject */ - CRLDPCache dp; /* DER of distribution point */ - CRLDPCache* dpp; -#if 0 - /* XCRL for future use. - We don't need to lock at the moment because we only have one DP, - which gets created at the same time as this object */ - NSSRWLock* lock; - CRLDPCache** dps; - PLHashTable* distributionpoints; - CERTCertificate* issuer; -#endif -}; - -/* CRL revocation cache object - This object tracks all the issuer caches -*/ - -struct CRLCacheStr { - PRLock* lock; - /* hash table of issuer to CRLIssuerCacheStr, - indexed by issuer DER subject */ - PLHashTable* issuers; -}; - -SECStatus InitCRLCache(void); -SECStatus ShutdownCRLCache(void); - -/* Returns a pointer to an environment-like string, a series of -** null-terminated strings, terminated by a zero-length string. -** This function is intended to be internal to NSS. -*/ -extern char * cert_GetCertificateEmailAddresses(CERTCertificate *cert); - -/* - * These functions are used to map subjectKeyID extension values to certs. - */ -SECStatus -cert_CreateSubjectKeyIDHashTable(void); - -SECStatus -cert_AddSubjectKeyIDMapping(SECItem *subjKeyID, CERTCertificate *cert); - -/* - * Call this function to remove an entry from the mapping table. - */ -SECStatus -cert_RemoveSubjectKeyIDMapping(SECItem *subjKeyID); - -SECStatus -cert_DestroySubjectKeyIDHashTable(void); - -SECItem* -cert_FindDERCertBySubjectKeyID(SECItem *subjKeyID); - -/* return maximum length of AVA value based on its type OID tag. */ -extern int cert_AVAOidTagToMaxLen(SECOidTag tag); - -#endif /* _CERTI_H_ */ - diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h deleted file mode 100644 index e502bfdda..000000000 --- a/security/nss/lib/certdb/certt.h +++ /dev/null @@ -1,855 +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 "nssilock.h" -#include "prio.h" -#include "prmon.h" - -/* Stan data types */ -struct NSSCertificateStr; -struct NSSTrustDomainStr; - -/* Non-opaque objects */ -typedef struct CERTAVAStr CERTAVA; -typedef struct CERTAttributeStr CERTAttribute; -typedef struct CERTAuthInfoAccessStr CERTAuthInfoAccess; -typedef struct CERTAuthKeyIDStr CERTAuthKeyID; -typedef struct CERTBasicConstraintsStr CERTBasicConstraints; -#ifdef NSS_CLASSIC -typedef struct CERTCertDBHandleStr CERTCertDBHandle; -#else -typedef struct NSSTrustDomainStr CERTCertDBHandle; -#endif -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; -}; - -struct CERTCertTrustStr { - unsigned int sslFlags; - unsigned int emailFlags; - unsigned int objectSigningFlags; -}; - -/* - * defined the types of trust that exist - */ -typedef enum SECTrustTypeEnum { - trustSSL = 0, - trustEmail = 1, - trustObjectSigning = 2, - trustTypeNone = 3 -} 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? */ - void *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; - struct NSSCertificateStr *nssCertificate; /* This is Stan stuff. */ - 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 belong in the static section, but are here to maintain - * the structure's integrity - */ - CERTAuthKeyID * authKeyID; /* x509v3 authority key identifier */ - PRBool isRoot; /* cert is the end of a chain */ - - /* 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 *authsocketlist; - int series; /* was int authsocketcount; record the series of the pkcs11ID */ - - /* 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)) -#define CERT_LIST_EMPTY(l) CERT_LIST_END(CERT_LIST_HEAD(l), l) - -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; - /* can't add anything there for binary backwards compatibility reasons */ -}; - -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; - void *reserved1; - PRBool reserved2; - PRBool isperm; - PRBool istemp; - int referenceCount; - CERTCertDBHandle *dbhandle; - CERTSignedData signatureWrap; /* XXX */ - char *url; - SECItem *derCrl; - PK11SlotInfo *slot; - CK_OBJECT_HANDLE pkcs11ID; - void* opaque; /* do not touch */ -}; - - -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 SECCertUsageEnum { - certUsageSSLClient = 0, - certUsageSSLServer = 1, - certUsageSSLServerWithStepUp = 2, - certUsageSSLCA = 3, - certUsageEmailSigner = 4, - certUsageEmailRecipient = 5, - certUsageObjectSigner = 6, - certUsageUserCertImport = 7, - certUsageVerifyCA = 8, - certUsageProtectedObjectSigner = 9, - certUsageStatusResponder = 10, - certUsageAnyCA = 11 -} SECCertUsage; - -typedef PRInt64 SECCertificateUsage; - -#define certificateUsageSSLClient (0x0001) -#define certificateUsageSSLServer (0x0002) -#define certificateUsageSSLServerWithStepUp (0x0004) -#define certificateUsageSSLCA (0x0008) -#define certificateUsageEmailSigner (0x0010) -#define certificateUsageEmailRecipient (0x0020) -#define certificateUsageObjectSigner (0x0040) -#define certificateUsageUserCertImport (0x0080) -#define certificateUsageVerifyCA (0x0100) -#define certificateUsageProtectedObjectSigner (0x0200) -#define certificateUsageStatusResponder (0x0400) -#define certificateUsageAnyCA (0x0800) - -#define certificateUsageHighest certificateUsageAnyCA - -/* - * Does the cert belong to the user, a peer, or a CA. - */ -typedef enum CERTCertOwnerEnum { - certOwnerUser = 0, - certOwnerPeer = 1, - certOwnerCA = 2 -} CERTCertOwner; - -/* - * This enum represents the state of validity times of a certificate - */ -typedef enum SECCertTimeValidityEnum { - secCertTimeValid = 0, - secCertTimeExpired = 1, - secCertTimeNotValidYet = 2 -} 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 CERTGeneralNameTypeEnum { - 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; - PZLock *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 DistributionPointTypesEnum { - 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 CERTPackageTypeEnum { - certPackageNone = 0, - certPackageCert = 1, - certPackagePKCS7 = 2, - certPackageNSCertSeq = 3, - certPackageNSCertWrap = 4 -} 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 */ - -SEC_BEGIN_PROTOS - -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_TimeChoiceTemplate[]; -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[]; - -/* These functions simply return the address of the above-declared templates. -** This is necessary for Windows DLLs. Sigh. -*/ -SEC_ASN1_CHOOSER_DECLARE(CERT_CertificateRequestTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_CertificateTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_CrlTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_NameTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_SetOfSignedCrlTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_SignedDataTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_SubjectPublicKeyInfoTemplate) -SEC_ASN1_CHOOSER_DECLARE(SEC_SignedCertificateTemplate) -SEC_ASN1_CHOOSER_DECLARE(CERT_TimeChoiceTemplate) - -SEC_END_PROTOS - -#endif /* _CERTT_H_ */ diff --git a/security/nss/lib/certdb/certv3.c b/security/nss/lib/certdb/certv3.c deleted file mode 100644 index f4e11b3ae..000000000 --- a/security/nss/lib/certdb/certv3.c +++ /dev/null @@ -1,415 +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; - unsigned 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_QuickDERDecodeItem(arena, &urlstringitem, SEC_IA5StringTemplate, - &urlitem); - - if ( rv != SECSuccess ) { - goto loser; - } - if ( hasbase ) { - rv = SEC_QuickDERDecodeItem(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_QuickDERDecodeItem(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_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem) -{ - - SECStatus rv; - SECItem encodedValue = {siBuffer, NULL, 0 }; - SECItem decodedValue = {siBuffer, NULL, 0 }; - - rv = cert_FindExtension - (cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue); - if (rv == SECSuccess) { - PLArenaPool * tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (tmpArena) { - rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue, - SEC_OctetStringTemplate, - &encodedValue); - if (rv == SECSuccess) { - rv = SECITEM_CopyItem(NULL, retItem, &decodedValue); - } - PORT_FreeArena(tmpArena, PR_FALSE); - } else { - rv = SECFailure; - } - } - SECITEM_FreeItem(&encodedValue, PR_FALSE); - 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 9e9fa9b97..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_QuickDERDecodeItem(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 0a00dc61e..000000000 --- a/security/nss/lib/certdb/config.mk +++ /dev/null @@ -1,43 +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 = -PROGRAM = - diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c deleted file mode 100644 index d3d07db92..000000000 --- a/security/nss/lib/certdb/crl.c +++ /dev/null @@ -1,1952 +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 "certi.h" -#include "secder.h" -#include "secasn1.h" -#include "secoid.h" -#include "certdb.h" -#include "certxutl.h" -#include "prtime.h" -#include "secerr.h" -#include "pk11func.h" -#include "dev.h" -#include "dev3hack.h" -#include "nssbase.h" -#ifdef USE_RWLOCK -#include "nssrwlk.h" -#endif - -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_INLINE, - offsetof(CERTCrlEntry,revocationDate), CERT_TimeChoiceTemplate }, - { 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_INLINE, - offsetof(CERTCrl,lastUpdate), CERT_TimeChoiceTemplate }, - { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, - offsetof(CERTCrl,nextUpdate), CERT_TimeChoiceTemplate }, - { 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 } -}; - -const SEC_ASN1Template CERT_CrlTemplateNoEntries[] = { - { 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_INLINE, - offsetof(CERTCrl,lastUpdate), CERT_TimeChoiceTemplate }, - { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, - offsetof(CERTCrl,nextUpdate), CERT_TimeChoiceTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF | - SEC_ASN1_SKIP }, /* skip entries */ - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_EXPLICIT | 0, - offsetof(CERTCrl,extensions), - SEC_CERTExtensionsTemplate }, - { 0 } -}; - -const SEC_ASN1Template CERT_CrlTemplateEntriesOnly[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrl) }, - { SEC_ASN1_SKIP | SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL }, - { SEC_ASN1_SKIP }, - { SEC_ASN1_SKIP }, - { SEC_ASN1_SKIP | SEC_ASN1_INLINE, - offsetof(CERTCrl,lastUpdate), CERT_TimeChoiceTemplate }, - { SEC_ASN1_SKIP | SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, - offsetof(CERTCrl,nextUpdate), CERT_TimeChoiceTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCrl,entries), - cert_CrlEntryTemplate }, /* decode entries */ - { SEC_ASN1_SKIP_REST }, - { 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 } -}; - -static const SEC_ASN1Template cert_SignedCrlTemplateNoEntries[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTSignedCrl) }, - { SEC_ASN1_SAVE, - offsetof(CERTSignedCrl,signatureWrap.data) }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedCrl,crl), - CERT_CrlTemplateNoEntries }, - { 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) { - 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); - - 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); -} - -#define GetOpaqueCRLFields(x) ((OpaqueCRLFields*)x->opaque) - -/* -PRBool CERT_CRLIsInvalid(CERTSignedCrl* crl) -{ - OpaqueCRLFields* extended = NULL; - - if (crl && (extended = (OpaqueCRLFields*) crl->opaque)) { - return extended->bad; - } - return PR_TRUE; -} -*/ - -SECStatus CERT_CompleteCRLDecodeEntries(CERTSignedCrl* crl) -{ - SECStatus rv = SECSuccess; - SECItem* crldata = NULL; - OpaqueCRLFields* extended = NULL; - - if ( (!crl) || - (!(extended = (OpaqueCRLFields*) crl->opaque)) ) { - rv = SECFailure; - } else { - if (PR_FALSE == extended->partial) { - /* the CRL has already been fully decoded */ - return SECSuccess; - } - if (PR_TRUE == extended->badEntries) { - /* the entries decoding already failed */ - return SECFailure; - } - crldata = &crl->signatureWrap.data; - if (!crldata) { - rv = SECFailure; - } - } - - if (SECSuccess == rv) { - rv = SEC_QuickDERDecodeItem(crl->arena, - &crl->crl, - CERT_CrlTemplateEntriesOnly, - crldata); - if (SECSuccess == rv) { - extended->partial = PR_FALSE; /* successful decode, avoid - decoding again */ - } else { - extended->bad = PR_TRUE; - extended->badEntries = PR_TRUE; - /* cache the decoding failure. If it fails the first time, - it will fail again, which will grow the arena and leak - memory, so we want to avoid it */ - } - } - return rv; -} - -/* - * take a DER CRL or KRL and decode it into a CRL structure - * allow reusing the input DER without making a copy - */ -CERTSignedCrl * -CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl, - int type, PRInt32 options) -{ - PRArenaPool *arena; - CERTSignedCrl *crl; - SECStatus rv; - OpaqueCRLFields* extended = NULL; - const SEC_ASN1Template* crlTemplate = cert_SignedCrlTemplate; - - /* 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 ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - crl->arena = arena; - - /* allocate opaque fields */ - crl->opaque = (void*)PORT_ArenaZAlloc(arena, sizeof(OpaqueCRLFields)); - if ( !crl->opaque ) { - goto loser; - } - extended = (OpaqueCRLFields*) crl->opaque; - - if (options & CRL_DECODE_DONT_COPY_DER) { - crl->derCrl = derSignedCrl; /* DER is not copied . The application - must keep derSignedCrl until it - destroys the CRL */ - } else { - crl->derCrl = (SECItem *)PORT_ArenaZAlloc(arena,sizeof(SECItem)); - if (crl->derCrl == NULL) { - goto loser; - } - rv = SECITEM_CopyItem(arena, crl->derCrl, derSignedCrl); - if (rv != SECSuccess) { - goto loser; - } - } - - /* Save the arena in the inner crl for CRL extensions support */ - crl->crl.arena = arena; - if (options & CRL_DECODE_SKIP_ENTRIES) { - crlTemplate = cert_SignedCrlTemplateNoEntries; - extended->partial = PR_TRUE; - } - - /* decode the CRL info */ - switch (type) { - case SEC_CRL_TYPE: - rv = SEC_QuickDERDecodeItem(arena, crl, crlTemplate, crl->derCrl); - if (rv != SECSuccess) { - extended->badDER = PR_TRUE; - break; - } - /* check for critical extentions */ - rv = cert_check_crl_version (&crl->crl); - if (rv != SECSuccess) { - extended->badExtensions = PR_TRUE; - } - break; - - case SEC_KRL_TYPE: - rv = SEC_QuickDERDecodeItem - (arena, crl, cert_SignedKrlTemplate, derSignedCrl); - break; - default: - rv = SECFailure; - break; - } - - if (rv != SECSuccess) { - goto loser; - } - - crl->referenceCount = 1; - - return(crl); - -loser: - if (options & CRL_DECODE_KEEP_BAD_CRL) { - extended->bad = PR_TRUE; - crl->referenceCount = 1; - return(crl); - } - - if ((narena == NULL) && arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(0); -} - -/* - * take a DER CRL or KRL and decode it into a CRL structure - */ -CERTSignedCrl * -CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) -{ - return CERT_DecodeDERCrlWithFlags(narena, derSignedCrl, type, CRL_DECODE_DEFAULT_OPTIONS); -} - -/* - * Lookup a CRL in the databases. We mirror the same fast caching data base - * caching stuff used by certificates....? - * return values : - * - * SECSuccess means we got a valid DER CRL (passed in "decoded"), or no CRL at all - * - * SECFailure means we got a fatal error - most likely, we found a CRL, - * and it failed decoding, or there was an out of memory error. Do NOT ignore - * it and specifically do NOT treat it the same as having no CRL, as this - * can compromise security !!! Ideally, you should treat this case as if you - * received a "catch-all" CRL where all certs you were looking up are - * considered to be revoked - */ -static SECStatus -SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, - CERTSignedCrl** decoded, PRInt32 decodeoptions) -{ - SECStatus rv = SECSuccess; - CERTSignedCrl *crl = NULL; - SECItem *derCrl = NULL; - CK_OBJECT_HANDLE crlHandle = 0; - char *url = NULL; - int nsserror; - - PORT_Assert(decoded); - if (!decoded) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* XXX it would be really useful to be able to fetch the CRL directly into an - arena. This would avoid a copy later on in the decode step */ - PORT_SetError(0); - derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey, type, &url); - if (derCrl == NULL) { - /* if we had a problem other than the CRL just didn't exist, return - * a failure to the upper level */ - nsserror = PORT_GetError(); - if ((nsserror != 0) && (nsserror != SEC_ERROR_CRL_NOT_FOUND)) { - rv = SECFailure; - } - goto loser; - } - PORT_Assert(crlHandle != CK_INVALID_HANDLE); - /* PK11_FindCrlByName obtained a slot reference. */ - - crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, type, decodeoptions); - if (crl) { - crl->slot = slot; - slot = NULL; /* adopt it */ - crl->pkcs11ID = crlHandle; - if (url) { - crl->url = PORT_ArenaStrdup(crl->arena,url); - } - } else { - rv = SECFailure; - } - - if (url) { - PORT_Free(url); - } - - if (slot) { - PK11_FreeSlot(slot); - } - -loser: - if (derCrl) { - /* destroy the DER, unless a decoded CRL was returned with DER - allocated on the heap. This is solely for cache purposes */ - if (crl && (decodeoptions & CRL_DECODE_DONT_COPY_DER)) { - /* mark the DER as having come from the heap instead of the - arena, so it can be destroyed */ - GetOpaqueCRLFields(crl)->heapDER = PR_TRUE; - } else { - SECITEM_FreeItem(derCrl, PR_TRUE); - } - } - - *decoded = crl; - - return rv; -} - -SECStatus SEC_DestroyCrl(CERTSignedCrl *crl); - -CERTSignedCrl * -crl_storeCRL (PK11SlotInfo *slot,char *url, - CERTSignedCrl *newCrl, SECItem *derCrl, int type) -{ - CERTSignedCrl *oldCrl = NULL, *crl = NULL; - PRBool deleteOldCrl = PR_FALSE; - CK_OBJECT_HANDLE crlHandle = CK_INVALID_HANDLE; - - PORT_Assert(newCrl); - PORT_Assert(derCrl); - - /* we can't use the cache here because we must look in the same - token */ - SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type, - &oldCrl, CRL_DECODE_SKIP_ENTRIES); - - /* if there is an old crl on the token, make sure the one we are - installing is newer. If not, exit out, otherwise delete the - old crl. - */ - if (oldCrl != NULL) { - /* if it's already there, quietly continue */ - if (SECITEM_CompareItem(newCrl->derCrl, oldCrl->derCrl) - == SECEqual) { - crl = newCrl; - crl->slot = PK11_ReferenceSlot(slot); - crl->pkcs11ID = oldCrl->pkcs11ID; - goto done; - } - 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) { - url = oldCrl->url; - } - - /* really destroy this crl */ - /* first drum it out of the permanment Data base */ - deleteOldCrl = PR_TRUE; - } - - /* invalidate CRL cache for this issuer */ - CERT_CRLCacheRefreshIssuer(NULL, &newCrl->crl.derName); - /* Write the new entry into the data base */ - crlHandle = PK11_PutCrl(slot, derCrl, &newCrl->crl.derName, url, type); - if (crlHandle != CK_INVALID_HANDLE) { - crl = newCrl; - crl->slot = PK11_ReferenceSlot(slot); - crl->pkcs11ID = crlHandle; - if (url) { - crl->url = PORT_ArenaStrdup(crl->arena,url); - } - } - -done: - if (oldCrl) { - if (deleteOldCrl && crlHandle != CK_INVALID_HANDLE) { - SEC_DeletePermCRL(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* retCrl = NULL; - PK11SlotInfo* slot = PK11_GetInternalKeySlot(); - retCrl = PK11_ImportCRL(slot, derCrl, url, type, NULL, - CRL_IMPORT_BYPASS_CHECKS, NULL, CRL_DECODE_DEFAULT_OPTIONS); - PK11_FreeSlot(slot); - - return retCrl; -} - -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_FindCrlByName(handle, &crlKey, type); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(crl); -} - -CERTSignedCrl* SEC_DupCrl(CERTSignedCrl* acrl) -{ - if (acrl) - { - PR_AtomicIncrement(&acrl->referenceCount); - return acrl; - } - return NULL; -} - -SECStatus -SEC_DestroyCrl(CERTSignedCrl *crl) -{ - if (crl) { - if (PR_AtomicDecrement(&crl->referenceCount) < 1) { - if (crl->slot) { - PK11_FreeSlot(crl->slot); - } - if (PR_TRUE == GetOpaqueCRLFields(crl)->heapDER) { - SECITEM_FreeItem(crl->derCrl, PR_TRUE); - } - PORT_FreeArena(crl->arena, PR_FALSE); - } - } - return SECSuccess; -} - -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; - - rv = PK11_LookupCrls(head, type, NULL); - - if (rv != SECSuccess) { - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - *nodes = NULL; - } - } - - return rv; -} - -/* These functions simply return the address of the above-declared templates. -** This is necessary for Windows DLLs. Sigh. -*/ -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_IssuerAndSNTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CrlTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SetOfSignedCrlTemplate) - -/* -** Pre-allocator hash allocator ops. -*/ -static void * PR_CALLBACK -PreAllocTable(void *pool, PRSize size) -{ - PreAllocator* alloc = (PreAllocator*)pool; - PR_ASSERT(alloc); - if (!alloc) - { - /* no allocator, or buffer full */ - return NULL; - } - if (size > (alloc->len - alloc->used)) - { - alloc->extra += size; - return PORT_ArenaAlloc(alloc->arena, size); - } - alloc->used += size; - return (char*) alloc->data + alloc->used - size; -} - -static void PR_CALLBACK -PreFreeTable(void *pool, void *item) -{ -} - -static PLHashEntry * PR_CALLBACK -PreAllocEntry(void *pool, const void *key) -{ - return PreAllocTable(pool, sizeof(PLHashEntry)); -} - -static void PR_CALLBACK -PreFreeEntry(void *pool, PLHashEntry *he, PRUintn flag) -{ -} - -static PLHashAllocOps preAllocOps = { - PreAllocTable, PreFreeTable, - PreAllocEntry, PreFreeEntry -}; - -void PreAllocator_Destroy(PreAllocator* PreAllocator) -{ - if (!PreAllocator) - { - return; - } - if (PreAllocator->arena) - { - PORT_FreeArena(PreAllocator->arena, PR_TRUE); - } - if (PreAllocator->data) - { - PORT_Free(PreAllocator->data); - } - PORT_Free(PreAllocator); -} - -PreAllocator* PreAllocator_Create(PRSize size) -{ - PreAllocator prebuffer; - PreAllocator* prepointer = NULL; - memset(&prebuffer, 0, sizeof(PreAllocator)); - prebuffer.len = size; - prebuffer.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - PR_ASSERT(prebuffer.arena); - if (!prebuffer.arena) { - PreAllocator_Destroy(&prebuffer); - return NULL; - } - if (prebuffer.len) { - prebuffer.data = PR_Malloc(prebuffer.len); - if (!prebuffer.data) { - PreAllocator_Destroy(&prebuffer); - return NULL; - } - } else { - prebuffer.data = NULL; - } - prepointer = (PreAllocator*)PR_Malloc(sizeof(PreAllocator)); - if (!prepointer) { - PreAllocator_Destroy(&prebuffer); - return NULL; - } - *prepointer = prebuffer; - return prepointer; -} - -static CRLCache crlcache = { NULL, NULL }; - -static PRBool crlcache_initialized = PR_FALSE; - -/* this needs to be called at NSS initialization time */ - -SECStatus InitCRLCache(void) -{ - if (PR_FALSE == crlcache_initialized) - { - PR_ASSERT(NULL == crlcache.lock); - crlcache.lock = PR_NewLock(); - if (!crlcache.lock) - { - return SECFailure; - } - PR_ASSERT(NULL == crlcache.issuers); - crlcache.issuers = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, - PL_CompareValues, NULL, NULL); - if (!crlcache.issuers) - { - PR_DestroyLock(crlcache.lock); - crlcache.lock = NULL; - return SECFailure; - } - crlcache_initialized = PR_TRUE; - return SECSuccess; - } - else - { - PR_ASSERT(crlcache.lock); - PR_ASSERT(crlcache.issuers); - if ( (NULL == crlcache.lock) || (NULL == crlcache.issuers) ) - { - return SECFailure; - } - else - { - return SECSuccess; - } - } -} - -SECStatus DPCache_Destroy(CRLDPCache* cache) -{ - PRUint32 i = 0; - PR_ASSERT(cache); - if (!cache) { - return SECFailure; - } - if (cache->lock) - { -#ifdef USE_RWLOCK - NSSRWLock_Destroy(cache->lock); -#else - PR_DestroyLock(cache->lock); -#endif - } - /* destroy all our CRL objects */ - for (i=0;i<cache->ncrls;i++) - { - SEC_DestroyCrl(cache->crls[i]); - } - /* free the array of CRLs */ - if (cache->crls) - { - PR_Free(cache->crls); - } - /* destroy the hash table */ - if (cache->entries) - { - PL_HashTableDestroy(cache->entries); - } - /* free the pre buffer */ - if (cache->prebuffer) - { - PreAllocator_Destroy(cache->prebuffer); - } - /* destroy the cert */ - if (cache->issuer) - { - CERT_DestroyCertificate(cache->issuer); - } - /* free the subject */ - if (cache->subject) - { - SECITEM_FreeItem(cache->subject, PR_TRUE); - } - /* free the distribution points */ - if (cache->distributionPoint) - { - SECITEM_FreeItem(cache->distributionPoint, PR_TRUE); - } - return SECSuccess; -} - -SECStatus IssuerCache_Destroy(CRLIssuerCache* cache) -{ - PORT_Assert(cache); - if (!cache) - { - return SECFailure; - } -#if 0 - /* XCRL */ - if (cache->lock) - { - NSSRWLock_Destroy(cache->lock); - } - if (cache->issuer) - { - CERT_DestroyCertificate(cache->issuer); - } -#endif - /* free the subject */ - if (cache->subject) - { - SECITEM_FreeItem(cache->subject, PR_TRUE); - } - DPCache_Destroy(&cache->dp); - PR_Free(cache); - return SECSuccess; -} - -PRIntn PR_CALLBACK FreeIssuer(PLHashEntry *he, PRIntn i, void *arg) -{ - CRLIssuerCache* issuer = NULL; - PR_ASSERT(he); - if (!he) { - return HT_ENUMERATE_NEXT; - } - issuer = (CRLIssuerCache*) he->value; - PR_ASSERT(issuer); - if (issuer) { - IssuerCache_Destroy(issuer); - } - return HT_ENUMERATE_NEXT; -} - -SECStatus ShutdownCRLCache(void) -{ - if (!crlcache.lock || !crlcache.issuers) - { - return SECFailure; - } - /* empty the cache */ - PL_HashTableEnumerateEntries(crlcache.issuers, &FreeIssuer, NULL); - PL_HashTableDestroy(crlcache.issuers); - crlcache.issuers = NULL; - PR_DestroyLock(crlcache.lock); - crlcache.lock = NULL; - crlcache_initialized = PR_FALSE; - return SECSuccess; -} - -SECStatus DPCache_AddCRL(CRLDPCache* cache, CERTSignedCrl* crl) -{ - CERTSignedCrl** newcrls = NULL; - PORT_Assert(cache); - PORT_Assert(crl); - if (!cache || !crl) { - return SECFailure; - } - - newcrls = (CERTSignedCrl**)PORT_Realloc(cache->crls, - (cache->ncrls+1)*sizeof(CERTSignedCrl*)); - if (!newcrls) { - return SECFailure; - } - cache->crls = newcrls; - cache->ncrls++; - cache->crls[cache->ncrls-1] = crl; - return SECSuccess; -} - -SECStatus DPCache_Cleanup(CRLDPCache* cache) -{ - /* remove deleted CRLs from memory */ - PRUint32 i = 0; - PORT_Assert(cache); - if (!cache) { - return SECFailure; - } - for (i=0;i<cache->ncrls;i++) { - CERTSignedCrl* acrl = cache->crls[i]; - if (acrl && (PR_TRUE == GetOpaqueCRLFields(acrl)->deleted)) { - cache->crls[i] = cache->crls[cache->ncrls-1]; - cache->crls[cache->ncrls-1] = NULL; - cache->ncrls--; - } - } - return SECSuccess; -} - -PRBool CRLStillExists(CERTSignedCrl* crl) -{ - NSSItem newsubject; - SECItem subject; - CK_ULONG crl_class; - PRStatus status; - PK11SlotInfo* slot = NULL; - nssCryptokiObject instance; - NSSArena* arena; - PRBool xstatus = PR_TRUE; - SECItem* oldSubject = NULL; - - PORT_Assert(crl); - if (!crl) { - return PR_FALSE; - } - slot = crl->slot; - PORT_Assert(slot); - if (!slot) { - return PR_FALSE; - } - oldSubject = &crl->crl.derName; - PR_ASSERT(oldSubject); - if (!oldSubject) { - return PR_FALSE; - } - - /* query subject and type attributes in order to determine if the - object has been deleted */ - - /* first, make an nssCryptokiObject */ - instance.handle = crl->pkcs11ID; - PORT_Assert(instance.handle); - if (!instance.handle) { - return PR_FALSE; - } - instance.token = PK11Slot_GetNSSToken(slot); - PORT_Assert(instance.token); - if (!instance.token) { - return PR_FALSE; - } - instance.isTokenObject = PR_TRUE; - instance.label = NULL; - - arena = NSSArena_Create(); - PORT_Assert(arena); - if (!arena) { - return PR_FALSE; - } - - status = nssCryptokiCRL_GetAttributes(&instance, - NULL, /* XXX sessionOpt */ - arena, - NULL, - &newsubject, /* subject */ - &crl_class, /* class */ - NULL, - NULL); - if (PR_SUCCESS == status) { - subject.data = newsubject.data; - subject.len = newsubject.size; - if (SECITEM_CompareItem(oldSubject, &subject) != SECEqual) { - xstatus = PR_FALSE; - } - if (CKO_NETSCAPE_CRL != crl_class) { - xstatus = PR_FALSE; - } - } else { - xstatus = PR_FALSE; - } - NSSArena_Destroy(arena); - return xstatus; -} - -SECStatus DPCache_Refresh(CRLDPCache* cache, CERTSignedCrl* crlobject, - PRTime vfdate, void* wincx) -{ - SECStatus rv = SECSuccess; - /* Check if it is an invalid CRL - if we got a bad CRL, we want to cache it in order to avoid - subsequent fetches of this same identical bad CRL. We set - the cache to the invalid state to ensure that all certs - on this DP are considered revoked from now on. The cache - object will remain in this state until the bad CRL object - is removed from the token it was fetched from. If the cause - of the failure is that we didn't have the issuer cert to - verify the signature, this state can be cleared when - the issuer certificate becomes available if that causes the - signature to verify */ - - if (PR_TRUE == GetOpaqueCRLFields(crlobject)->bad) { - PORT_SetError(SEC_ERROR_BAD_DER); - cache->invalid |= CRL_CACHE_INVALID_CRLS; - return SECSuccess; - } else { - SECStatus signstatus = SECFailure; - if (cache->issuer) { - signstatus = CERT_VerifySignedData(&crlobject->signatureWrap, - cache->issuer, vfdate, wincx); - } - if (SECSuccess != signstatus) { - if (!cache->issuer) { - /* we tried to verify without an issuer cert . This is - because this CRL came through a call to SEC_FindCrlByName. - So we don't cache this verification failure. We'll try - to verify the CRL again when a certificate from that issuer - becomes available */ - GetOpaqueCRLFields(crlobject)->unverified = PR_TRUE; - } else { - GetOpaqueCRLFields(crlobject)->unverified = PR_FALSE; - } - PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE); - cache->invalid |= CRL_CACHE_INVALID_CRLS; - return SECSuccess; - } else { - GetOpaqueCRLFields(crlobject)->unverified = PR_FALSE; - } - } - - /* complete the entry decoding */ - rv = CERT_CompleteCRLDecodeEntries(crlobject); - if (SECSuccess == rv) { - /* XCRL : if this is a delta, add it to the hash table */ - /* for now, always build the hash table from the full CRL */ - CERTCrlEntry** crlEntry = NULL; - PRUint32 numEntries = 0; - if (cache->entries) { - /* we already have a hash table, destroy it */ - PL_HashTableDestroy(cache->entries); - cache->entries = NULL; - } - /* also destroy the PreAllocator */ - if (cache->prebuffer) - { - PreAllocator_Destroy(cache->prebuffer); - cache->prebuffer = NULL; - } - /* count CRL entries so we can pre-allocate space for hash table entries */ - for (crlEntry = crlobject->crl.entries; crlEntry && *crlEntry; crlEntry++) { - numEntries++; - } - cache->prebuffer = PreAllocator_Create(numEntries*sizeof(PLHashEntry)); - PR_ASSERT(cache->prebuffer); - if (cache->prebuffer) { - /* create a new hash table */ - cache->entries = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare, - PL_CompareValues, &preAllocOps, cache->prebuffer); - } - PR_ASSERT(cache->entries); - if (!cache->entries) { - rv = SECFailure; - } - if (SECSuccess == rv) { - /* add all serial numbers to the hash table */ - for (crlEntry = crlobject->crl.entries; crlEntry && *crlEntry; crlEntry++) { - PL_HashTableAdd(cache->entries, &(*crlEntry)->serialNumber, *crlEntry); - } - cache->full = crlobject; - cache->invalid = 0; /* valid cache */ - } else { - cache->invalid |= CRL_CACHE_OUT_OF_MEMORY; - } - } else { - cache->invalid |= CRL_CACHE_INVALID_CRLS; - } - return rv; -} - -void DPCache_Empty(CRLDPCache* cache) -{ - PRUint32 i; - PR_ASSERT(cache); - if (!cache) - { - return; - } - cache->full = NULL; - - cache->invalid = 0; - - if (cache->entries) { - /* we already have a hash table, destroy it */ - PL_HashTableDestroy(cache->entries); - cache->entries = NULL; - } - /* also destroy the PreAllocator */ - if (cache->prebuffer) - { - PreAllocator_Destroy(cache->prebuffer); - cache->prebuffer = NULL; - } - - for (i=0;i<cache->ncrls;i++) - { - CERTSignedCrl* crl = cache->crls[i]; - if (crl) - { - GetOpaqueCRLFields(crl)->deleted = PR_TRUE; - } - } -} - -SECStatus DPCache_Fetch(CRLDPCache* cache, PRTime vfdate, void* wincx) -{ - SECStatus rv = SECSuccess; - CERTSignedCrl* crlobject = NULL; - PRUint32 i=0; - /* XCRL For now, we can only get one full CRL. In the future, we'll be able to - find more than one object, because of multiple tokens and deltas */ - rv = SEC_FindCrlByKeyOnSlot(NULL, cache->subject, SEC_CRL_TYPE, - &crlobject, CRL_DECODE_DONT_COPY_DER | - CRL_DECODE_SKIP_ENTRIES | - CRL_DECODE_KEEP_BAD_CRL); - /* if this function fails, something very wrong happened, such as an out - of memory error during CRL decoding. We don't want to proceed and must - mark the cache object invalid */ - if (SECFailure == rv) { - cache->invalid |= CRL_CACHE_LAST_FETCH_FAILED; - } else { - cache->invalid &= (~CRL_CACHE_LAST_FETCH_FAILED); - } - - if ((SECSuccess == rv) && (!crlobject)) { - /* no CRL was found. This is OK */ - DPCache_Empty(cache); - return SECSuccess; - } - - /* now check if we already have a binary equivalent DER CRL */ - for (i=0;i<cache->ncrls;i++) { - CERTSignedCrl* existing = cache->crls[i]; - if (existing && (SECEqual == SECITEM_CompareItem(existing->derCrl, crlobject->derCrl))) { - /* yes. Has the matching CRL been marked deleted ? */ - if (PR_TRUE == GetOpaqueCRLFields(crlobject)->deleted) { - /* Yes. Just replace the CK object ID and slot in the existing object. - This avoids an unnecessary signature verification & entry decode */ - /* XCRL we'll need to lock the CRL here in the future for iCRLs that are - shared between multiple CAs */ - existing->pkcs11ID = crlobject->pkcs11ID; - PK11_FreeSlot(existing->slot); /* release reference to old - CRL slot */ - existing->slot = crlobject->slot; /* adopt new CRL slot */ - crlobject->slot = NULL; /* clear slot to avoid double-freeing it - during CRL destroy */ - rv = SEC_DestroyCrl(crlobject); - PORT_Assert(SECSuccess == rv); - return rv; - } else { - /* We got an identical CRL from a different token. - Throw it away. */ - return SEC_DestroyCrl(crlobject); - } - } - } - - /* add the CRL to our array */ - if (SECSuccess == rv) { - rv = DPCache_AddCRL(cache, crlobject); - } - - /* update the cache with this new CRL */ - if (SECSuccess == rv) { - rv = DPCache_Refresh(cache, crlobject, vfdate, wincx); - } - return rv; -} - -SECStatus DPCache_Lookup(CRLDPCache* cache, SECItem* sn, CERTCrlEntry** returned) -{ - CERTSignedCrl* crl = NULL; - CERTCrlEntry* acrlEntry = NULL; - if (!cache || !sn) { - /* no cache or SN to look up, this is bad */ - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - if (0 != cache->invalid) { - /* the cache contains a bad CRL, consider all certs revoked - as a security measure */ - PORT_SetError(SEC_ERROR_CRL_INVALID); - return SECFailure; - } - if (!cache->full) { - /* no CRL means no entry to return, but this is OK */ - *returned = NULL; - return SECSuccess; - } - crl = cache->full; - PR_ASSERT(cache->entries); - if (!cache->entries) - { - return SECFailure; - } - acrlEntry = PL_HashTableLookup(cache->entries, (void*)sn); - if (acrlEntry) - { - *returned = acrlEntry; - } - return SECSuccess; -} - -#ifdef USE_RWLOCK - -#define DPCache_LockWrite() { \ - if (readlocked){ \ - NSSRWLock_UnlockRead(cache->lock); \ - } \ - NSSRWLock_LockWrite(cache->lock); \ -} - -#define DPCache_UnlockWrite() { \ - if (readlocked){ \ - NSSRWLock_LockRead(cache->lock); \ - } \ - NSSRWLock_UnlockWrite(cache->lock); \ -} - -#else - -#define DPCache_LockWrite() {} - -#define DPCache_UnlockWrite() {} - -#endif - -SECStatus DPCache_Update(CRLDPCache* cache, CERTCertificate* issuer, - PRBool readlocked, PRTime vfdate, void* wincx) -{ - /* Update the CRLDPCache now. We don't cache token CRL lookup misses - yet, as we have no way of getting notified of new PKCS#11 object - creation that happens in a token */ - SECStatus rv = SECSuccess; - PRUint32 i = 0; - PRBool updated = PR_FALSE; - - if (!cache) { - return SECFailure; - } - - /* verify CRLs that couldn't be checked when inserted into the cache - because the issuer cert was unavailable. These are CRLs that were - inserted into the cache through SEC_FindCrlByName, rather than - through a certificate verification (CERT_CheckCRL) */ - if (issuer) { - /* if we didn't have a valid issuer cert yet, but we do now. add it */ - if (NULL == cache->issuer) { - /* save the issuer cert */ - cache->issuer = CERT_DupCertificate(issuer); - } - - /* re-process all unverified CRLs */ - if (cache->issuer) { - for (i = 0; i < cache->ncrls ; i++) { - CERTSignedCrl* acrl = cache->crls[i]; - if (PR_TRUE == GetOpaqueCRLFields(acrl)->unverified) { - DPCache_LockWrite(); - /* check that we are the first thread to update */ - if (PR_TRUE == GetOpaqueCRLFields(acrl)->unverified) { - DPCache_Refresh(cache, acrl, vfdate, wincx); - /* also check all the other CRLs */ - for (i = i+1 ; i < cache->ncrls ; i++) { - acrl = cache->crls[i]; - if (acrl && (PR_TRUE == GetOpaqueCRLFields(acrl)->unverified)) { - DPCache_Refresh(cache, acrl, vfdate, wincx); - } - } - } - DPCache_UnlockWrite(); - break; - } - } - } - } - - if (cache->ncrls) { - /* check if all CRLs still exist */ - for (i = 0; (i < cache->ncrls) && (PR_FALSE == updated); i++) - { - CERTSignedCrl* savcrl = cache->crls[i]; - if (savcrl && (PR_TRUE != CRLStillExists(savcrl))) { - - /* this CRL is gone */ - DPCache_LockWrite(); - /* first, we need to check if another thread updated - it before we did, and abort if it has been modified since - we acquired the lock */ - if ((savcrl == cache->crls[i]) && - PR_TRUE != CRLStillExists(savcrl)) { - /* the CRL is gone. And we are the one to do the update */ - /* Mark the CRL deleted */ - GetOpaqueCRLFields(savcrl)->deleted = PR_TRUE; - /* also check all the other CRLs */ - for (i = i+1 ; i < cache->ncrls ; i++) { - CERTSignedCrl* acrl = cache->crls[i]; - if (acrl && (PR_TRUE != CRLStillExists(acrl))) { - GetOpaqueCRLFields(acrl)->deleted = PR_TRUE; - } - } - /* and try to fetch a new one */ - rv = DPCache_Fetch(cache, vfdate, wincx); - updated = PR_TRUE; - if (SECSuccess == rv) { - rv = DPCache_Cleanup(cache); /* clean up deleted CRLs - from the cache*/ - } - } - DPCache_UnlockWrite(); - } - } - } else { - /* we had zero CRL for this DP, try to get one from tokens */ - DPCache_LockWrite(); - /* check if another thread updated before us, and skip update if so */ - if (0 == cache->ncrls) - { - /* we are the first */ - rv = DPCache_Fetch(cache, vfdate, wincx); - } - DPCache_UnlockWrite(); - } - - return rv; -} - -SECStatus DPCache_Initialize(CRLDPCache* cache, CERTCertificate* issuer, - SECItem* subject, SECItem* dp) -{ - PORT_Assert(cache); - if (!cache) { - return SECFailure; - } - memset(cache, 0, sizeof(CRLDPCache)); -#ifdef USE_RWLOCK - cache->lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL); -#else - cache->lock = PR_NewLock(); -#endif - if (!cache->lock) - { - return SECFailure; - } - if (issuer) - { - cache->issuer = CERT_DupCertificate(issuer); - } - cache->distributionPoint = SECITEM_DupItem(dp); - cache->subject = SECITEM_DupItem(subject); - return SECSuccess; -} - -SECStatus IssuerCache_Create(CRLIssuerCache** returned, - CERTCertificate* issuer, - SECItem* subject, SECItem* dp) -{ - SECStatus rv = SECSuccess; - CRLIssuerCache* cache = NULL; - PORT_Assert(returned); - PORT_Assert(subject); - if (!returned || !subject) - { - return SECFailure; - } - cache = (CRLIssuerCache*) PR_Malloc(sizeof(CRLIssuerCache)); - if (!cache) - { - return SECFailure; - } - memset(cache, 0, sizeof(CRLIssuerCache)); - cache->subject = SECITEM_DupItem(subject); -#if 0 - /* XCRL */ - cache->lock = NSSRWLock_New(NSS_RWLOCK_RANK_NONE, NULL); - if (!cache->lock) - { - rv = SECFailure; - } - if (SECSuccess == rv && issuer) - { - cache->issuer = CERT_DupCertificate(issuer); - if (!cache->issuer) - { - rv = SECFailure; - } - } -#endif - if (SECSuccess != rv) - { - return IssuerCache_Destroy(cache); - } - *returned = cache; - return SECSuccess; -} - -SECStatus IssuerCache_AddDP(CRLIssuerCache* cache, CERTCertificate* issuer, - SECItem* subject, SECItem* dp, CRLDPCache** newdpc) -{ - SECStatus rv = SECSuccess; - /* now create the required DP cache object */ - if (!dp) { - /* default distribution point */ - rv = DPCache_Initialize(&cache->dp, issuer, subject, NULL); - if (SECSuccess == rv) { - cache->dpp = &cache->dp; - if (newdpc) { - *newdpc = cache->dpp; - } - } - } else { - /* we should never hit this until we support multiple DPs */ - PORT_Assert(dp); - rv = SECFailure; - /* XCRL allocate a new distribution point cache object, initialize it, - and add it to the hash table of DPs */ - } - return rv; -} - -SECStatus CRLCache_AddIssuer(CRLIssuerCache* issuer) -{ - PORT_Assert(issuer); - PORT_Assert(crlcache.issuers); - if (!issuer || !crlcache.issuers) { - return SECFailure; - } - if (NULL == PL_HashTableAdd(crlcache.issuers, (void*) issuer->subject, - (void*) issuer)) { - return SECFailure; - } - return SECSuccess; -} - -SECStatus GetIssuerCache(CRLCache* cache, SECItem* subject, CRLIssuerCache** returned) -{ - /* we need to look up the issuer in the hash table */ - SECStatus rv = SECSuccess; - PORT_Assert(cache); - PORT_Assert(subject); - PORT_Assert(returned); - PORT_Assert(crlcache.issuers); - if (!cache || !subject || !returned || !crlcache.issuers) { - rv = SECFailure; - } - - if (SECSuccess == rv){ - *returned = (CRLIssuerCache*) PL_HashTableLookup(crlcache.issuers, - (void*) subject); - } - - return rv; -} - -CERTSignedCrl* GetBestCRL(CRLDPCache* cache) -{ - PRUint32 i = 0; - PR_ASSERT(cache); - if (!cache) { - return NULL; - } - if (0 == cache->ncrls) { - /* no CRLs in the cache */ - return NULL; - } - /* first, check if we have a valid full CRL, and use that */ - if (cache->full) { - return SEC_DupCrl(cache->full); - } - /* otherwise, check all the fetched CRLs for one with valid DER */ - for (i = 0; i < cache->ncrls ; i++) { - CERTSignedCrl* acrl = cache->crls[i]; - if (PR_FALSE == GetOpaqueCRLFields(acrl)->bad) { - SECStatus rv = CERT_CompleteCRLDecodeEntries(acrl); - if (SECSuccess == rv) { - return SEC_DupCrl(acrl); - } - } - } - return NULL; -} - -CRLDPCache* GetDPCache(CRLIssuerCache* cache, SECItem* dp) -{ - CRLDPCache* dpp = NULL; - PORT_Assert(cache); - /* XCRL for now we only support the "default" DP, ie. the - full CRL. So we can return the global one without locking. In - the future we will have a lock */ - PORT_Assert(NULL == dp); - if (!cache || dp) { - return NULL; - } -#if 0 - /* XCRL */ - NSSRWLock_LockRead(cache->lock); -#endif - dpp = cache->dpp; -#if 0 - /* XCRL */ - NSSRWLock_UnlockRead(cache->lock); -#endif - return dpp; -} - -SECStatus AcquireDPCache(CERTCertificate* issuer, SECItem* subject, SECItem* dp, - int64 t, void* wincx, CRLDPCache** dpcache, - PRBool* writeLocked) -{ - SECStatus rv = SECSuccess; - CRLIssuerCache* issuercache = NULL; - - PORT_Assert(crlcache.lock); - if (!crlcache.lock) { - /* CRL cache is not initialized */ - return SECFailure; - } - PR_Lock(crlcache.lock); - rv = GetIssuerCache(&crlcache, subject, &issuercache); - if (SECSuccess != rv) { - PR_Unlock(crlcache.lock); - return SECFailure; - } - if (!issuercache) { - /* there is no cache for this issuer yet. This means this is the - first time we look up a cert from that issuer, and we need to - create the cache. Do it within the global cache lock to ensure - no two threads will simultaneously try to create the same issuer - cache. XXX this could be optimized with a r/w lock at this level - too. But the code would have to check if it already exists when - adding to the hash table */ - - rv = IssuerCache_Create(&issuercache, issuer, subject, dp); - if (SECSuccess == rv && !issuercache) { - PORT_Assert(issuercache); - rv = SECFailure; - } - - if (SECSuccess == rv) { - /* This is the first time we look up a cert of this issuer. - Create the DPCache for this DP . */ - rv = IssuerCache_AddDP(issuercache, issuer, subject, dp, dpcache); - } - - if (SECSuccess == rv) { - /* lock the DPCache for write to ensure the update happens in this thread */ - *writeLocked = PR_TRUE; -#ifdef USE_RWLOCK - NSSRWLock_LockWrite((*dpcache)->lock); -#else - PR_Lock((*dpcache)->lock); -#endif - } - - if (SECSuccess == rv) { - /* now add the new issuer cache to the global hash table of issuers */ - rv = CRLCache_AddIssuer(issuercache); - if (SECSuccess != rv) { - /* failure */ - rv = SECFailure; - } - } - - /* now unlock the global cache. We only want to lock the hash table - addition. Holding it longer would hurt scalability */ - PR_Unlock(crlcache.lock); - - if (SECSuccess != rv && issuercache) { - if (PR_TRUE == *writeLocked) { -#ifdef USE_RWLOCK - NSSRWLock_UnlockWrite((*dpcache)->lock); -#else - PR_Unlock((*dpcache)->lock); -#endif - } - IssuerCache_Destroy(issuercache); - issuercache = NULL; - } - - if (SECSuccess != rv) { - return SECFailure; - } - } else { - PR_Unlock(crlcache.lock); - *dpcache = GetDPCache(issuercache, dp); - } - /* we now have a DPCache that we can use for lookups */ - /* lock it for read, unless we already locked for write */ - if (PR_FALSE == *writeLocked) - { -#ifdef USE_RWLOCK - NSSRWLock_LockRead((*dpcache)->lock); -#else - PR_Lock((*dpcache)->lock); -#endif - } - - if (SECSuccess == rv) { - /* currently there is always one and only one DPCache */ - PORT_Assert(*dpcache); - if (*dpcache) - { - /* make sure the DP cache is up to date before using it */ - rv = DPCache_Update(*dpcache, issuer, PR_FALSE == *writeLocked, t, wincx); - } - else - { - rv = SECFailure; - } - } - return rv; -} - -void ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked) -{ - if (!dpcache) { - return; - } - if (PR_TRUE == writeLocked) { -#ifdef USE_RWLOCK - NSSRWLock_UnlockWrite(dpcache->lock); -#else - PR_Unlock(dpcache->lock); -#endif - } else { -#ifdef USE_RWLOCK - NSSRWLock_UnlockRead(dpcache->lock); -#else - PR_Unlock(dpcache->lock); -#endif - } -} - -SECStatus -CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer, SECItem* dp, - int64 t, void* wincx) -{ - PRBool lockedwrite = PR_FALSE; - SECStatus rv = SECSuccess; - CRLDPCache* dpcache = NULL; - if (!cert || !issuer) { - return SECFailure; - } - - if (SECSuccess != CERT_CheckCertValidTimes(issuer, t, PR_FALSE)) { - /* we won't be able to check the CRL's signature if the issuer cert - is expired as of the time we are verifying. This may cause a valid - CRL to be cached as bad. short-circuit to avoid this case. */ - PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE); - return SECFailure; - } - - rv = AcquireDPCache(issuer, &issuer->derSubject, dp, t, wincx, &dpcache, &lockedwrite); - - if (SECSuccess == rv) { - /* now look up the certificate SN in the DP cache's CRL */ - CERTCrlEntry* entry = NULL; - rv = DPCache_Lookup(dpcache, &cert->serialNumber, &entry); - if (SECSuccess == rv && entry) { - /* check the time if we have one */ - if (entry->revocationDate.data && entry->revocationDate.len) { - int64 revocationDate = 0; - if (SECSuccess == CERT_DecodeTimeChoice(&revocationDate, - &entry->revocationDate)) { - /* we got a good revocation date, only consider the - certificate revoked if the time we are inquiring about - is past the revocation date */ - if (t>=revocationDate) { - rv = SECFailure; - } - } else { - /* invalid revocation date, consider the certificate - permanently revoked */ - rv = SECFailure; - } - } else { - /* no revocation date, certificate is permanently revoked */ - rv = SECFailure; - } - if (SECFailure == rv) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - } - } - } - - ReleaseDPCache(dpcache, lockedwrite); - return rv; -} - -CERTSignedCrl * -SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type) -{ - CERTSignedCrl* acrl = NULL; - CRLDPCache* dpcache = NULL; - SECStatus rv = SECSuccess; - PRBool writeLocked = PR_FALSE; - - rv = AcquireDPCache(NULL, crlKey, NULL, 0, NULL, &dpcache, &writeLocked); - if (SECSuccess == rv) - { - acrl = GetBestCRL(dpcache); - ReleaseDPCache(dpcache, writeLocked); - } - return acrl; -} - -void CERT_CRLCacheRefreshIssuer(CERTCertDBHandle* dbhandle, SECItem* crlKey) -{ - CRLDPCache* cache = NULL; - SECStatus rv = SECSuccess; - PRBool writeLocked = PR_FALSE; - - (void) dbhandle; /* silence compiler warnings */ - - rv = AcquireDPCache(NULL, crlKey, NULL, 0, NULL, &cache, &writeLocked); - if (SECSuccess != rv) - { - return; - } - if (PR_TRUE == writeLocked) - { - /* the DPCache is write-locked. This means that the issuer was just - added to the CRL cache. There is no need to do anything */ - } - else - { - PRBool readlocked = PR_TRUE; - /* we need to invalidate the DPCache here */ - DPCache_LockWrite(); - DPCache_Empty(cache); - DPCache_Cleanup(cache); - DPCache_UnlockWrite(); - } - ReleaseDPCache(cache, writeLocked); - return; -} - diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c deleted file mode 100644 index 93c437778..000000000 --- a/security/nss/lib/certdb/genname.c +++ /dev/null @@ -1,1810 +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_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_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 } -}; - - - -CERTGeneralName * -cert_NewGeneralName(PLArenaPool *arena, CERTGeneralNameType type) -{ - CERTGeneralName *name = arena - ? PORT_ArenaZNew(arena, CERTGeneralName) - : PORT_ZNew(CERTGeneralName); - if (name) { - name->type = type; - name->l.prev = name->l.next = &name->l; - } - return name; -} - -/* Copy content of one General Name to another. -** Caller has allocated destination general name. -** This function does not change the destinate's GeneralName's list linkage. -*/ -SECStatus -cert_CopyOneGeneralName(PRArenaPool *arena, - CERTGeneralName *dest, - CERTGeneralName *src) -{ - SECStatus rv; - - /* TODO: mark arena */ - PORT_Assert(dest != NULL); - dest->type = src->type; - - switch (src->type) { - case certDirectoryName: - rv = SECITEM_CopyItem(arena, &dest->derDirectoryName, - &src->derDirectoryName); - if (rv == SECSuccess) - 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) - rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid, - &src->name.OthName.oid); - break; - - default: - rv = SECITEM_CopyItem(arena, &dest->name.other, - &src->name.other); - break; - - } - if (rv != SECSuccess) { - /* TODO: release back to mark */ - } else { - /* TODO: unmark arena */ - } - return rv; -} - - -void -CERT_DestroyGeneralNameList(CERTGeneralNameList *list) -{ - PZLock *lock; - - if (list != NULL) { - lock = list->lock; - PZ_Lock(lock); - if (--list->refCount <= 0 && list->arena != NULL) { - PORT_FreeArena(list->arena, PR_FALSE); - PZ_Unlock(lock); - PZ_DestroyLock(lock); - } else { - PZ_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 = PORT_ArenaZNew(arena, CERTGeneralNameList); - if (!list) - goto loser; - if (name != NULL) { - SECStatus rv; - list->name = cert_NewGeneralName(arena, (CERTGeneralNameType)0); - if (!list->name) - goto loser; - rv = CERT_CopyGeneralName(arena, list->name, name); - if (rv != SECSuccess) - goto loser; - } - list->lock = PZ_NewLock(nssILockList); - if (!list->lock) - goto loser; - list->arena = arena; - list->refCount = 1; -done: - return list; - -loser: - PORT_FreeArena(arena, PR_FALSE); - return NULL; -} - -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) -{ - - const SEC_ASN1Template * template; - - PORT_Assert(arena); - if (arena == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - /* TODO: mark arena */ - if (dest == NULL) { - dest = PORT_ArenaZNew(arena, SECItem); - if (!dest) - goto loser; - } - if (genName->type == certDirectoryName) { - if (genName->derDirectoryName.data == NULL) { - /* The field hasn't been encoded yet. */ - SECItem * pre_dest = - SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName), - &(genName->name.directoryName), - CERT_NameTemplate); - if (!pre_dest) - goto loser; - } - if (genName->derDirectoryName.data == NULL) { - goto loser; - } - } - switch (genName->type) { - case certURI: template = CERT_URITemplate; break; - case certRFC822Name: template = CERT_RFC822NameTemplate; break; - case certDNSName: template = CERT_DNSNameTemplate; break; - case certIPAddress: template = CERT_IPAddressTemplate; break; - case certOtherName: template = CERTOtherNameTemplate; break; - case certRegisterID: template = CERT_RegisteredIDTemplate; break; - /* for this type, we expect the value is already encoded */ - case certEDIPartyName: template = CERT_EDIPartyNameTemplate; break; - /* for this type, we expect the value is already encoded */ - case certX400Address: template = CERT_X400AddressTemplate; break; - case certDirectoryName: template = CERT_DirectoryNameTemplate; break; - default: - PORT_Assert(0); goto loser; - } - dest = SEC_ASN1EncodeItem(arena, dest, genName, template); - if (!dest) { - goto loser; - } - /* TODO: unmark arena */ - return dest; -loser: - /* TODO: release arena back to mark */ - 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); - /* TODO: mark 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 = PORT_ArenaNewArray(arena, 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; - /* TODO: unmark arena */ - return items; -loser: - /* TODO: release arena to mark */ - return NULL; -} - -CERTGeneralName * -CERT_DecodeGeneralName(PRArenaPool *arena, - SECItem *encodedName, - CERTGeneralName *genName) -{ - const SEC_ASN1Template * template; - CERTGeneralNameType genNameType; - SECStatus rv = SECSuccess; - - PORT_Assert(arena); - /* TODO: mark arena */ - genNameType = (CERTGeneralNameType)((*(encodedName->data) & 0x0f) + 1); - if (genName == NULL) { - genName = cert_NewGeneralName(arena, genNameType); - if (!genName) - goto loser; - } else { - genName->type = genNameType; - genName->l.prev = genName->l.next = &genName->l; - } - switch (genNameType) { - case certURI: template = CERT_URITemplate; break; - case certRFC822Name: template = CERT_RFC822NameTemplate; break; - case certDNSName: template = CERT_DNSNameTemplate; break; - case certIPAddress: template = CERT_IPAddressTemplate; break; - case certOtherName: template = CERTOtherNameTemplate; break; - case certRegisterID: template = CERT_RegisteredIDTemplate; break; - case certEDIPartyName: template = CERT_EDIPartyNameTemplate; break; - case certX400Address: template = CERT_X400AddressTemplate; break; - case certDirectoryName: template = CERT_DirectoryNameTemplate; break; - default: - goto loser; - } - rv = SEC_ASN1DecodeItem(arena, genName, template, encodedName); - if (rv != SECSuccess) - goto loser; - if (genNameType == certDirectoryName) { - rv = SEC_ASN1DecodeItem(arena, &(genName->name.directoryName), - CERT_NameTemplate, - &(genName->derDirectoryName)); - if (rv != SECSuccess) - goto loser; - } - - /* TODO: unmark arena */ - return genName; -loser: - /* TODO: release arena to mark */ - return NULL; -} - -CERTGeneralName * -cert_DecodeGeneralNames (PRArenaPool *arena, - SECItem **encodedGenName) -{ - PRCList *head = NULL; - PRCList *tail = NULL; - CERTGeneralName *currentName = NULL; - - PORT_Assert(arena); - if (!encodedGenName || !arena) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - /* TODO: mark arena */ - while (*encodedGenName != NULL) { - currentName = CERT_DecodeGeneralName(arena, *encodedGenName, NULL); - if (currentName == NULL) - break; - if (head == NULL) { - head = &(currentName->l); - tail = head; - } - currentName->l.next = head; - currentName->l.prev = tail; - tail = head->prev = tail->next = &(currentName->l); - encodedGenName++; - } - if (currentName) { - /* TODO: unmark arena */ - return cert_get_next_general_name(currentName); - } - /* TODO: release arena to mark */ - 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; -} - -static SECItem * -cert_EncodeNameConstraint(CERTNameConstraint *constraint, - SECItem *dest, - PRArenaPool *arena) -{ - PORT_Assert(arena); - if (dest == NULL) { - dest = PORT_ArenaZNew(arena, 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); - /* TODO: mark arena */ - if (constraints != NULL) { - count = 1; - } - head = &constraints->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 = PORT_ArenaZNewArray(arena, 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; - } - /* TODO: unmark arena */ - return SECSuccess; -loser: - /* TODO: release arena to mark */ - return SECFailure; -} - -SECStatus -cert_EncodeNameConstraints(CERTNameConstraints *constraints, - PRArenaPool *arena, - SECItem *dest) -{ - SECStatus rv = SECSuccess; - - PORT_Assert(arena); - /* TODO: mark 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; - } - /* TODO: unmark arena */ - return SECSuccess; -loser: - /* TODO: release arena to mark */ - return SECFailure; -} - - -CERTNameConstraint * -cert_DecodeNameConstraint(PRArenaPool *arena, - SECItem *encodedConstraint) -{ - CERTNameConstraint *constraint; - SECStatus rv = SECSuccess; - CERTGeneralName *temp; - - PORT_Assert(arena); - /* TODO: mark arena */ - constraint = PORT_ArenaZNew(arena, CERTNameConstraint); - if (!constraint) - goto loser; - 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); - /* TODO: unmark arena */ - return constraint; -loser: - /* TODO: release arena back to mark */ - return NULL; -} - -CERTNameConstraint * -cert_DecodeNameConstraintSubTree(PRArenaPool *arena, - SECItem **subTree, - PRBool permited) -{ - CERTNameConstraint *current = NULL; - CERTNameConstraint *first = NULL; - CERTNameConstraint *last = NULL; - int i = 0; - - PORT_Assert(arena); - /* TODO: mark arena */ - 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); - /* TODO: unmark arena */ - return first; -loser: - /* TODO: release arena back to mark */ - return NULL; -} - -CERTNameConstraints * -cert_DecodeNameConstraints(PRArenaPool *arena, - SECItem *encodedConstraints) -{ - CERTNameConstraints *constraints; - SECStatus rv; - - PORT_Assert(arena); - PORT_Assert(encodedConstraints); - /* TODO: mark arena */ - constraints = PORT_ArenaZNew(arena, 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; - } - } - /* TODO: unmark arena */ - return constraints; -loser: - /* TODO: release arena back to mark */ - return NULL; -} - -/* Copy a chain of one or more general names to a destination chain. -** Caller has allocated at least the first destination GeneralName struct. -** Both source and destination chains are circular doubly-linked lists. -** The first source struct is copied to the first destination struct. -** If the source chain has more than one member, and the destination chain -** has only one member, then this function allocates new structs for all but -** the first copy from the arena and links them into the destination list. -** If the destination struct is part of a list with more than one member, -** then this function traverses both the source and destination lists, -** copying each source struct to the corresponding dest struct. -** In that case, the destination list MUST contain at least as many -** structs as the source list or some dest entries will be overwritten. -*/ -SECStatus -CERT_CopyGeneralName(PRArenaPool *arena, - CERTGeneralName *dest, - CERTGeneralName *src) -{ - SECStatus rv; - CERTGeneralName *destHead = dest; - CERTGeneralName *srcHead = src; - - PORT_Assert(dest != NULL); - if (!dest) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* TODO: mark arena */ - do { - rv = cert_CopyOneGeneralName(arena, dest, src); - if (rv != SECSuccess) - goto loser; - 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) { - CERTGeneralName *temp; - temp = cert_NewGeneralName(arena, (CERTGeneralNameType)0); - if (!temp) - goto loser; - 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); - /* TODO: unmark arena */ - return rv; -loser: - /* TODO: release back to mark */ - return SECFailure; -} - - -CERTGeneralNameList * -CERT_DupGeneralNameList(CERTGeneralNameList *list) -{ - if (list != NULL) { - PZ_Lock(list->lock); - list->refCount++; - PZ_Unlock(list->lock); - } - return list; -} - -CERTNameConstraint * -CERT_CopyNameConstraint(PRArenaPool *arena, - CERTNameConstraint *dest, - CERTNameConstraint *src) -{ - SECStatus rv; - - /* TODO: mark arena */ - if (dest == NULL) { - dest = PORT_ArenaZNew(arena, CERTNameConstraint); - if (!dest) - goto loser; - /* 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; - /* TODO: unmark arena */ - return dest; -loser: - /* TODO: release arena to mark */ - 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_GetNameConstraintByType (CERTNameConstraint *constraints, - CERTGeneralNameType type, - CERTNameConstraint **returnList, - PRArenaPool *arena) -{ - CERTNameConstraint *current; - - *returnList = NULL; - if (!constraints) - return SECSuccess; - /* TODO: mark arena */ - current = constraints; - do { - PORT_Assert(current->name.type); - if (current->name.type == type) { - CERTNameConstraint *temp; - temp = CERT_CopyNameConstraint(arena, NULL, current); - if (temp == NULL) - goto loser; - *returnList = CERT_AddNameConstraint(*returnList, temp); - } - current = cert_get_next_name_constraint(current); - } while (current != constraints); - /* TODO: unmark arena */ - return SECSuccess; -loser: - /* TODO: release arena back to mark */ - 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 (void *)¤t->name.other; /* SECItem * */ - - case certOtherName: - return (void *)¤t->name.OthName; /* OthName * */ - - case certDirectoryName: - return derFormat - ? (void *)¤t->derDirectoryName /* SECItem * */ - : (void *)¤t->name.directoryName; /* CERTName * */ - } - PORT_Assert(0); - return NULL; - } - 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; -} - -/* Creates new GeneralNames for any email addresses found in the -** input DN, and links them onto the list for the DN. -*/ -SECStatus -cert_ExtractDNEmailAddrs(CERTGeneralName *name, PLArenaPool *arena) -{ - CERTGeneralName *nameList = NULL; - const CERTRDN **nRDNs = name->name.directoryName.rdns; - SECStatus rv = SECSuccess; - - PORT_Assert(name->type == certDirectoryName); - if (name->type != certDirectoryName) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* TODO: mark arena */ - while (nRDNs && *nRDNs) { /* loop over RDNs */ - const CERTRDN *nRDN = *nRDNs++; - CERTAVA **nAVAs = nRDN->avas; - while (nAVAs && *nAVAs) { /* loop over AVAs */ - int tag; - CERTAVA *nAVA = *nAVAs++; - tag = CERT_GetAVATag(nAVA); - if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS || - tag == SEC_OID_RFC1274_MAIL) { /* email AVA */ - CERTGeneralName *newName = NULL; - SECItem *avaValue = CERT_DecodeAVAValue(&nAVA->value); - if (!avaValue) - goto loser; - rv = SECFailure; - newName = cert_NewGeneralName(arena, certRFC822Name); - if (newName) { - rv = SECITEM_CopyItem(arena, &newName->name.other, avaValue); - } - SECITEM_FreeItem(avaValue, PR_TRUE); - if (rv != SECSuccess) - goto loser; - nameList = cert_CombineNamesLists(nameList, newName); - } /* handle one email AVA */ - } /* loop over AVAs */ - } /* loop over RDNs */ - /* combine new names with old one. */ - name = cert_CombineNamesLists(name, nameList); - /* TODO: unmark arena */ - return SECSuccess; - -loser: - /* TODO: release arena back to mark */ - return SECFailure; -} - -/* This function is called by CERT_VerifyCertChain to extract all -** names from a cert in preparation for a name constraints test. -*/ -CERTGeneralName * -CERT_GetCertificateNames(CERTCertificate *cert, PRArenaPool *arena) -{ - CERTGeneralName *DN; - CERTGeneralName *altName = NULL; - SECItem altNameExtension = {siBuffer, NULL, 0 }; - SECStatus rv; - - /* TODO: mark arena */ - DN = cert_NewGeneralName(arena, certDirectoryName); - if (DN == NULL) { - goto loser; - } - rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject); - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject); - if (rv != SECSuccess) { - goto loser; - } - /* Extract email addresses from DN, construct CERTGeneralName structs - ** for them, add them to the name list - */ - rv = cert_ExtractDNEmailAddrs(DN, arena); - if (rv != SECSuccess) - goto loser; - - /* Now extract any GeneralNames from the subject name names extension. */ - rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, - &altNameExtension); - if (rv == SECSuccess) { - altName = CERT_DecodeAltNameExtension(arena, &altNameExtension); - rv = altName ? SECSuccess : SECFailure; - } - if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) - rv = SECSuccess; - if (altNameExtension.data) - SECITEM_FreeItem(&altNameExtension, PR_FALSE); - if (rv != SECSuccess) - goto loser; - DN = cert_CombineNamesLists(DN, altName); - - /* TODO: unmark arena */ - return DN; -loser: - /* TODO: release arena to mark */ - return NULL; -} - -/* Returns SECSuccess if name matches constraint per RFC 3280 rules for -** URI name constraints. SECFailure otherwise. -** If the constraint begins with a dot, it is a domain name, otherwise -** It is a host name. Examples: -** Constraint Name Result -** ------------ --------------- -------- -** foo.bar.com foo.bar.com matches -** foo.bar.com FoO.bAr.CoM matches -** foo.bar.com www.foo.bar.com no match -** foo.bar.com nofoo.bar.com no match -** .foo.bar.com www.foo.bar.com matches -** .foo.bar.com nofoo.bar.com no match -** .foo.bar.com foo.bar.com no match -** .foo.bar.com www..foo.bar.com no match -*/ -static SECStatus -compareURIN2C(const SECItem *name, const SECItem *constraint) -{ - int offset; - /* The spec is silent on intepreting zero-length constraints. - ** We interpret them as matching no URI names. - */ - if (!constraint->len) - return SECFailure; - if (constraint->data[0] != '.') { - /* constraint is a host name. */ - if (name->len != constraint->len || - PL_strncasecmp(name->data, constraint->data, constraint->len)) - return SECFailure; - return SECSuccess; - } - /* constraint is a domain name. */ - if (name->len < constraint->len) - return SECFailure; - offset = name->len - constraint->len; - if (PL_strncasecmp(name->data + offset, constraint->data, constraint->len)) - return SECFailure; - if (!offset || - (name->data[offset - 1] == '.') + (constraint->data[0] == '.') == 1) - return SECSuccess; - return SECFailure; -} - -/* for DNSnames, the constraint matches any string to which it matches the -** rightmost characters in that string. -** Constraint Name Result -** ------------ --------------- -------- -** foo.bar.com foo.bar.com matches -** foo.bar.com FoO.bAr.CoM matches -** foo.bar.com www.foo.bar.com matches -** foo.bar.com nofoo.bar.com MATCHES -** .foo.bar.com www.foo.bar.com matches -** .foo.bar.com foo.bar.com no match -** .foo.bar.com www..foo.bar.com matches -*/ -static SECStatus -compareDNSN2C(const SECItem *name, const SECItem *constraint) -{ - int offset; - /* The spec is silent on intepreting zero-length constraints. - ** We interpret them as matching all DNSnames. - */ - if (!constraint->len) - return SECSuccess; - if (name->len < constraint->len) - return SECFailure; - offset = name->len - constraint->len; - if (PL_strncasecmp(name->data + offset, constraint->data, constraint->len)) - return SECFailure; - return SECSuccess; -} - -/* Returns SECSuccess if name matches constraint per RFC 3280 rules for -** internet email addresses. SECFailure otherwise. -** If constraint contains a '@' then the two strings much match exactly. -** Else if constraint starts with a '.'. then it must match the right-most -** substring of the name, -** else constraint string must match entire name after the name's '@'. -** Empty constraint string matches all names. All comparisons case insensitive. -*/ -static SECStatus -compareRFC822N2C(const SECItem *name, const SECItem *constraint) -{ - int offset; - if (!constraint->len) - return SECSuccess; - if (name->len < constraint->len) - return SECFailure; - if (constraint->len == 1 && constraint->data[0] == '.') - return SECSuccess; - for (offset = constraint->len - 1; offset >= 0; --offset) { - if (constraint->data[offset] == '@') { - return (name->len == constraint->len && - !PL_strncasecmp(name->data, constraint->data, constraint->len)) - ? SECSuccess : SECFailure; - } - } - offset = name->len - constraint->len; - if (PL_strncasecmp(name->data + offset, constraint->data, constraint->len)) - return SECFailure; - if (constraint->data[0] == '.') - return SECSuccess; - if (offset > 0 && name->data[offset - 1] == '@') - return SECSuccess; - return SECFailure; -} - -/* name contains either a 4 byte IPv4 address or a 16 byte IPv6 address. -** constraint contains an address of the same length, and a subnet mask -** of the same length. Compare name's address to the constraint's -** address, subject to the mask. -** Return SECSuccess if they match, SECFailure if they don't. -*/ -static SECStatus -compareIPaddrN2C(const SECItem *name, const SECItem *constraint) -{ - int i; - if (name->len == 4 && constraint->len == 8) { /* ipv4 addr */ - for (i = 0; i < 4; i++) { - if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+4]) - goto loser; - } - return SECSuccess; - } - if (name->len == 16 && constraint->len == 32) { /* ipv6 addr */ - for (i = 0; i < 16; i++) { - if ((name->data[i] ^ constraint->data[i]) & constraint->data[i+16]) - goto loser; - } - return SECSuccess; - } -loser: - return SECFailure; -} - -/* start with a SECItem that points to a URI. Parse it lookingg for -** a hostname. Modify item->data and item->len to define the hostname, -** but do not modify and data at item->data. -** If anything goes wrong, the contents of *item are undefined. -*/ -static SECStatus -parseUriHostname(SECItem * item) -{ - int i; - PRBool found = PR_FALSE; - for (i = 0; (unsigned)(i+2) < item->len; ++i) { - if (item->data[i ] == ':' && - item->data[i+1] == '/' && - item->data[i+2] == '/') { - i += 3; - item->data += i; - item->len -= i; - found = PR_TRUE; - break; - } - } - if (!found) - return SECFailure; - /* now look for a '/', which is an upper bound in the end of the name */ - for (i = 0; (unsigned)i < item->len; ++i) { - if (item->data[i] == '/') { - item->len = i; - break; - } - } - /* now look for a ':', which marks the end of the name */ - for (i = item->len; --i >= 0; ) { - if (item->data[i] == ':') { - item->len = i; - break; - } - } - /* now look for an '@', which marks the beginning of the hostname */ - for (i = 0; (unsigned)i < item->len; ++i) { - if (item->data[i] == '@') { - ++i; - item->data += i; - item->len -= i; - break; - } - } - return item->len ? SECSuccess : SECFailure; -} - -/* This function takes one name, and a list of constraints. -** It searches the constraints looking for a match. -** It returns SECSuccess if the name satisfies the constraints, i.e., -** if excluded, then the name does not match any constraint, -** if permitted, then the name matches at least one constraint. -** It returns SECFailure if the name fails to satisfy the constraints, -** or if some code fails (e.g. out of memory, or invalid constraint) -*/ -static SECStatus -cert_CompareNameWithConstraints(CERTGeneralName *name, - CERTNameConstraint *constraints, - PRBool excluded) -{ - SECStatus rv = SECSuccess; - SECStatus matched = SECFailure; - CERTNameConstraint *current; - - PORT_Assert(constraints); /* caller should not call with NULL */ - if (!constraints) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - current = constraints; - do { - rv = SECSuccess; - matched = SECFailure; - PORT_Assert(name->type == current->name.type); - switch (name->type) { - - case certDNSName: - matched = compareDNSN2C(&name->name.other, - ¤t->name.name.other); - break; - - case certRFC822Name: - matched = compareRFC822N2C(&name->name.other, - ¤t->name.name.other); - break; - - case certURI: - { - /* make a modifiable copy of the URI SECItem. */ - SECItem uri = name->name.other; - /* find the hostname in the URI */ - rv = parseUriHostname(&uri); - if (rv == SECSuccess) { - /* does our hostname meet the constraint? */ - matched = compareURIN2C(&uri, ¤t->name.name.other); - } - } - break; - - case certDirectoryName: - /* Determine if the constraint directory name is a "prefix" - ** for the directory name being tested. - */ - { - /* status defaults to SECEqual, so that a constraint with - ** no AVAs will be a wildcard, matching all directory names. - */ - SECComparison status = SECEqual; - const CERTRDN **cRDNs = current->name.name.directoryName.rdns; - const CERTRDN **nRDNs = name->name.directoryName.rdns; - while (cRDNs && *cRDNs && nRDNs && *nRDNs) { - /* loop over name RDNs and constraint RDNs in lock step */ - const CERTRDN *cRDN = *cRDNs++; - const CERTRDN *nRDN = *nRDNs++; - CERTAVA **cAVAs = cRDN->avas; - while (cAVAs && *cAVAs) { /* loop over constraint AVAs */ - CERTAVA *cAVA = *cAVAs++; - CERTAVA **nAVAs = nRDN->avas; - while (nAVAs && *nAVAs) { /* loop over name AVAs */ - CERTAVA *nAVA = *nAVAs++; - status = CERT_CompareAVA(cAVA, nAVA); - if (status == SECEqual) - break; - } /* loop over name AVAs */ - if (status != SECEqual) - break; - } /* loop over constraint AVAs */ - if (status != SECEqual) - break; - } /* loop over name RDNs and constraint RDNs */ - matched = (status == SECEqual) ? SECSuccess : SECFailure; - break; - } - - case certIPAddress: /* type 8 */ - matched = compareIPaddrN2C(&name->name.other, - ¤t->name.name.other); - break; - - /* NSS does not know how to compare these "Other" type names with - ** their respective constraints. But it does know how to tell - ** if the constraint applies to the type of name (by comparing - ** the constraint OID to the name OID). NSS makes no use of "Other" - ** type names at all, so NSS errs on the side of leniency for these - ** types, provided that their OIDs match. So, when an "Other" - ** name constraint appears in an excluded subtree, it never causes - ** a name to fail. When an "Other" name constraint appears in a - ** permitted subtree, AND the constraint's OID matches the name's - ** OID, then name is treated as if it matches the constraint. - */ - case certOtherName: /* type 1 */ - matched = (!excluded && - name->type == current->name.type && - SECITEM_ItemsAreEqual(&name->name.OthName.oid, - ¤t->name.name.OthName.oid)) - ? SECSuccess : SECFailure; - break; - - /* NSS does not know how to compare these types of names with their - ** respective constraints. But NSS makes no use of these types of - ** names at all, so it errs on the side of leniency for these types. - ** Constraints for these types of names never cause the name to - ** fail the constraints test. NSS behaves as if the name matched - ** for permitted constraints, and did not match for excluded ones. - */ - case certX400Address: /* type 4 */ - case certEDIPartyName: /* type 6 */ - case certRegisterID: /* type 9 */ - matched = excluded ? SECFailure : SECSuccess; - break; - - default: /* non-standard types are not supported */ - rv = SECFailure; - break; - } - if (matched == SECSuccess || rv != SECSuccess) - break; - current = cert_get_next_name_constraint(current); - } while (current != constraints); - if (rv == SECSuccess) { - if (matched == SECSuccess) - rv = excluded ? SECFailure : SECSuccess; - else - rv = excluded ? SECSuccess : SECFailure; - return rv; - } - - return SECFailure; -} - -/* Extract the name constraints extension from the CA cert. -** Test each and every name in namesList against all the constraints -** relevant to that type of name. -** Returns NULL for success, all names are acceptable. -** If some name is not acceptable, returns a pointer to the cert that -** contained that name. -*/ -SECStatus -CERT_CompareNameSpace(CERTCertificate *cert, - CERTGeneralName *namesList, - CERTCertificate **certsList, - PRArenaPool *arena, - CERTCertificate **pBadCert) -{ - 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) { - if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) { - rv = SECSuccess; - } else { - count = -1; - } - goto done; - } - /* TODO: mark arena */ - constraints = cert_DecodeNameConstraints(arena, &constraintsExtension); - currentName = namesList; - if (constraints == NULL) { /* decode failed */ - rv = SECFailure; - count = -1; - goto done; - } - do { - if (constraints->excluded != NULL) { - rv = CERT_GetNameConstraintByType(constraints->excluded, - currentName->type, - &matchingConstraints, arena); - if (rv == SECSuccess && matchingConstraints != NULL) { - rv = cert_CompareNameWithConstraints(currentName, - matchingConstraints, - PR_TRUE); - } - if (rv != SECSuccess) - break; - } - if (constraints->permited != NULL) { - rv = CERT_GetNameConstraintByType(constraints->permited, - currentName->type, - &matchingConstraints, arena); - if (rv == SECSuccess && matchingConstraints != NULL) { - rv = cert_CompareNameWithConstraints(currentName, - matchingConstraints, - PR_FALSE); - } - if (rv != SECSuccess) - break; - } - currentName = cert_get_next_general_name(currentName); - count ++; - } while (currentName != namesList); -done: - if (rv != SECSuccess) { - badCert = (count >= 0) ? certsList[count] : cert; - } - if (pBadCert) - *pBadCert = badCert; - /* TODO: release back to mark */ - return rv; -} - -/* Search the cert for an X509_SUBJECT_ALT_NAME extension. -** ASN1 Decode it into a list of alternate names. -** Search the list of alternate names for one with the NETSCAPE_NICKNAME OID. -** ASN1 Decode that name. Turn the result into a zString. -** Look for duplicate nickname already in the certdb. -** If one is found, create a nickname string that is not a duplicate. -*/ -char * -CERT_GetNickName(CERTCertificate *cert, - CERTCertDBHandle *handle, - PRArenaPool *nicknameArena) -{ - CERTGeneralName *current; - CERTGeneralName *names; - char *nickname = NULL; - char *returnName = NULL; - char *basename = NULL; - PRArenaPool *arena = NULL; - CERTCertificate *tmpcert; - SECStatus rv; - int count; - int found = 0; - SECItem altNameExtension; - SECItem nick; - - if (handle == NULL) { - handle = CERT_GetDefaultCertDB(); - } - altNameExtension.data = NULL; - 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) { - found = 1; - break; - } - current = cert_get_next_general_name(current); - } while (current != names); - if (!found) - goto loser; - - rv = SEC_ASN1DecodeItem(arena, &nick, SEC_IA5StringTemplate, - ¤t->name.OthName.name); - if (rv != SECSuccess) { - goto loser; - } - - /* make a null terminated string out of nick, with room enough at - ** the end to add on a number of up to 21 digits in length, (a signed - ** 64-bit number in decimal) plus a space and a "#". - */ - nickname = (char*)PORT_ZAlloc(nick.len + 24); - if (!nickname) - goto loser; - PORT_Strncpy(nickname, (char *)nick.data, nick.len); - - /* Don't let this cert's nickname duplicate one already in the DB. - ** If it does, create a variant of the nickname that doesn't. - */ - count = 0; - while ((tmpcert = CERT_FindCertByNickname(handle, nickname)) != NULL) { - CERT_DestroyCertificate(tmpcert); - if (!basename) { - basename = PORT_Strdup(nickname); - if (!basename) - goto loser; - } - count++; - sprintf(nickname, "%s #%d", basename, count); - } - - /* success */ - if (nicknameArena) { - returnName = PORT_ArenaStrdup(nicknameArena, nickname); - } else { - returnName = nickname; - nickname = NULL; - } -loser: - if (arena != NULL) - PORT_FreeArena(arena, PR_FALSE); - if (nickname) - PORT_Free(nickname); - if (basename) - PORT_Free(basename); - if (altNameExtension.data) - PORT_Free(altNameExtension.data); - return returnName; -} - -#if 0 -/* not exported from shared libs, not used. Turn on if we ever need it. */ -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) { - PZ_Lock(a->lock); - PZ_Lock(b->lock); - rv = CERT_CompareGeneralName(a->name, b->name); - PZ_Unlock(a->lock); - PZ_Unlock(b->lock); - } else { - rv = SECFailure; - } - return rv; -} -#endif - -#if 0 -/* This function is not exported from NSS shared libraries, and is not -** used inside of NSS. -** XXX it doesn't check for failed allocations. :-( -*/ -void * -CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, - CERTGeneralNameType type, - PRArenaPool *arena) -{ - CERTName *name = NULL; - SECItem *item = NULL; - OtherName *other = NULL; - OtherName *tmpOther = NULL; - void *data; - - PZ_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 = PORT_ArenaNew(arena, SECItem); - if (item != NULL) { -XXX SECITEM_CopyItem(arena, item, (SECItem *) data); - } - } else { - item = SECITEM_DupItem((SECItem *) data); - } - PZ_Unlock(list->lock); - return item; - case certOtherName: - other = (OtherName *) data; - if (arena != NULL) { - tmpOther = PORT_ArenaNew(arena, OtherName); - } else { - tmpOther = PORT_New(OtherName); - } - if (tmpOther != NULL) { -XXX SECITEM_CopyItem(arena, &tmpOther->oid, &other->oid); -XXX SECITEM_CopyItem(arena, &tmpOther->name, &other->name); - } - PZ_Unlock(list->lock); - return tmpOther; - case certDirectoryName: - if (arena) { - name = PORT_ArenaZNew(list->arena, CERTName); - if (name) { -XXX CERT_CopyName(arena, name, (CERTName *) data); - } - } - PZ_Unlock(list->lock); - return name; - } - } - PZ_Unlock(list->lock); - return NULL; -} -#endif - -#if 0 -/* This function is not exported from NSS shared libraries, and is not -** used inside of NSS. -** XXX it should NOT be a void function, since it does allocations -** that can fail. -*/ -void -CERT_AddGeneralNameToList(CERTGeneralNameList *list, - CERTGeneralNameType type, - void *data, SECItem *oid) -{ - CERTGeneralName *name; - - if (list != NULL && data != NULL) { - PZ_Lock(list->lock); - name = cert_NewGeneralName(list->arena, type); - if (!name) - goto done; - switch (type) { - case certDNSName: - case certEDIPartyName: - case certIPAddress: - case certRegisterID: - case certRFC822Name: - case certX400Address: - case certURI: -XXX SECITEM_CopyItem(list->arena, &name->name.other, (SECItem *)data); - break; - case certOtherName: -XXX SECITEM_CopyItem(list->arena, &name->name.OthName.name, - (SECItem *) data); -XXX SECITEM_CopyItem(list->arena, &name->name.OthName.oid, - oid); - break; - case certDirectoryName: -XXX CERT_CopyName(list->arena, &name->name.directoryName, - (CERTName *) data); - break; - } - list->name = cert_CombineNamesLists(list->name, name); - list->len++; -done: - PZ_Unlock(list->lock); - } - return; -} -#endif diff --git a/security/nss/lib/certdb/genname.h b/security/nss/lib/certdb/genname.h deleted file mode 100644 index 504f0cd06..000000000 --- a/security/nss/lib/certdb/genname.h +++ /dev/null @@ -1,149 +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); - -/*********************************************************************/ -/* A thread safe implementation of General Names */ -/*********************************************************************/ - -/* Destroy a Single CERTGeneralName */ -void -CERT_DestroyGeneralName(CERTGeneralName *name); - -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 */ - -/* 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 number of CERTGeneralName objects in the doubly linked -** list of which *names is a member. -*/ -extern int -CERT_GetNamesLength(CERTGeneralName *names); - -/************************************************************************/ - -SECStatus -CERT_CompareNameSpace(CERTCertificate *cert, - CERTGeneralName *namesList, - CERTCertificate **certsList, - PRArenaPool *arena, - CERTCertificate **pBadCert); - -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 944d38a55..000000000 --- a/security/nss/lib/certdb/manifest.mn +++ /dev/null @@ -1,68 +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 \ - $(NULL) - -PRIVATE_EXPORTS = \ - genname.h \ - xconst.h \ - certxutl.h \ - certi.h \ - $(NULL) - -MODULE = nss - -CSRCS = \ - alg1485.c \ - certdb.c \ - certv3.c \ - certxutl.c \ - crl.c \ - genname.c \ - stanpcertdb.c \ - polcyxtn.c \ - secname.c \ - xauthkid.c \ - xbsconst.c \ - xconst.c \ - $(NULL) - -REQUIRES = dbm - -LIBRARY_NAME = certdb - diff --git a/security/nss/lib/certdb/polcyxtn.c b/security/nss/lib/certdb/polcyxtn.c deleted file mode 100644 index 41302f039..000000000 --- a/security/nss/lib/certdb/polcyxtn.c +++ /dev/null @@ -1,565 +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; - SECItem newExtnValue; - - /* 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; - - /* copy the DER into the arena, since Quick DER returns data that points - into the DER input, which may get freed by the caller */ - rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue); - if ( rv != SECSuccess ) { - goto loser; - } - - /* decode the policy info */ - rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate, - &newExtnValue); - - 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; - SECItem newNoticeItem; - - /* 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; - - /* copy the DER into the arena, since Quick DER returns data that points - into the DER input, which may get freed by the caller */ - rv = SECITEM_CopyItem(arena, &newNoticeItem, noticeItem); - if ( rv != SECSuccess ) { - goto loser; - } - - /* decode the user notice */ - rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate, - &newNoticeItem); - - 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_ArenaZAlloc(arena, 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_QuickDERDecodeItem(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; - SECItem newSeqItem; - - /* 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; - - /* copy the DER into the arena, since Quick DER returns data that points - into the DER input, which may get freed by the caller */ - rv = SECITEM_CopyItem(arena, &newSeqItem, seqItem); - if ( rv != SECSuccess ) { - goto loser; - } - - /* decode the user notice */ - rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, &newSeqItem); - - 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 5a40249da..000000000 --- a/security/nss/lib/certdb/secname.c +++ /dev/null @@ -1,689 +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 <stdarg.h> -#include "secerr.h" -#include "certi.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; -} - - -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; - int maxLen; - SECOidData *oidrec; - - oidrec = SECOID_FindOIDByTag(type); - if (oidrec == NULL) - return SECFailure; - - oid = oidrec->oid.data; - oidLen = oidrec->oid.len; - - maxLen = cert_AVAOidTagToMaxLen(type); - if (maxLen < 0) { - 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 = (unsigned)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: - case SEC_ASN1_UTF8_STRING: /* no conversion required */ - valueLen = PORT_Strlen(value); - break; - case SEC_ASN1_UNIVERSAL_STRING: - valueLen = PORT_Strlen(value); - ucs4MaxLen = valueLen * 6; - ucs4Val = (unsigned char *)PORT_ArenaZAlloc(arena, ucs4MaxLen); - 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; - maxLen *= 4; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (valueLen > maxLen) { - 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 = 0; - if (ava0) { - count++; - 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; - } - if (ava0) { - *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 = SECSuccess; - - /* Copy each ava from from */ - avas = from->avas; - if (avas) { - if (avas[0] == NULL) { - rv = CERT_AddAVA(arena, to, NULL); - return rv; - } - while ((fava = *avas++) != 0) { - tava = CERT_CopyAVA(arena, fava); - if (!tava) { - rv = SECFailure; - break; - } - rv = CERT_AddAVA(arena, to, tava); - if (rv != SECSuccess) - break; - } - } - return rv; -} - -/************************************************************************/ - -const SEC_ASN1Template CERT_NameTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) } -}; - -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_NameTemplate) - -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 */ - if (!rdn0) { - count = 0; - } else { - count = 1; - va_start(ap, rdn0); - while ((rdn = va_arg(ap, CERTRDN*)) != 0) { - count++; - } - va_end(ap); - } - - /* Allocate space (including space for terminal null ptr) */ - name->rdns = rdnp = - (CERTRDN**) PORT_ArenaAlloc(arena, (count + 1) * sizeof(CERTRDN*)); - if (!name->rdns) { - goto loser; - } - - /* Now fill in the pointers */ - if (count > 0) { - *rdnp++ = rdn0; - va_start(ap, rdn0); - while ((rdn = va_arg(ap, CERTRDN*)) != 0) { - *rdnp++ = rdn; - } - va_end(ap); - } - - /* null terminate the list */ - *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 = SECSuccess; - - if (!to || !from) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - CERT_DestroyName(to); - to->arena = arena; - - /* Copy each rdn from from */ - rdns = from->rdns; - if (rdns) { - if (rdns[0] == NULL) { - rv = CERT_AddRDN(to, NULL); - return rv; - } - while ((frdn = *rdns++) != NULL) { - trdn = CERT_CreateRDN(arena, 0); - if (!trdn) { - rv = SECFailure; - break; - } - rv = CERT_CopyRDN(arena, trdn, frdn); - if (rv != SECSuccess) - break; - rv = CERT_AddRDN(to, trdn); - if (rv != SECSuccess) - break; - } - } - return rv; -} - -/************************************************************************/ - -static void -canonicalize(SECItem * foo) -{ - int ch, lastch, len, src, dest; - - /* strip trailing whitespace. */ - len = foo->len; - while (len > 0 && ((ch = foo->data[len - 1]) == ' ' || - ch == '\t' || ch == '\r' || ch == '\n')) { - len--; - } - - src = 0; - /* strip leading whitespace. */ - while (src < len && ((ch = foo->data[src]) == ' ' || - ch == '\t' || ch == '\r' || ch == '\n')) { - src++; - } - dest = 0; lastch = ' '; - while (src < len) { - ch = foo->data[src++]; - if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { - ch = ' '; - if (ch == lastch) - continue; - } else if (ch >= 'A' && ch <= 'Z') { - ch |= 0x20; /* downshift */ - } - foo->data[dest++] = lastch = ch; - } - foo->len = dest; -} - -/* SECItems a and b contain DER-encoded printable strings. */ -SECComparison -CERT_CompareDERPrintableStrings(const SECItem *a, const SECItem *b) -{ - SECComparison rv = SECLessThan; - SECItem * aVal = CERT_DecodeAVAValue(a); - SECItem * bVal = CERT_DecodeAVAValue(b); - - if (aVal && aVal->len && aVal->data && - bVal && bVal->len && bVal->data) { - canonicalize(aVal); - canonicalize(bVal); - rv = SECITEM_CompareItem(aVal, bVal); - } - SECITEM_FreeItem(aVal, PR_TRUE); - SECITEM_FreeItem(bVal, PR_TRUE); - return rv; -} - -SECComparison -CERT_CompareAVA(const CERTAVA *a, const CERTAVA *b) -{ - SECComparison rv; - - rv = SECITEM_CompareItem(&a->type, &b->type); - if (SECEqual != rv) - return rv; /* Attribute types don't match. */ - /* Let's be optimistic. Maybe the values will just compare equal. */ - rv = SECITEM_CompareItem(&a->value, &b->value); - if (SECEqual == rv) - return rv; /* values compared exactly. */ - if (a->value.len && a->value.data && b->value.len && b->value.data) { - /* Here, the values did not match. - ** If the values had different encodings, convert them to the same - ** encoding and compare that way. - */ - if (a->value.data[0] != b->value.data[0]) { - /* encodings differ. Convert both to UTF-8 and compare. */ - SECItem * aVal = CERT_DecodeAVAValue(&a->value); - SECItem * bVal = CERT_DecodeAVAValue(&b->value); - if (aVal && aVal->len && aVal->data && - bVal && bVal->len && bVal->data) { - rv = SECITEM_CompareItem(aVal, bVal); - } - SECITEM_FreeItem(aVal, PR_TRUE); - SECITEM_FreeItem(bVal, PR_TRUE); - } else if (a->value.data[0] == 0x13) { /* both are printable strings. */ - /* printable strings */ - rv = CERT_CompareDERPrintableStrings(&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(const SECItem *derAVAValue) -{ - SECItem *retItem; - const SEC_ASN1Template *theTemplate = NULL; - PRBool convertUCS4toUTF8 = PR_FALSE; - PRBool convertUCS2toUTF8 = PR_FALSE; - SECItem avaValue = {siBuffer, 0}; - PLArenaPool *newarena = NULL; - - if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) { - 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; - case SEC_ASN1_UTF8_STRING: - /* No conversion needed ! */ - theTemplate = SEC_UTF8StringTemplate; - break; - default: - return NULL; - } - - PORT_Memset(&avaValue, 0, sizeof(SECItem)); - newarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (!newarena) { - return NULL; - } - if(SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) - != SECSuccess) { - PORT_FreeArena(newarena, PR_FALSE); - return NULL; - } - - if (convertUCS4toUTF8) { - unsigned int utf8ValLen = avaValue.len * 3; - unsigned char *utf8Val = (unsigned char*) - PORT_ArenaZAlloc(newarena, utf8ValLen); - - if(avaValue.len % 4 != 0 || - !PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, - utf8Val, utf8ValLen, &utf8ValLen)) { - PORT_FreeArena(newarena, PR_FALSE); - PORT_SetError(SEC_ERROR_INVALID_AVA); - return NULL; - } - - avaValue.data = utf8Val; - avaValue.len = utf8ValLen; - - } else if (convertUCS2toUTF8) { - - unsigned int utf8ValLen = avaValue.len * 3; - unsigned char *utf8Val = (unsigned char*) - PORT_ArenaZAlloc(newarena, utf8ValLen); - - if(avaValue.len % 2 != 0 || - !PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, - utf8Val, utf8ValLen, &utf8ValLen)) { - PORT_FreeArena(newarena, PR_FALSE); - PORT_SetError(SEC_ERROR_INVALID_AVA); - return NULL; - } - - avaValue.data = utf8Val; - avaValue.len = utf8ValLen; - } - - retItem = SECITEM_DupItem(&avaValue); - PORT_FreeArena(newarena, PR_FALSE); - return retItem; -} diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c deleted file mode 100644 index 7d607e255..000000000 --- a/security/nss/lib/certdb/stanpcertdb.c +++ /dev/null @@ -1,988 +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 "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 "nssilock.h" -#include "prmon.h" -#include "nsslocks.h" -#include "base64.h" -#include "sechash.h" -#include "plhash.h" -#include "pk11func.h" /* sigh */ - -#ifndef NSS_3_4_CODE -#define NSS_3_4_CODE -#endif /* NSS_3_4_CODE */ -#include "nsspki.h" -#include "pki.h" -#include "pkim.h" -#include "pki3hack.h" -#include "ckhelper.h" -#include "base.h" -#include "pkistore.h" -#include "dev3hack.h" -#include "dev.h" - -PRBool -SEC_CertNicknameConflict(char *nickname, SECItem *derSubject, - CERTCertDBHandle *handle) -{ - CERTCertificate *cert; - PRBool conflict = PR_FALSE; - - cert=CERT_FindCertByNickname(handle, nickname); - - if (!cert) { - return conflict; - } - - conflict = !SECITEM_ItemsAreEqual(derSubject,&cert->derSubject); - CERT_DestroyCertificate(cert); - return conflict; -} - -SECStatus -SEC_DeletePermCertificate(CERTCertificate *cert) -{ - PRStatus nssrv; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - NSSCertificate *c = STAN_GetNSSCertificate(cert); - - /* get rid of the token instances */ - nssrv = NSSCertificate_DeleteStoredObject(c, NULL); - - /* get rid of the cache entry */ - nssTrustDomain_LockCertCache(td); - nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); - nssTrustDomain_UnlockCertCache(td); - - return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; -} - -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); -} - -#ifdef notdef -static char * -cert_parseNickname(char *nickname) -{ - char *cp; - for (cp=nickname; *cp && *cp != ':'; cp++); - if (*cp == ':') return cp+1; - return nickname; -} -#endif - -SECStatus -CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert, - CERTCertTrust *trust) -{ - SECStatus rv = SECFailure; - PRStatus ret; - - CERT_LockCertTrust(cert); - ret = STAN_ChangeCertTrust(cert, trust); - rv = (ret == PR_SUCCESS) ? SECSuccess : SECFailure; - CERT_UnlockCertTrust(cert); - return rv; -} - -extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; - -SECStatus -__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, - CERTCertTrust *trust) -{ - NSSUTF8 *stanNick; - PK11SlotInfo *slot; - NSSToken *internal; - NSSCryptoContext *context; - nssCryptokiObject *permInstance; - NSSCertificate *c = STAN_GetNSSCertificate(cert); - context = c->object.cryptoContext; - if (!context) { - PORT_SetError(SEC_ERROR_ADDING_CERT); - return SECFailure; /* wasn't a temp cert */ - } - stanNick = nssCertificate_GetNickname(c, NULL); - if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { - /* take the new nickname */ - cert->nickname = NULL; - stanNick = NULL; - } - if (!stanNick && nickname) { - stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena); - } - /* Delete the temp instance */ - nssCertificateStore_Lock(context->certStore); - nssCertificateStore_RemoveCertLOCKED(context->certStore, c); - nssCertificateStore_Unlock(context->certStore); - c->object.cryptoContext = NULL; - /* Import the perm instance onto the internal token */ - slot = PK11_GetInternalKeySlot(); - internal = PK11Slot_GetNSSToken(slot); - permInstance = nssToken_ImportCertificate(internal, NULL, - NSSCertificateType_PKIX, - &c->id, - stanNick, - &c->encoding, - &c->issuer, - &c->subject, - &c->serial, - cert->emailAddr, - PR_TRUE); - PK11_FreeSlot(slot); - if (!permInstance) { - if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { - PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); - } - return SECFailure; - } - nssPKIObject_AddInstance(&c->object, permInstance); - nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1); - /* reset the CERTCertificate fields */ - cert->nssCertificate = NULL; - cert = STAN_GetCERTCertificate(c); /* will return same pointer */ - if (!cert) { - return SECFailure; - } - cert->istemp = PR_FALSE; - cert->isperm = PR_TRUE; - if (!trust) { - return SECSuccess; - } - return (STAN_ChangeCertTrust(cert, trust) == PR_SUCCESS) ? - SECSuccess: SECFailure; -} - -SECStatus -CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, - CERTCertTrust *trust) -{ - return __CERT_AddTempCertToPerm(cert, nickname, trust); -} - -CERTCertificate * -__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER) -{ - PRStatus nssrv; - NSSCertificate *c; - CERTCertificate *cc; - NSSCertificate *tempCert; - nssPKIObject *pkio; - NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); - NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); - if (!isperm) { - NSSDER encoding; - NSSITEM_FROM_SECITEM(&encoding, derCert); - /* First, see if it is already a temp cert */ - c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC, - &encoding); - if (!c) { - /* Then, see if it is already a perm cert */ - c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, - &encoding); - /* actually, that search ends up going by issuer/serial, - * so it is still possible to return a cert with the same - * issuer/serial but a different encoding, and we're - * going to reject that - */ - if (c && !nssItem_Equal(&c->encoding, &encoding, NULL)) { - nssCertificate_Destroy(c); - PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); - return NULL; - } - } - if (c) { - return STAN_GetCERTCertificate(c); - } - } - pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC); - if (!pkio) { - return NULL; - } - c = nss_ZNEW(pkio->arena, NSSCertificate); - if (!c) { - nssPKIObject_Destroy(pkio); - return NULL; - } - c->object = *pkio; - if (copyDER) { - nssItem_Create(c->object.arena, &c->encoding, - derCert->len, derCert->data); - } else { - NSSITEM_FROM_SECITEM(&c->encoding, derCert); - } - /* Forces a decoding of the cert in order to obtain the parts used - * below - */ - cc = STAN_GetCERTCertificate(c); - if (!cc) { - goto loser; - } - nssItem_Create(c->object.arena, - &c->issuer, cc->derIssuer.len, cc->derIssuer.data); - nssItem_Create(c->object.arena, - &c->subject, cc->derSubject.len, cc->derSubject.data); - if (PR_TRUE) { - /* CERTCertificate stores serial numbers decoded. I need the DER - * here. sigh. - */ - SECItem derSerial = { 0 }; - CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); - if (!derSerial.data) goto loser; - nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data); - PORT_Free(derSerial.data); - } - if (nickname) { - c->object.tempName = nssUTF8_Create(c->object.arena, - nssStringType_UTF8String, - (NSSUTF8 *)nickname, - PORT_Strlen(nickname)); - } - if (cc->emailAddr && cc->emailAddr[0]) { - c->email = nssUTF8_Create(c->object.arena, - nssStringType_PrintableString, - (NSSUTF8 *)cc->emailAddr, - PORT_Strlen(cc->emailAddr)); - } - /* this function cannot detect if the cert exists as a temp cert now, but - * didn't when CERT_NewTemp was first called. - */ - nssrv = NSSCryptoContext_ImportCertificate(gCC, c); - if (nssrv != PR_SUCCESS) { - goto loser; - } - /* so find the entry in the temp store */ - tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(gCC, - &c->issuer, - &c->serial); - /* destroy the copy */ - NSSCertificate_Destroy(c); - if (tempCert) { - /* and use the "official" entry */ - c = tempCert; - cc = STAN_GetCERTCertificate(c); - if (!cc) { - return NULL; - } - } else { - return NULL; - } - cc->istemp = PR_TRUE; - cc->isperm = PR_FALSE; - return cc; -loser: - nssPKIObject_Destroy(&c->object); - return NULL; -} - -CERTCertificate * -CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER) -{ - return( __CERT_NewTempCertificate(handle, derCert, nickname, - isperm, copyDER) ); -} - -/* maybe all the wincx's should be some const for internal token login? */ -CERTCertificate * -CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN) -{ - PK11SlotInfo *slot; - CERTCertificate *cert; - - cert = PK11_FindCertByIssuerAndSN(&slot,issuerAndSN,NULL); - if (cert && slot) { - PK11_FreeSlot(slot); - } - - return cert; -} - -static NSSCertificate * -get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp) -{ - NSSUsage usage; - NSSCertificate *arr[3]; - if (!ct) { - return nssCertificate_AddRef(cp); - } else if (!cp) { - return nssCertificate_AddRef(ct); - } - arr[0] = ct; - arr[1] = cp; - arr[2] = NULL; - usage.anyUsage = PR_TRUE; - return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL); -} - -CERTCertificate * -CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name) -{ - NSSCertificate *cp, *ct, *c; - NSSDER subject; - NSSUsage usage; - NSSCryptoContext *cc; - NSSITEM_FROM_SECITEM(&subject, name); - usage.anyUsage = PR_TRUE; - cc = STAN_GetDefaultCryptoContext(); - ct = NSSCryptoContext_FindBestCertificateBySubject(cc, &subject, - NULL, &usage, NULL); - cp = NSSTrustDomain_FindBestCertificateBySubject(handle, &subject, - NULL, &usage, NULL); - c = get_best_temp_or_perm(ct, cp); - if (ct) { - CERTCertificate *cert = STAN_GetCERTCertificate(ct); - if (!cert) { - return NULL; - } - CERT_DestroyCertificate(cert); - } - if (cp) { - CERTCertificate *cert = STAN_GetCERTCertificate(cp); - if (!cert) { - return NULL; - } - CERT_DestroyCertificate(cert); - } - if (c) { - return STAN_GetCERTCertificate(c); - } else { - return NULL; - } -} - -CERTCertificate * -CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID) -{ - CERTCertList *list = - CERT_CreateSubjectCertList(NULL,handle,name,0,PR_FALSE); - CERTCertificate *cert = NULL; - CERTCertListNode *node = CERT_LIST_HEAD(list); - - if (list == NULL) return NULL; - - for (node = CERT_LIST_HEAD(list); node ; node = CERT_LIST_NEXT(node)) { - if (SECITEM_ItemsAreEqual(&cert->subjectKeyID, keyID) ) { - cert = CERT_DupCertificate(node->cert); - break; - } - } - return cert; -} - -CERTCertificate * -CERT_FindCertByNickname(CERTCertDBHandle *handle, char *nickname) -{ - NSSCryptoContext *cc; - NSSCertificate *c, *ct; - CERTCertificate *cert; - NSSUsage usage; - usage.anyUsage = PR_TRUE; - cc = STAN_GetDefaultCryptoContext(); - ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname, - NULL, &usage, NULL); - cert = PK11_FindCertFromNickname(nickname, NULL); - c = NULL; - if (cert) { - c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); - CERT_DestroyCertificate(cert); - if (ct) { - CERTCertificate *cert2 = STAN_GetCERTCertificate(ct); - if (!cert2) { - return NULL; - } - CERT_DestroyCertificate(cert2); - } - } else { - c = ct; - } - if (c) { - return STAN_GetCERTCertificate(c); - } else { - return NULL; - } -} - -CERTCertificate * -CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert) -{ - NSSCryptoContext *cc; - NSSCertificate *c; - NSSDER encoding; - NSSITEM_FROM_SECITEM(&encoding, derCert); - cc = STAN_GetDefaultCryptoContext(); - c = NSSCryptoContext_FindCertificateByEncodedCertificate(cc, &encoding); - if (!c) { - c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, - &encoding); - if (!c) return NULL; - } - return STAN_GetCERTCertificate(c); -} - -CERTCertificate * -CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, char *name) -{ - NSSCryptoContext *cc; - NSSCertificate *c, *ct; - CERTCertificate *cert; - NSSUsage usage; - - if (NULL == name) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - usage.anyUsage = PR_TRUE; - cc = STAN_GetDefaultCryptoContext(); - ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, - NULL, &usage, NULL); - if (!ct && PORT_Strchr(name, '@') != NULL) { - char* lowercaseName = CERT_FixupEmailAddr(name); - if (lowercaseName) { - ct = NSSCryptoContext_FindBestCertificateByEmail(cc, lowercaseName, - NULL, &usage, NULL); - PORT_Free(lowercaseName); - } - } - cert = PK11_FindCertFromNickname(name, NULL); - if (cert) { - c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); - CERT_DestroyCertificate(cert); - if (ct) { - CERTCertificate *cert2 = STAN_GetCERTCertificate(ct); - if (!cert2) { - return NULL; - } - CERT_DestroyCertificate(cert2); - } - } else { - c = ct; - } - if (c) { - return STAN_GetCERTCertificate(c); - } - return NULL; -} - -static void -add_to_subject_list(CERTCertList *certList, CERTCertificate *cert, - PRBool validOnly, int64 sorttime) -{ - SECStatus secrv; - if (!validOnly || - CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE) - == secCertTimeValid) { - secrv = CERT_AddCertToListSorted(certList, cert, - CERT_SortCBValidity, - (void *)&sorttime); - if (secrv != SECSuccess) { - CERT_DestroyCertificate(cert); - } - } else { - CERT_DestroyCertificate(cert); - } -} - -CERTCertList * -CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle, - SECItem *name, int64 sorttime, PRBool validOnly) -{ - NSSCryptoContext *cc; - NSSCertificate **tSubjectCerts, **pSubjectCerts; - NSSCertificate **ci; - CERTCertificate *cert; - NSSDER subject; - PRBool myList = PR_FALSE; - cc = STAN_GetDefaultCryptoContext(); - NSSITEM_FROM_SECITEM(&subject, name); - /* Collect both temp and perm certs for the subject */ - tSubjectCerts = NSSCryptoContext_FindCertificatesBySubject(cc, - &subject, - NULL, - 0, - NULL); - pSubjectCerts = NSSTrustDomain_FindCertificatesBySubject(handle, - &subject, - NULL, - 0, - NULL); - if (!tSubjectCerts && !pSubjectCerts) { - return NULL; - } - if (certList == NULL) { - certList = CERT_NewCertList(); - myList = PR_TRUE; - if (!certList) goto loser; - } - /* Iterate over the matching temp certs. Add them to the list */ - ci = tSubjectCerts; - while (ci && *ci) { - cert = STAN_GetCERTCertificate(*ci); - if (cert) { - add_to_subject_list(certList, cert, validOnly, sorttime); - } - ci++; - } - /* Iterate over the matching perm certs. Add them to the list */ - ci = pSubjectCerts; - while (ci && *ci) { - cert = STAN_GetCERTCertificate(*ci); - if (cert) { - add_to_subject_list(certList, cert, validOnly, sorttime); - } - ci++; - } - nss_ZFreeIf(tSubjectCerts); - nss_ZFreeIf(pSubjectCerts); - return certList; -loser: - nss_ZFreeIf(tSubjectCerts); - nss_ZFreeIf(pSubjectCerts); - if (myList && certList != NULL) { - CERT_DestroyCertList(certList); - } - return NULL; -} - -void -CERT_DestroyCertificate(CERTCertificate *cert) -{ - if ( cert ) { - /* don't use STAN_GetNSSCertificate because we don't want to - * go to the trouble of translating the CERTCertificate into - * an NSSCertificate just to destroy it. If it hasn't been done - * yet, don't do it at all. - */ - NSSCertificate *tmp = cert->nssCertificate; - if (tmp) { - /* delete the NSSCertificate */ - NSSCertificate_Destroy(tmp); - } else { - PORT_FreeArena(cert->arena, PR_FALSE); - } - } - return; -} - -#ifdef notdef -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); -} -#endif - -int -CERT_GetDBContentVersion(CERTCertDBHandle *handle) -{ - /* should read the DB content version from the pkcs #11 device */ - return 0; -} - -SECStatus -certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr, - SECItem *emailProfile, SECItem *profileTime) -{ - int64 oldtime; - int64 newtime; - SECStatus rv = SECFailure; - PRBool saveit; - SECItem oldprof, oldproftime; - SECItem *oldProfile = NULL; - SECItem *oldProfileTime = NULL; - PK11SlotInfo *slot = NULL; - NSSCertificate *c; - NSSCryptoContext *cc; - nssSMIMEProfile *stanProfile = NULL; - PRBool freeOldProfile = PR_FALSE; - - c = STAN_GetNSSCertificate(cert); - if (!c) return SECFailure; - cc = c->object.cryptoContext; - if (cc != NULL) { - stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); - if (stanProfile) { - PORT_Assert(stanProfile->profileData); - SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData); - oldProfile = &oldprof; - SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime); - oldProfileTime = &oldproftime; - } - } else { - oldProfile = PK11_FindSMimeProfile(&slot, (char *)emailAddr, - &cert->derSubject, &oldProfileTime); - freeOldProfile = PR_TRUE; - } - - saveit = PR_FALSE; - - /* both profileTime and emailProfile have to exist or not exist */ - if ( emailProfile == NULL ) { - profileTime = NULL; - } else if ( profileTime == NULL ) { - emailProfile = NULL; - } - - if ( oldProfileTime == 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 ( oldProfileTime->len == 0 ) { - /* always replace if old entry doesn't have a time */ - oldtime = LL_MININT; - } else { - rv = DER_UTCTimeToTime(&oldtime, oldProfileTime); - 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 { - saveit = PR_TRUE; - } - } - - - if (saveit) { - if (cc) { - if (stanProfile) { - /* stanProfile is already stored in the crypto context, - * overwrite the data - */ - NSSArena *arena = stanProfile->object.arena; - stanProfile->profileTime = nssItem_Create(arena, - NULL, - profileTime->len, - profileTime->data); - stanProfile->profileData = nssItem_Create(arena, - NULL, - emailProfile->len, - emailProfile->data); - } else if (profileTime && emailProfile) { - PRStatus nssrv; - NSSDER subject; - NSSItem profTime, profData; - NSSItem *pprofTime, *pprofData; - NSSITEM_FROM_SECITEM(&subject, &cert->derSubject); - if (profileTime) { - NSSITEM_FROM_SECITEM(&profTime, profileTime); - pprofTime = &profTime; - } else { - pprofTime = NULL; - } - if (emailProfile) { - NSSITEM_FROM_SECITEM(&profData, emailProfile); - pprofData = &profData; - } else { - pprofData = NULL; - } - stanProfile = nssSMIMEProfile_Create(c, pprofTime, pprofData); - if (!stanProfile) goto loser; - nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile); - rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; - } - } else { - rv = PK11_SaveSMimeProfile(slot, (char *)emailAddr, - &cert->derSubject, emailProfile, profileTime); - } - } else { - rv = SECSuccess; - } - -loser: - if (oldProfile && freeOldProfile) { - SECITEM_FreeItem(oldProfile,PR_TRUE); - } - if (oldProfileTime && freeOldProfile) { - SECITEM_FreeItem(oldProfileTime,PR_TRUE); - } - if (stanProfile) { - nssSMIMEProfile_Destroy(stanProfile); - } - if (slot) { - PK11_FreeSlot(slot); - } - - return(rv); -} - -/* - * - * Manage S/MIME profiles - * - */ - -SECStatus -CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, - SECItem *profileTime) -{ - const char *emailAddr; - SECStatus rv; - - if (!cert) { - return SECFailure; - } - - if (cert->slot && !PK11_IsInternal(cert->slot)) { - /* this cert comes from an external source, we need to add it - to the cert db before creating an S/MIME profile */ - PK11SlotInfo* internalslot = PK11_GetInternalKeySlot(); - if (!internalslot) { - return SECFailure; - } - rv = PK11_ImportCert(internalslot, cert, - CK_INVALID_HANDLE, NULL, PR_FALSE); - - PK11_FreeSlot(internalslot); - if (rv != SECSuccess ) { - return SECFailure; - } - } - - - for (emailAddr = CERT_GetFirstEmailAddress(cert); emailAddr != NULL; - emailAddr = CERT_GetNextEmailAddress(cert,emailAddr)) { - rv = certdb_SaveSingleProfile(cert,emailAddr,emailProfile,profileTime); - if (rv != SECSuccess) { - return SECFailure; - } - } - return SECSuccess; - -} - - -SECItem * -CERT_FindSMimeProfile(CERTCertificate *cert) -{ - PK11SlotInfo *slot = NULL; - NSSCertificate *c; - NSSCryptoContext *cc; - SECItem *rvItem = NULL; - - c = STAN_GetNSSCertificate(cert); - if (!c) return NULL; - cc = c->object.cryptoContext; - if (cc != NULL) { - nssSMIMEProfile *stanProfile; - stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); - if (stanProfile) { - rvItem = SECITEM_AllocItem(NULL, NULL, - stanProfile->profileData->size); - if (rvItem) { - rvItem->data = stanProfile->profileData->data; - } - nssSMIMEProfile_Destroy(stanProfile); - } - return rvItem; - } - rvItem = - PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL); - if (slot) { - PK11_FreeSlot(slot); - } - return rvItem; -} - -/* - * depricated functions that are now just stubs. - */ -/* - * Close the database - */ -void -__CERT_ClosePermCertDB(CERTCertDBHandle *handle) -{ - PORT_Assert("CERT_ClosePermCertDB is Depricated" == NULL); - return; -} - -SECStatus -CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname, - PRBool readOnly) -{ - PORT_Assert("CERT_OpenCertDBFilename is Depricated" == NULL); - return SECFailure; -} - -SECItem * -SECKEY_HashPassword(char *pw, SECItem *salt) -{ - PORT_Assert("SECKEY_HashPassword is Depricated" == NULL); - return NULL; -} - -SECStatus -__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, - SECItem *derSubject, - void *cb, void *cbarg) -{ - PORT_Assert("CERT_TraversePermCertsForSubject is Depricated" == NULL); - return SECFailure; -} - - -SECStatus -__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname, - void *cb, void *cbarg) -{ - PORT_Assert("CERT_TraversePermCertsForNickname is Depricated" == NULL); - return SECFailure; -} - - - diff --git a/security/nss/lib/certdb/xauthkid.c b/security/nss/lib/certdb/xauthkid.c deleted file mode 100644 index 089d16f14..000000000 --- a/security/nss/lib/certdb/xauthkid.c +++ /dev/null @@ -1,155 +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; - SECItem newEncodedValue; - - PORT_Assert (arena); - - do { - mark = PORT_ArenaMark (arena); - value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); - value->DERAuthCertIssuer = NULL; - if (value == NULL) - break; - /* copy the DER into the arena, since Quick DER returns data that points - into the DER input, which may get freed by the caller */ - rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); - if ( rv != SECSuccess ) { - break; - } - - rv = SEC_QuickDERDecodeItem - (arena, value, CERTAuthKeyIDTemplate, &newEncodedValue); - 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 fea0e5dc8..000000000 --- a/security/nss/lib/certdb/xbsconst.c +++ /dev/null @@ -1,168 +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_QuickDERDecodeItem - (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 6bd95ba22..000000000 --- a/security/nss/lib/certdb/xconst.c +++ /dev/null @@ -1,257 +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" -#include "secerr.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; - } - if (encodedContext.encodedGenName && encodedContext.encodedGenName[0]) - return cert_DecodeGeneralNames(arena, encodedContext.encodedGenName); - /* Extension contained an empty GeneralNames sequence */ - /* Treat as extension not found */ - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); -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 e615fa3b4..000000000 --- a/security/nss/lib/certdb/xconst.h +++ /dev/null @@ -1,82 +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_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); |