diff options
author | ian.mcgreer%sun.com <devnull@localhost> | 2003-02-11 22:11:00 +0000 |
---|---|---|
committer | ian.mcgreer%sun.com <devnull@localhost> | 2003-02-11 22:11:00 +0000 |
commit | 3ed632314bbd04131ab19c152173b74c58f6791c (patch) | |
tree | c173038a28d35e8cede41a3684d5066e379c7cd6 | |
parent | 5228b53ea6dccdd63692d7730f610270c7502b8b (diff) | |
download | nss-hg-3ed632314bbd04131ab19c152173b74c58f6791c.tar.gz |
remove old files, move softoken dependencies inside softoken
83 files changed, 37 insertions, 46640 deletions
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 9bd248640..000000000 --- a/security/nss/lib/certdb/alg1485.c +++ /dev/null @@ -1,989 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "cert.h" -#include "xconst.h" -#include "genname.h" -#include "secitem.h" -#include "secerr.h" - -struct NameToKind { - char *name; - SECOidTag kind; -}; - -static struct NameToKind name2kinds[] = { - { "CN", SEC_OID_AVA_COMMON_NAME, }, - { "ST", SEC_OID_AVA_STATE_OR_PROVINCE, }, - { "OU", SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, }, - { "DC", SEC_OID_AVA_DC, }, - { "C", SEC_OID_AVA_COUNTRY_NAME, }, - { "O", SEC_OID_AVA_ORGANIZATION_NAME, }, - { "L", SEC_OID_AVA_LOCALITY, }, - { "dnQualifier", SEC_OID_AVA_DN_QUALIFIER, }, - { "E", SEC_OID_PKCS9_EMAIL_ADDRESS, }, - { "UID", SEC_OID_RFC1274_UID, }, - { "MAIL", SEC_OID_RFC1274_MAIL, }, - { 0, SEC_OID_UNKNOWN }, -}; - -#define C_DOUBLE_QUOTE '\042' - -#define C_BACKSLASH '\134' - -#define C_EQUAL '=' - -#define OPTIONAL_SPACE(c) \ - (((c) == ' ') || ((c) == '\r') || ((c) == '\n')) - -#define SPECIAL_CHAR(c) \ - (((c) == ',') || ((c) == '=') || ((c) == C_DOUBLE_QUOTE) || \ - ((c) == '\r') || ((c) == '\n') || ((c) == '+') || \ - ((c) == '<') || ((c) == '>') || ((c) == '#') || \ - ((c) == ';') || ((c) == C_BACKSLASH)) - - - - - - - -#if 0 -/* -** Find the start and end of a <string>. Strings can be wrapped in double -** quotes to protect special characters. -*/ -static int BracketThing(char **startp, char *end, char *result) -{ - char *start = *startp; - char c; - - /* Skip leading white space */ - while (start < end) { - c = *start++; - if (!OPTIONAL_SPACE(c)) { - start--; - break; - } - } - if (start == end) return 0; - - switch (*start) { - case '#': - /* Process hex thing */ - start++; - *startp = start; - while (start < end) { - c = *start++; - if (((c >= '0') && (c <= '9')) || - ((c >= 'a') && (c <= 'f')) || - ((c >= 'A') && (c <= 'F'))) { - continue; - } - break; - } - rv = IS_HEX; - break; - - case C_DOUBLE_QUOTE: - start++; - *startp = start; - while (start < end) { - c = *start++; - if (c == C_DOUBLE_QUOTE) { - break; - } - *result++ = c; - } - rv = IS_STRING; - break; - - default: - while (start < end) { - c = *start++; - if (SPECIAL_CHAR(c)) { - start--; - break; - } - *result++ = c; - } - rv = IS_STRING; - break; - } - - /* Terminate result string */ - *result = 0; - return start; -} - -static char *BracketSomething(char **startp, char* end, int spacesOK) -{ - char *start = *startp; - char c; - int stopAtDQ; - - /* Skip leading white space */ - while (start < end) { - c = *start; - if (!OPTIONAL_SPACE(c)) { - break; - } - start++; - } - if (start == end) return 0; - stopAtDQ = 0; - if (*start == C_DOUBLE_QUOTE) { - stopAtDQ = 1; - } - - /* - ** Find the end of the something. The something is terminated most of - ** the time by a space. However, if spacesOK is true then it is - ** terminated by a special character only. - */ - *startp = start; - while (start < end) { - c = *start; - if (stopAtDQ) { - if (c == C_DOUBLE_QUOTE) { - *start = ' '; - break; - } - } else { - if (SPECIAL_CHAR(c)) { - break; - } - if (!spacesOK && OPTIONAL_SPACE(c)) { - break; - } - } - start++; - } - return start; -} -#endif - -#define IS_PRINTABLE(c) \ - ((((c) >= 'a') && ((c) <= 'z')) || \ - (((c) >= 'A') && ((c) <= 'Z')) || \ - (((c) >= '0') && ((c) <= '9')) || \ - ((c) == ' ') || \ - ((c) == '\'') || \ - ((c) == '\050') || /* ( */ \ - ((c) == '\051') || /* ) */ \ - (((c) >= '+') && ((c) <= '/')) || /* + , - . / */ \ - ((c) == ':') || \ - ((c) == '=') || \ - ((c) == '?')) - -static PRBool -IsPrintable(unsigned char *data, unsigned len) -{ - unsigned char ch, *end; - - end = data + len; - while (data < end) { - ch = *data++; - if (!IS_PRINTABLE(ch)) { - return PR_FALSE; - } - } - return PR_TRUE; -} - -static 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; - 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 { - vt = SEC_ASN1_UNIVERSAL_STRING; - } - } - a = CERT_CreateAVA(arena, n2k->kind, vt, (char *) valBuf); - return a; - } - } - /* matched no kind -- invalid tag */ - PORT_SetError(SEC_ERROR_INVALID_AVA); - return 0; -} - -static CERTName * -ParseRFC1485Name(char *buf, int len) -{ - SECStatus rv; - CERTName *name; - char *bp, *e; - CERTAVA *ava; - CERTRDN *rdn; - - name = CERT_CreateName(NULL); - if (name == NULL) { - return NULL; - } - - e = buf + len; - bp = buf; - while (bp < e) { - ava = CERT_ParseRFC1485AVA(name->arena, &bp, e, PR_FALSE); - if (ava == 0) goto loser; - rdn = CERT_CreateRDN(name->arena, ava, 0); - if (rdn == 0) goto loser; - rv = CERT_AddRDN(name, rdn); - if (rv) goto loser; - skipSpace(&bp, e); - } - - if (name->rdns[0] == 0) { - /* empty name -- illegal */ - goto loser; - } - - /* Reverse order of RDNS to comply with RFC */ - { - CERTRDN **firstRdn; - CERTRDN **lastRdn; - CERTRDN *tmp; - - /* get first one */ - firstRdn = name->rdns; - - /* find last one */ - lastRdn = name->rdns; - while (*lastRdn) lastRdn++; - lastRdn--; - - /* reverse list */ - for ( ; firstRdn < lastRdn; firstRdn++, lastRdn--) { - tmp = *firstRdn; - *firstRdn = *lastRdn; - *lastRdn = tmp; - } - } - - /* return result */ - return name; - - loser: - CERT_DestroyName(name); - return NULL; -} - -CERTName * -CERT_AsciiToName(char *string) -{ - CERTName *name; - name = ParseRFC1485Name(string, PORT_Strlen(string)); - return name; -} - -/************************************************************************/ - -typedef struct stringBufStr { - char *buffer; - unsigned offset; - unsigned size; -} stringBuf; - -#define DEFAULT_BUFFER_SIZE 200 -#define MAX(x,y) ((x) > (y) ? (x) : (y)) - -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 = 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; - - /* need to make an initial pass to determine if quoting is needed */ - for (i = 0; i < srclen; i++) { - char c = src[i]; - reqLen++; - if (SPECIAL_CHAR(c)) { - /* entirety will need quoting */ - needsQuoting = PR_TRUE; - } - if (c == C_DOUBLE_QUOTE || c == C_BACKSLASH) { - /* this char will need escaping */ - reqLen++; - } - } - /* if it begins or ends in optional space it needs quoting */ - if (srclen > 0 && - (OPTIONAL_SPACE(src[srclen-1]) || OPTIONAL_SPACE(src[0]))) { - needsQuoting = PR_TRUE; - } - - if (needsQuoting) reqLen += 2; - - /* space for terminal null */ - reqLen++; - - if (reqLen > dstlen) { - PORT_SetError(SEC_ERROR_OUTPUT_LEN); - return SECFailure; - } - - d = dst; - if (needsQuoting) *d++ = C_DOUBLE_QUOTE; - for (i = 0; i < srclen; i++) { - char c = src[i]; - if (c == C_DOUBLE_QUOTE || c == C_BACKSLASH) { - /* escape it */ - *d++ = C_BACKSLASH; - } - *d++ = c; - } - if (needsQuoting) *d++ = C_DOUBLE_QUOTE; - *d++ = 0; - return SECSuccess; -} - -static SECStatus -AppendAVA(stringBuf *bufp, CERTAVA *ava) -{ - char *tagName; - char tmpBuf[384]; - unsigned len, maxLen; - int tag; - SECStatus rv; - SECItem *avaValue = NULL; - - tag = CERT_GetAVATag(ava); - switch (tag) { - case SEC_OID_AVA_COUNTRY_NAME: - tagName = "C"; - maxLen = 2; - break; - case SEC_OID_AVA_ORGANIZATION_NAME: - tagName = "O"; - maxLen = 64; - break; - case SEC_OID_AVA_COMMON_NAME: - tagName = "CN"; - maxLen = 64; - break; - case SEC_OID_AVA_LOCALITY: - tagName = "L"; - maxLen = 128; - break; - case SEC_OID_AVA_STATE_OR_PROVINCE: - tagName = "ST"; - maxLen = 128; - break; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - tagName = "OU"; - maxLen = 64; - break; - case SEC_OID_AVA_DC: - tagName = "DC"; - maxLen = 128; - break; - case SEC_OID_AVA_DN_QUALIFIER: - tagName = "dnQualifier"; - maxLen = 0x7fff; - break; - case SEC_OID_PKCS9_EMAIL_ADDRESS: - tagName = "E"; - maxLen = 128; - break; - case SEC_OID_RFC1274_UID: - tagName = "UID"; - maxLen = 256; - break; - case SEC_OID_RFC1274_MAIL: - tagName = "MAIL"; - maxLen = 256; - break; - default: -#if 0 - PORT_SetError(SEC_ERROR_INVALID_AVA); - return SECFailure; -#else - rv = AppendStr(bufp, "ERR=Unknown AVA"); - return rv; -#endif - } - - avaValue = CERT_DecodeAVAValue(&ava->value); - if(!avaValue) { - return SECFailure; - } - - /* Check value length */ - if (avaValue->len > maxLen) { - PORT_SetError(SEC_ERROR_INVALID_AVA); - return SECFailure; - } - - len = PORT_Strlen(tagName); - PORT_Memcpy(tmpBuf, tagName, len); - tmpBuf[len++] = '='; - - /* escape and quote as necessary */ - rv = CERT_RFC1485_EscapeAndQuote(tmpBuf+len, sizeof(tmpBuf)-len, - (char *)avaValue->data, avaValue->len); - SECITEM_FreeItem(avaValue, PR_TRUE); - if (rv) return SECFailure; - - rv = AppendStr(bufp, tmpBuf); - return rv; -} - -char * -CERT_NameToAscii(CERTName *name) -{ - SECStatus rv; - CERTRDN** rdns; - CERTRDN** lastRdn; - CERTRDN** rdn; - CERTAVA** avas; - CERTAVA* ava; - PRBool first = PR_TRUE; - char *buf = NULL; - unsigned buflen = 0; - 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--) { - avas = (*rdn)->avas; - while ((ava = *avas++) != NULL) { - /* Put in comma separator */ - if (!first) { - rv = AppendStr(&strBuf, ", "); - if (rv) goto loser; - } else { - first = PR_FALSE; - } - - /* Add in tag type plus value into buf */ - rv = AppendAVA(&strBuf, ava); - if (rv) goto loser; - } - } - 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; - CERTAVA** avas; - CERTAVA* ava; - char *buf = 0; - int tag; - SECItem *decodeItem = NULL; - - rdns = name->rdns; - while ((rdn = *rdns++) != 0) { - avas = rdn->avas; - while ((ava = *avas++) != 0) { - tag = CERT_GetAVATag(ava); - if ( tag == wantedTag ) { - decodeItem = CERT_DecodeAVAValue(&ava->value); - if(!decodeItem) { - return NULL; - } - 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; - char *emailAddr = 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); -} - -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); -} - -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 ba28a2713..000000000 --- a/security/nss/lib/certdb/cert.h +++ /dev/null @@ -1,1434 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * cert.h - public data structures and prototypes for the certificate library - * - * $Id$ - */ - -#ifndef _CERT_H_ -#define _CERT_H_ - -#include "plarena.h" -#include "plhash.h" -#include "prlong.h" -#include "prlog.h" - -#include "seccomon.h" -#include "secdert.h" -#include "secoidt.h" -#include "keyt.h" -#include "certt.h" - -SEC_BEGIN_PROTOS - -/**************************************************************************** - * - * RFC1485 ascii to/from X.? RelativeDistinguishedName (aka CERTName) - * - ****************************************************************************/ - -/* -** Convert an ascii RFC1485 encoded name into its CERTName equivalent. -*/ -extern CERTName *CERT_AsciiToName(char *string); - -/* -** Convert an CERTName into its RFC1485 encoded equivalent. -*/ -extern char *CERT_NameToAscii(CERTName *name); - -extern CERTAVA *CERT_CopyAVA(PRArenaPool *arena, CERTAVA *src); - -/* -** Examine an AVA and return the tag that refers to it. The AVA tags are -** defined as SEC_OID_AVA*. -*/ -extern SECOidTag CERT_GetAVATag(CERTAVA *ava); - -/* -** Compare two AVA's, returning the difference between them. -*/ -extern SECComparison CERT_CompareAVA(CERTAVA *a, CERTAVA *b); - -/* -** Create an RDN (relative-distinguished-name). The argument list is a -** NULL terminated list of AVA's. -*/ -extern CERTRDN *CERT_CreateRDN(PRArenaPool *arena, CERTAVA *avas, ...); - -/* -** Make a copy of "src" storing it in "dest". -*/ -extern SECStatus CERT_CopyRDN(PRArenaPool *arena, CERTRDN *dest, CERTRDN *src); - -/* -** Destory an RDN object. -** "rdn" the RDN to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void CERT_DestroyRDN(CERTRDN *rdn, PRBool freeit); - -/* -** Add an AVA to an RDN. -** "rdn" the RDN to add to -** "ava" the AVA to add -*/ -extern SECStatus CERT_AddAVA(PRArenaPool *arena, CERTRDN *rdn, CERTAVA *ava); - -/* -** Compare two RDN's, returning the difference between them. -*/ -extern SECComparison CERT_CompareRDN(CERTRDN *a, CERTRDN *b); - -/* -** Create an X.500 style name using a NULL terminated list of RDN's. -*/ -extern CERTName *CERT_CreateName(CERTRDN *rdn, ...); - -/* -** Make a copy of "src" storing it in "dest". Memory is allocated in -** "dest" for each of the appropriate sub objects. Memory is not freed in -** "dest" before allocation is done (use CERT_DestroyName(dest, PR_FALSE) to -** do that). -*/ -extern SECStatus CERT_CopyName(PRArenaPool *arena, CERTName *dest, CERTName *src); - -/* -** Destroy a Name object. -** "name" the CERTName to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void CERT_DestroyName(CERTName *name); - -/* -** Add an RDN to a name. -** "name" the name to add the RDN to -** "rdn" the RDN to add to name -*/ -extern SECStatus CERT_AddRDN(CERTName *name, CERTRDN *rdn); - -/* -** Compare two names, returning the difference between them. -*/ -extern SECComparison CERT_CompareName(CERTName *a, CERTName *b); - -/* -** Convert a CERTName into something readable -*/ -extern char *CERT_FormatName (CERTName *name); - -/* -** Convert a der-encoded integer to a hex printable string form. -** Perhaps this should be a SEC function but it's only used for certs. -*/ -extern char *CERT_Hexify (SECItem *i, int do_colon); - -/****************************************************************************** - * - * Certificate handling operations - * - *****************************************************************************/ - -/* -** Create a new validity object given two unix time values. -** "notBefore" the time before which the validity is not valid -** "notAfter" the time after which the validity is not valid -*/ -extern CERTValidity *CERT_CreateValidity(int64 notBefore, int64 notAfter); - -/* -** Destroy a validity object. -** "v" the validity to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void CERT_DestroyValidity(CERTValidity *v); - -/* -** Copy the "src" object to "dest". Memory is allocated in "dest" for -** each of the appropriate sub-objects. Memory in "dest" is not freed -** before memory is allocated (use CERT_DestroyValidity(v, PR_FALSE) to do -** that). -*/ -extern SECStatus CERT_CopyValidity - (PRArenaPool *arena, CERTValidity *dest, CERTValidity *src); - -/* -** 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 SubjectPublicKeyInfo -*/ -extern SECKEYPublicKey *CERT_ExtractPublicKey(CERTCertificate *cert); - -/* - * used to get a public key with Key Material ID. Only used for fortezza V1 - * certificates. - */ -extern SECKEYPublicKey *CERT_KMIDPublicKey(CERTCertificate *cert); - - -/* -** Retrieve the Key Type associated with the cert we're dealing with -*/ - -extern KeyType CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki); - -/* -** Initialize the certificate database. This is called to create -** the initial list of certificates in the database. -*/ -extern SECStatus CERT_InitCertDB(CERTCertDBHandle *handle); - -/* -** Default certificate database routines -*/ -extern void CERT_SetDefaultCertDB(CERTCertDBHandle *handle); - -extern CERTCertDBHandle *CERT_GetDefaultCertDB(void); - -extern CERTCertList *CERT_GetCertChainFromCert(CERTCertificate *cert, - int64 time, - SECCertUsage usage); -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_DecodeDERCrlEx(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_DecodeDERCrlEx */ - -#define CRL_DECODE_DONT_COPY_DER 0x00000001 -#define CRL_DECODE_SKIP_ENTRIES 0x00000002 - -/* 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); - -/* -** 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 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); - -/* -** 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(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_GetCommonName(CERTName *name); - -extern char *CERT_GetCertificateEmailAddress(CERTCertificate *cert); - -extern char *CERT_GetCertEmailAddress(CERTName *name); - -extern char *CERT_GetCommonName(CERTName *name); - -extern char *CERT_GetCountryName(CERTName *name); - -extern char *CERT_GetLocalityName(CERTName *name); - -extern char *CERT_GetStateName(CERTName *name); - -extern char *CERT_GetOrgName(CERTName *name); - -extern char *CERT_GetOrgUnitName(CERTName *name); - -extern char *CERT_GetDomainComponentName(CERTName *name); - -extern char *CERT_GetCertUid(CERTName *name); - -/* manipulate the trust parameters of a certificate */ - -extern SECStatus CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust); - -extern SECStatus -CERT_ChangeCertTrust (CERTCertDBHandle *handle, CERTCertificate *cert, - CERTCertTrust *trust); - -extern SECStatus -CERT_ChangeCertTrustByUsage(CERTCertDBHandle *certdb, CERTCertificate *cert, - SECCertUsage usage); - -/************************************************************************* - * - * manipulate the extensions of a certificate - * - ************************************************************************/ - -/* -** Set up a cert for adding X509v3 extensions. Returns an opaque handle -** used by the next two routines. -** "cert" is the certificate we are adding extensions to -*/ -extern void *CERT_StartCertExtensions(CERTCertificate *cert); - -/* -** Add an extension to a certificate. -** "exthandle" is the handle returned by the previous function -** "idtag" is the integer tag for the OID that should ID this extension -** "value" is the value of the extension -** "critical" is the critical extension flag -** "copyData" is a flag indicating whether the value data should be -** copied. -*/ -extern SECStatus CERT_AddExtension (void *exthandle, int idtag, - SECItem *value, PRBool critical, PRBool copyData); - -extern SECStatus CERT_AddExtensionByOID (void *exthandle, SECItem *oid, - SECItem *value, PRBool critical, PRBool copyData); - -extern SECStatus CERT_EncodeAndAddExtension - (void *exthandle, int idtag, void *value, PRBool critical, - const SEC_ASN1Template *atemplate); - -extern SECStatus CERT_EncodeAndAddBitStrExtension - (void *exthandle, int idtag, SECItem *value, PRBool critical); - -/* -** Finish adding cert extensions. Does final processing on extension -** data, putting it in the right format, and freeing any temporary -** storage. -** "exthandle" is the handle used to add extensions to a certificate -*/ -extern SECStatus CERT_FinishExtensions(void *exthandle); - - -/* If the extension is found, return its criticality and value. -** This allocate storage for the returning extension value. -*/ -extern SECStatus CERT_GetExtenCriticality - (CERTCertExtension **extensions, int tag, PRBool *isCritical); - -extern void -CERT_DestroyOidSequence(CERTOidSequence *oidSeq); - -/**************************************************************************** - * - * DER encode and decode extension values - * - ****************************************************************************/ - -/* Encode the value of the basicConstraint extension. -** arena - where to allocate memory for the encoded value. -** value - extension value to encode -** encodedValue - output encoded value -*/ -extern SECStatus CERT_EncodeBasicConstraintValue - (PRArenaPool *arena, CERTBasicConstraints *value, SECItem *encodedValue); - -/* -** Encode the value of the authorityKeyIdentifier extension. -*/ -extern SECStatus CERT_EncodeAuthKeyID - (PRArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue); - -/* -** Encode the value of the crlDistributionPoints extension. -*/ -extern SECStatus CERT_EncodeCRLDistributionPoints - (PRArenaPool *arena, CERTCrlDistributionPoints *value,SECItem *derValue); - -/* -** Decodes a DER encoded basicConstaint extension value into a readable format -** value - decoded value -** encodedValue - value to decoded -*/ -extern SECStatus CERT_DecodeBasicConstraintValue - (CERTBasicConstraints *value, SECItem *encodedValue); - -/* Decodes a DER encoded authorityKeyIdentifier extension value into a -** readable format. -** arena - where to allocate memory for the decoded value -** encodedValue - value to be decoded -** Returns a CERTAuthKeyID structure which contains the decoded value -*/ -extern CERTAuthKeyID *CERT_DecodeAuthKeyID - (PRArenaPool *arena, SECItem *encodedValue); - - -/* Decodes a DER encoded crlDistributionPoints extension value into a -** readable format. -** arena - where to allocate memory for the decoded value -** der - value to be decoded -** Returns a CERTCrlDistributionPoints structure which contains the -** decoded value -*/ -extern CERTCrlDistributionPoints * CERT_DecodeCRLDistributionPoints - (PRArenaPool *arena, SECItem *der); - -/* Extract certain name type from a generalName */ -extern void *CERT_GetGeneralNameByType - (CERTGeneralName *genNames, CERTGeneralNameType type, PRBool derFormat); - - -extern CERTOidSequence * -CERT_DecodeOidSequence(SECItem *seqItem); - - - - -/**************************************************************************** - * - * Find extension values of a certificate - * - ***************************************************************************/ - -extern SECStatus CERT_FindCertExtension - (CERTCertificate *cert, int tag, SECItem *value); - -extern SECStatus CERT_FindNSCertTypeExtension - (CERTCertificate *cert, SECItem *value); - -extern char * CERT_FindNSStringExtension (CERTCertificate *cert, int oidtag); - -extern SECStatus CERT_FindIssuerCertExtension - (CERTCertificate *cert, int tag, SECItem *value); - -extern SECStatus CERT_FindCertExtensionByOID - (CERTCertificate *cert, SECItem *oid, SECItem *value); - -extern char *CERT_FindCertURLExtension (CERTCertificate *cert, int tag, - int catag); - -/* Returns the decoded value of the authKeyID extension. -** Note that this uses passed in the arena to allocate storage for the result -*/ -extern CERTAuthKeyID * CERT_FindAuthKeyIDExten (PRArenaPool *arena,CERTCertificate *cert); - -/* Returns the decoded value of the basicConstraint extension. - */ -extern SECStatus CERT_FindBasicConstraintExten - (CERTCertificate *cert, CERTBasicConstraints *value); - -/* Returns the decoded value of the crlDistributionPoints extension. -** Note that the arena in cert is used to allocate storage for the result -*/ -extern CERTCrlDistributionPoints * CERT_FindCRLDistributionPoints - (CERTCertificate *cert); - -/* Returns value of the keyUsage extension. This uses PR_Alloc to allocate -** buffer for the decoded value, The caller should free up the storage -** allocated in value->data. -*/ -extern SECStatus CERT_FindKeyUsageExtension (CERTCertificate *cert, - SECItem *value); - -/* Return the decoded value of the subjectKeyID extension. The caller should -** free up the storage allocated in retItem->data. -*/ -extern SECStatus CERT_FindSubjectKeyIDExten (CERTCertificate *cert, - SECItem *retItem); - -/* -** If cert is a v3 certificate, and a critical keyUsage extension is included, -** then check the usage against the extension value. If a non-critical -** keyUsage extension is included, this will return SECSuccess without -** checking, since the extension is an advisory field, not a restriction. -** If cert is not a v3 certificate, this will return SECSuccess. -** cert - certificate -** usage - one of the x.509 v3 the Key Usage Extension flags -*/ -extern SECStatus CERT_CheckCertUsage (CERTCertificate *cert, - unsigned char usage); - -/**************************************************************************** - * - * CRL v2 Extensions supported routines - * - ****************************************************************************/ - -extern SECStatus CERT_FindCRLExtensionByOID - (CERTCrl *crl, SECItem *oid, SECItem *value); - -extern SECStatus CERT_FindCRLExtension - (CERTCrl *crl, int tag, SECItem *value); - -extern SECStatus - CERT_FindInvalidDateExten (CERTCrl *crl, int64 *value); - -extern void *CERT_StartCRLExtensions (CERTCrl *crl); - -extern CERTCertNicknames *CERT_GetCertNicknames (CERTCertDBHandle *handle, - int what, void *wincx); - -/* -** Finds the crlNumber extension and decodes its value into 'value' -*/ -extern SECStatus CERT_FindCRLNumberExten (CERTCrl *crl, CERTCrlNumber *value); - -extern void CERT_FreeNicknames(CERTCertNicknames *nicknames); - -extern PRBool CERT_CompareCerts(CERTCertificate *c1, CERTCertificate *c2); - -extern PRBool CERT_CompareCertsForRedirection(CERTCertificate *c1, - CERTCertificate *c2); - -/* -** Generate an array of the Distinguished Names that the given cert database -** "trusts" -*/ -extern CERTDistNames *CERT_GetSSLCACerts(CERTCertDBHandle *handle); - -extern void CERT_FreeDistNames(CERTDistNames *names); - -/* -** Generate an array of Distinguished names from an array of nicknames -*/ -extern CERTDistNames *CERT_DistNamesFromNicknames - (CERTCertDBHandle *handle, char **nicknames, int nnames); - -/* -** Generate a certificate chain from a certificate. -*/ -extern CERTCertificateList * -CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, - PRBool includeRoot); - -extern CERTCertificateList * -CERT_CertListFromCert(CERTCertificate *cert); - -extern CERTCertificateList * -CERT_DupCertList(CERTCertificateList * oldList); - -extern void CERT_DestroyCertificateList(CERTCertificateList *list); - -/* 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); - -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); - -int -CERT_GetNamesLength(CERTGeneralName *names); - -CERTCertificate * -CERT_CompareNameSpace(CERTCertificate *cert, - CERTGeneralName *namesList, - SECItem *namesListIndex, - PRArenaPool *arena, - CERTCertDBHandle *handle); - -SECStatus -CERT_EncodeSubjectKeyID(PRArenaPool *arena, char *value, int len, SECItem *encodedValue); - -char * -CERT_GetNickName(CERTCertificate *cert, CERTCertDBHandle *handle, PRArenaPool *nicknameArena); - -/* - * Creates or adds to a list of all certs with a give subject name, sorted by - * validity time, newest first. Invalid certs are considered older than - * valid certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle, - SECItem *name, int64 sorttime, PRBool validOnly); - -/* - * Creates or adds to a list of all certs with a give nickname, sorted by - * validity time, newest first. Invalid certs are considered older than valid - * certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateNicknameCertList(CERTCertList *certList, CERTCertDBHandle *handle, - char *nickname, int64 sorttime, PRBool validOnly); - -/* - * Creates or adds to a list of all certs with a give email addr, sorted by - * validity time, newest first. Invalid certs are considered older than valid - * certs. If validOnly is set, do not include invalid certs on list. - */ -CERTCertList * -CERT_CreateEmailAddrCertList(CERTCertList *certList, CERTCertDBHandle *handle, - char *emailAddr, int64 sorttime, PRBool validOnly); - -/* - * remove certs from a list that don't have keyUsage and certType - * that match the given usage. - */ -SECStatus -CERT_FilterCertListByUsage(CERTCertList *certList, SECCertUsage usage, - PRBool ca); - -/* - * check the key usage of a cert against a set of required values - */ -SECStatus -CERT_CheckKeyUsage(CERTCertificate *cert, unsigned int requiredUsage); - -/* - * return required key usage and cert type based on cert usage - */ -SECStatus -CERT_KeyUsageAndTypeForCertUsage(SECCertUsage usage, - PRBool ca, - unsigned int *retKeyUsage, - unsigned int *retCertType); -/* - * return required trust flags for various cert usages for CAs - */ -SECStatus -CERT_TrustFlagsForCACertUsage(SECCertUsage usage, - unsigned int *retFlags, - SECTrustType *retTrustType); - -/* - * Find all user certificates that match the given criteria. - * - * "handle" - database to search - * "usage" - certificate usage to match - * "oneCertPerName" - if set then only return the "best" cert per - * name - * "validOnly" - only return certs that are curently valid - * "proto_win" - window handle passed to pkcs11 - */ -CERTCertList * -CERT_FindUserCertsByUsage(CERTCertDBHandle *handle, - SECCertUsage usage, - PRBool oneCertPerName, - PRBool validOnly, - void *proto_win); - -/* - * Find a user certificate that matchs the given criteria. - * - * "handle" - database to search - * "nickname" - nickname to match - * "usage" - certificate usage to match - * "validOnly" - only return certs that are curently valid - * "proto_win" - window handle passed to pkcs11 - */ -CERTCertificate * -CERT_FindUserCertByUsage(CERTCertDBHandle *handle, - char *nickname, - SECCertUsage usage, - PRBool validOnly, - void *proto_win); - -/* - * Filter a list of certificates, removing those certs that do not have - * one of the named CA certs somewhere in their cert chain. - * - * "certList" - the list of certificates to filter - * "nCANames" - number of CA names - * "caNames" - array of CA names in string(rfc 1485) form - * "usage" - what use the certs are for, this is used when - * selecting CA certs - */ -SECStatus -CERT_FilterCertListByCANames(CERTCertList *certList, int nCANames, - char **caNames, SECCertUsage usage); - -/* - * Collect the nicknames from all certs in a CertList. If the cert is not - * valid, append a string to that nickname. - * - * "certList" - the list of certificates - * "expiredString" - the string to append to the nickname of any expired cert - * "notYetGoodString" - the string to append to the nickname of any cert - * that is not yet valid - */ -CERTCertNicknames * -CERT_NicknameStringsFromCertList(CERTCertList *certList, char *expiredString, - char *notYetGoodString); - -/* - * Extract the nickname from a nickmake string that may have either - * expiredString or notYetGoodString appended. - * - * Args: - * "namestring" - the string containing the nickname, and possibly - * one of the validity label strings - * "expiredString" - the expired validity label string - * "notYetGoodString" - the not yet good validity label string - * - * Returns the raw nickname - */ -char * -CERT_ExtractNicknameString(char *namestring, char *expiredString, - char *notYetGoodString); - -/* - * Given a certificate, return a string containing the nickname, and possibly - * one of the validity strings, based on the current validity state of the - * certificate. - * - * "arena" - arena to allocate returned string from. If NULL, then heap - * is used. - * "cert" - the cert to get nickname from - * "expiredString" - the string to append to the nickname if the cert is - * expired. - * "notYetGoodString" - the string to append to the nickname if the cert is - * not yet good. - */ -char * -CERT_GetCertNicknameWithValidity(PRArenaPool *arena, CERTCertificate *cert, - char *expiredString, char *notYetGoodString); - -/* - * Return the string representation of a DER encoded distinguished name - * "dername" - The DER encoded name to convert - */ -char * -CERT_DerNameToAscii(SECItem *dername); - -/* - * Supported usage values and types: - * certUsageSSLClient - * certUsageSSLServer - * certUsageSSLServerWithStepUp - * certUsageEmailSigner - * certUsageEmailRecipient - * certUsageObjectSigner - */ - -CERTCertificate * -CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName, - CERTCertOwner owner, SECCertUsage usage, - PRBool preferTrusted, int64 validTime, PRBool validOnly); - - -/*********************************************************************/ -/* A thread safe implementation of General Names */ -/*********************************************************************/ - -/* Destroy a Single CERTGeneralName */ -void -CERT_DestroyGeneralName(CERTGeneralName *name); - -/* Destroys a CERTGeneralNameList */ -void -CERT_DestroyGeneralNameList(CERTGeneralNameList *list); - -/* Creates a CERTGeneralNameList */ -CERTGeneralNameList * -CERT_CreateGeneralNameList(CERTGeneralName *name); - -/* Compares two CERTGeneralNameList */ -SECStatus -CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b); - -/* returns a copy of the first name of the type requested */ -void * -CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, - CERTGeneralNameType type, - PRArenaPool *arena); - -/* Adds a name to the tail of the list */ -void -CERT_AddGeneralNameToList(CERTGeneralNameList *list, - CERTGeneralNameType type, - void *data, SECItem *oid); - -/* returns a duplicate of the CERTGeneralNameList */ -CERTGeneralNameList * -CERT_DupGeneralNameList(CERTGeneralNameList *list); - -/* returns the length of a CERTGeneralName */ -int -CERT_GetNamesLength(CERTGeneralName *names); - -/* - * Acquire the global lock on the cert database. - * This lock is currently used for the following operations: - * adding or deleting a cert to either the temp or perm databases - * converting a temp to perm or perm to temp - * changing(maybe just adding?) the trust of a cert - * adjusting the reference count of a cert - */ -void -CERT_LockDB(CERTCertDBHandle *handle); - -/* - * Free the global cert database lock. - */ -void -CERT_UnlockDB(CERTCertDBHandle *handle); - -/* - * Get the certificate status checking configuratino data for - * the certificate database - */ -CERTStatusConfig * -CERT_GetStatusConfig(CERTCertDBHandle *handle); - -/* - * Set the certificate status checking information for the - * database. The input structure becomes part of the certificate - * database and will be freed by calling the 'Destroy' function in - * the configuration object. - */ -void -CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config); - - - -/* - * Acquire the cert reference count lock - * There is currently one global lock for all certs, but I'm putting a cert - * arg here so that it will be easy to make it per-cert in the future if - * that turns out to be necessary. - */ -void -CERT_LockCertRefCount(CERTCertificate *cert); - -/* - * Free the cert reference count lock - */ -void -CERT_UnlockCertRefCount(CERTCertificate *cert); - -/* - * Acquire the cert trust lock - * There is currently one global lock for all certs, but I'm putting a cert - * arg here so that it will be easy to make it per-cert in the future if - * that turns out to be necessary. - */ -void -CERT_LockCertTrust(CERTCertificate *cert); - -/* - * Free the cert trust lock - */ -void -CERT_UnlockCertTrust(CERTCertificate *cert); - -/* - * Digest the cert's subject public key using the specified algorithm. - * The necessary storage for the digest data is allocated. If "fill" is - * non-null, the data is put there, otherwise a SECItem is allocated. - * Allocation from "arena" if it is non-null, heap otherwise. Any problem - * results in a NULL being returned (and an appropriate error set). - */ -extern SECItem * -CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert, - SECOidTag digestAlg, SECItem *fill); - -/* - * fill in nsCertType field of the cert based on the cert extension - */ -extern SECStatus CERT_GetCertType(CERTCertificate *cert); - -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 35ffc9e36..000000000 --- a/security/nss/lib/certdb/certdb.c +++ /dev/null @@ -1,2630 +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 "secder.h" -#include "secoid.h" -#include "secasn1.h" -#include "blapi.h" /* for SHA1_HashBuf */ -#include "genname.h" -#include "keyhi.h" -#include "secitem.h" -#include "mcom_db.h" -#include "certdb.h" -#include "prprf.h" -#include "sechash.h" -#include "prlong.h" -#include "certxutl.h" -#include "portreg.h" -#include "secerr.h" -#include "sslerr.h" -#include "nsslocks.h" -#include "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; - - tmpitem.data = NULL; - CERT_FindNSCertTypeExtension(cert, &tmpitem); - rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, - &encodedExtKeyUsage); - if (rv == SECSuccess) { - extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage); - } - rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); - if (rv == SECSuccess) { - basicConstraintPresent = PR_TRUE; - } - if (tmpitem.data != NULL || extKeyUsage != NULL) { - if (tmpitem.data == NULL) { - cert->nsCertType = 0; - } else { - cert->nsCertType = tmpitem.data[0]; - } - - /* free tmpitem data pointer to avoid memory leak */ - PORT_Free(tmpitem.data); - tmpitem.data = NULL; - - /* - * for this release, we will allow SSL certs with an email address - * to be used for email - */ - if ( ( cert->nsCertType & NS_CERT_TYPE_SSL_CLIENT ) && - cert->emailAddr ) { - cert->nsCertType |= NS_CERT_TYPE_EMAIL; - } - /* - * for this release, we will allow SSL intermediate CAs to be - * email intermediate CAs too. - */ - if ( cert->nsCertType & NS_CERT_TYPE_SSL_CA ) { - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } - /* - * allow a cert with the extended key usage of EMail Protect - * to be used for email or as an email CA, if basic constraints - * indicates that it is a CA. - */ - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) == - SECSuccess) { - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_EMAIL; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) == - SECSuccess){ - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_SSL_SERVER; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) == - SECSuccess){ - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_SSL_CLIENT; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_CODE_SIGN) == - SECSuccess) { - if (basicConstraintPresent == PR_TRUE && - (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA; - } else { - cert->nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING; - } - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_EXT_KEY_USAGE_TIME_STAMP) == - SECSuccess) { - cert->nsCertType |= EXT_KEY_USAGE_TIME_STAMP; - } - if (findOIDinOIDSeqByTagNum(extKeyUsage, - SEC_OID_OCSP_RESPONDER) == - SECSuccess) { - cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } - } else { - /* if no extension, then allow any ssl or email (no ca or object - * signing) - */ - cert->nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | - NS_CERT_TYPE_EMAIL; - - /* if the basic constraint extension says the cert is a CA, then - allow SSL CA and EMAIL CA and Status Responder */ - if ((basicConstraintPresent == PR_TRUE) - && (basicConstraint.isCA)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } else if (CERT_IsCACert(cert, NULL) == PR_TRUE) { - cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } - - /* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */ - if (fortezzaIsCA(cert)) { - cert->nsCertType |= NS_CERT_TYPE_SSL_CA; - cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA; - } - } - - if (extKeyUsage != NULL) { - PORT_Free(encodedExtKeyUsage.data); - CERT_DestroyOidSequence(extKeyUsage); - } - return(SECSuccess); -} - -/* - * cert_GetKeyID() - extract or generate the subjectKeyID from a certificate - */ -SECStatus -cert_GetKeyID(CERTCertificate *cert) -{ - SECItem tmpitem; - SECStatus rv; - SECKEYPublicKey *key; - - cert->subjectKeyID.len = 0; - - /* see of the cert has a key identifier extension */ - rv = CERT_FindSubjectKeyIDExten(cert, &tmpitem); - if ( rv == SECSuccess ) { - cert->subjectKeyID.data = (unsigned char*) PORT_ArenaAlloc(cert->arena, tmpitem.len); - if ( cert->subjectKeyID.data != NULL ) { - PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len); - cert->subjectKeyID.len = tmpitem.len; - cert->keyIDGenerated = PR_FALSE; - } - - PORT_Free(tmpitem.data); - } - - /* if the cert doesn't have a key identifier extension and the cert is - * a V1 fortezza certificate, use the cert's 8 byte KMID as the - * key identifier. */ - key = CERT_KMIDPublicKey(cert); - - if (key != NULL) { - - if (key->keyType == fortezzaKey) { - - cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, 8); - if ( cert->subjectKeyID.data != NULL ) { - PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8); - cert->subjectKeyID.len = 8; - cert->keyIDGenerated = PR_FALSE; - } - } - - SECKEY_DestroyPublicKey(key); - } - - /* if the cert doesn't have a key identifier extension, then generate one*/ - if ( cert->subjectKeyID.len == 0 ) { - /* - * pkix says that if the subjectKeyID is not present, then we should - * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert - */ - cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH); - if ( cert->subjectKeyID.data != NULL ) { - rv = 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); - -} - -/* - * 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_GetCertificateEmailAddress(cert); - - /* initialize the subjectKeyID */ - rv = cert_GetKeyID(cert); - if ( rv != SECSuccess ) { - goto loser; - } - - /* initialize keyUsage */ - rv = GetKeyUsage(cert); - if ( rv != SECSuccess ) { - goto loser; - } - - /* initialize the certType */ - rv = CERT_GetCertType(cert); - if ( rv != SECSuccess ) { - goto loser; - } - - tmpname = CERT_NameToAscii(&cert->subject); - if ( tmpname != NULL ) { - cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname); - PORT_Free(tmpname); - } - - tmpname = CERT_NameToAscii(&cert->issuer); - if ( tmpname != NULL ) { - cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname); - PORT_Free(tmpname); - } - - cert->referenceCount = 1; - cert->slot = NULL; - cert->pkcs11ID = CK_INVALID_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) -{ - int rv; - - /* convert DER not-before time */ - rv = DER_UTCTimeToTime(notBefore, &c->validity.notBefore); - if (rv) { - return(SECFailure); - } - - /* convert DER not-after time */ - rv = DER_UTCTimeToTime(notAfter, &c->validity.notAfter); - if (rv) { - return(SECFailure); - } - - return(SECSuccess); -} - -/* - * Check the validity times of a certificate - */ -SECCertTimeValidity -CERT_CheckCertValidTimes(CERTCertificate *c, 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 = DER_UTCTimeToTime(notBefore, &date->lastUpdate); - if (rv) { - return(SECFailure); - } - - /* convert DER not-after time */ - if (date->nextUpdate.data) { - rv = DER_UTCTimeToTime(notAfter, &date->nextUpdate); - if (rv) { - return(SECFailure); - } - } - else { - LL_I2L(*notAfter, 0L); - } - return(SECSuccess); -} - -/* These routines should probably be combined with the cert - * routines using an common extraction routine. - */ -SECCertTimeValidity -SEC_CheckCrlTimes(CERTCrl *crl, 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) -{ - SECKEYPublicKey *key; - - /* choose between key agreement or key encipherment based on key - * type in cert - */ - if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) { - key = CERT_ExtractPublicKey(cert); - if ( ( key->keyType == keaKey ) || ( key->keyType == fortezzaKey ) || - ( key->keyType == dhKey ) ) { - requiredUsage |= KU_KEY_AGREEMENT; - } else { - requiredUsage |= KU_KEY_ENCIPHERMENT; - } - - /* now turn off the special bit */ - requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT); - - SECKEY_DestroyPublicKey(key); - } - - if ( ( cert->keyUsage & requiredUsage ) != requiredUsage ) { - return(SECFailure); - } - return(SECSuccess); -} - - -CERTCertificate * -CERT_DupCertificate(CERTCertificate *c) -{ - if (c) { -#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); - } - } - } - 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; -} - - -/* - * 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 UTC time */ - now = PR_Now(); - - if ( newerbefore ) { - /* cert A was issued after cert B, but expires sooner */ - /* if A is expired, then pick B */ - if ( LL_CMP(notAfterA, <, now ) ) { - return(PR_FALSE); - } - return(PR_TRUE); - } else { - /* cert B was issued after cert A, but expires sooner */ - /* if B is expired, then pick A */ - if ( LL_CMP(notAfterB, <, now ) ) { - return(PR_TRUE); - } - return(PR_FALSE); - } -} - -void -CERT_DestroyCertArray(CERTCertificate **certs, unsigned int ncerts) -{ - unsigned int i; - - if ( certs ) { - for ( i = 0; i < ncerts; i++ ) { - if ( certs[i] ) { - CERT_DestroyCertificate(certs[i]); - } - } - - PORT_Free(certs); - } - - return; -} - -char * -CERT_FixupEmailAddr(char *emailAddr) -{ - char *retaddr; - char *str; - - if ( emailAddr == NULL ) { - return(NULL); - } - - /* copy the string */ - str = retaddr = PORT_Strdup(emailAddr); - if ( str == NULL ) { - return(NULL); - } - - /* make it lower case */ - while ( *str ) { - *str = tolower( *str ); - str++; - } - - return(retaddr); -} - -/* - * NOTE - don't allow encode of govt-approved or invisible bits - */ -SECStatus -CERT_DecodeTrustString(CERTCertTrust *trust, char *trusts) -{ - 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 == NULL ) { - saveit = PR_FALSE; - } - - if ( certtype & NS_CERT_TYPE_EMAIL ) { - trust.emailFlags = CERTDB_VALID_PEER; - if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) { - /* don't save it if KeyEncipherment is not allowed */ - saveit = PR_FALSE; - } - } - } - break; - case certUsageUserCertImport: - if ( isCA ) { - if ( certtype & NS_CERT_TYPE_SSL_CA ) { - trust.sslFlags = CERTDB_VALID_CA; - } - - if ( certtype & NS_CERT_TYPE_EMAIL_CA ) { - trust.emailFlags = CERTDB_VALID_CA; - } - - if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) { - trust.objectSigningFlags = CERTDB_VALID_CA; - } - - } else { - if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) { - trust.sslFlags = CERTDB_VALID_PEER; - } - - if ( certtype & NS_CERT_TYPE_EMAIL ) { - trust.emailFlags = CERTDB_VALID_PEER; - } - - if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) { - trust.objectSigningFlags = CERTDB_VALID_PEER; - } - } - break; - 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 = (CERTCertificate**)PORT_ZAlloc(sizeof(CERTCertificate *) * ncerts ); - if ( certs == NULL ) { - return(SECFailure); - } - - /* decode all of the certs into the temporary DB */ - for ( i = 0, fcerts= 0; i < ncerts; i++) { - certs[fcerts] = CERT_NewTempCertificate(certdb, - derCerts[i], - NULL, - PR_FALSE, - PR_TRUE); - if (certs[fcerts]) fcerts++; - } - - if ( keepCerts ) { - for ( i = 0; i < fcerts; i++ ) { - 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(SECSuccess); - -#if 0 /* dead code here - why ?? XXX */ -loser: - if ( retCerts ) { - *retCerts = NULL; - } - if ( certs ) { - CERT_DestroyCertArray(certs, ncerts); - } - return(SECFailure); -#endif -} - -/* - * a real list of certificates - need to convert CERTCertificateList - * stuff and ASN 1 encoder/decoder over to using this... - */ -CERTCertList * -CERT_NewCertList(void) -{ - PRArenaPool *arena = NULL; - CERTCertList *ret = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList)); - if ( ret == NULL ) { - goto loser; - } - - ret->arena = arena; - - PR_INIT_CLIST(&ret->list); - - return(ret); - -loser: - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -void -CERT_DestroyCertList(CERTCertList *certs) -{ - PRCList *node; - - while( !PR_CLIST_IS_EMPTY(&certs->list) ) { - node = PR_LIST_HEAD(&certs->list); - CERT_DestroyCertificate(((CERTCertListNode *)node)->cert); - PR_REMOVE_LINK(node); - } - - PORT_FreeArena(certs->arena, PR_FALSE); - - return; -} - -void -CERT_RemoveCertListNode(CERTCertListNode *node) -{ - CERT_DestroyCertificate(node->cert); - PR_REMOVE_LINK(&node->links); - return; -} - - -SECStatus -CERT_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; - PRBool bad; - SECStatus rv; - unsigned int certType; - PRBool dummyret; - - if (certList == NULL) goto loser; - - rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage, - &requiredCertType); - if ( rv != SECSuccess ) { - goto loser; - } - - node = CERT_LIST_HEAD(certList); - - while ( !CERT_LIST_END(node, certList) ) { - - bad = PR_FALSE; - - /* bad key usage */ - if ( CERT_CheckKeyUsage(node->cert, requiredKeyUsage ) - != SECSuccess ) { - bad = PR_TRUE; - } - /* bad cert type */ - if ( ca ) { - /* This function returns a more comprehensive cert type that - * takes trust flags into consideration. Should probably - * fix the cert decoding code to do this. - */ - dummyret = CERT_IsCACert(node->cert, &certType); - } else { - certType = node->cert->nsCertType; - } - - if ( ! ( certType & requiredCertType ) ) { - bad = PR_TRUE; - } - - if ( bad ) { - /* remove the node if it is bad */ - savenode = CERT_LIST_NEXT(node); - CERT_RemoveCertListNode(node); - node = savenode; - } else { - node = CERT_LIST_NEXT(node); - } - } - return(SECSuccess); - -loser: - return(SECFailure); -} - -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; -} diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h deleted file mode 100644 index 7340961c2..000000000 --- a/security/nss/lib/certdb/certdb.h +++ /dev/null @@ -1,159 +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); - -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 05bcd4c7c..000000000 --- a/security/nss/lib/certdb/certi.h +++ /dev/null @@ -1,50 +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 _CERTI_H_ -#define _CERTI_H_ - -#include "certt.h" - -typedef struct OpaqueCRLFieldsStr OpaqueCRLFields; - -struct OpaqueCRLFieldsStr { - /* these fields are subject to change */ - PRBool partial; -}; - -#endif /* _CERTI_H_ */ diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h deleted file mode 100644 index 80c3d8fc8..000000000 --- a/security/nss/lib/certdb/certt.h +++ /dev/null @@ -1,848 +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 fields are used by client GUI code to keep track of ssl sockets - * that are blocked waiting on GUI feedback related to this cert. - * XXX - these should be moved into some sort of application specific - * data structure. They are only used by the browser right now. - */ - struct SECSocketNode *socketlist; - int socketcount; - struct SECSocketNode *authsocketlist; - int 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)) - -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 highestUsage 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_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_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 ea48b704c..000000000 --- a/security/nss/lib/certdb/certv3.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Code for dealing with X509.V3 extensions. - * - * $Id$ - */ - -#include "cert.h" -#include "secitem.h" -#include "secoid.h" -#include "secder.h" -#include "secasn1.h" -#include "certxutl.h" -#include "secerr.h" - -SECStatus -CERT_FindCertExtensionByOID(CERTCertificate *cert, SECItem *oid, - SECItem *value) -{ - return (cert_FindExtensionByOID (cert->extensions, oid, value)); -} - - -SECStatus -CERT_FindCertExtension(CERTCertificate *cert, int tag, SECItem *value) -{ - return (cert_FindExtension (cert->extensions, tag, value)); -} - -static void -SetExts(void *object, CERTCertExtension **exts) -{ - CERTCertificate *cert = (CERTCertificate *)object; - - cert->extensions = exts; - DER_SetUInteger (cert->arena, &(cert->version), SEC_CERTIFICATE_VERSION_3); -} - -void * -CERT_StartCertExtensions(CERTCertificate *cert) -{ - return (cert_StartExtensions ((void *)cert, cert->arena, SetExts)); -} - -/* find the given extension in the certificate of the Issuer of 'cert' */ -SECStatus -CERT_FindIssuerCertExtension(CERTCertificate *cert, int tag, SECItem *value) -{ - CERTCertificate *issuercert; - SECStatus rv; - - issuercert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer); - if ( issuercert ) { - rv = cert_FindExtension(issuercert->extensions, tag, value); - CERT_DestroyCertificate(issuercert); - } else { - rv = SECFailure; - } - - return(rv); -} - -/* find a URL extension in the cert or its CA - * apply the base URL string if it exists - */ -char * -CERT_FindCertURLExtension(CERTCertificate *cert, int tag, int catag) -{ - SECStatus rv; - SECItem urlitem; - SECItem baseitem; - SECItem urlstringitem = {siBuffer,0}; - SECItem basestringitem = {siBuffer,0}; - PRArenaPool *arena = NULL; - PRBool hasbase; - char *urlstring; - char *str; - int len; - int i; - - urlstring = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( ! arena ) { - goto loser; - } - - hasbase = PR_FALSE; - urlitem.data = NULL; - baseitem.data = NULL; - - rv = cert_FindExtension(cert->extensions, tag, &urlitem); - if ( rv == SECSuccess ) { - rv = cert_FindExtension(cert->extensions, SEC_OID_NS_CERT_EXT_BASE_URL, - &baseitem); - if ( rv == SECSuccess ) { - hasbase = PR_TRUE; - } - - } else if ( catag ) { - /* if the cert doesn't have the extensions, see if the issuer does */ - rv = CERT_FindIssuerCertExtension(cert, catag, &urlitem); - if ( rv != SECSuccess ) { - goto loser; - } - rv = CERT_FindIssuerCertExtension(cert, SEC_OID_NS_CERT_EXT_BASE_URL, - &baseitem); - if ( rv == SECSuccess ) { - hasbase = PR_TRUE; - } - } else { - goto loser; - } - - rv = SEC_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_FindSubjectKeyIDExten(CERTCertificate *cert, SECItem *retItem) -{ - - SECItem encodedValue; - SECStatus rv; - - encodedValue.data = NULL; - rv = cert_FindExtension - (cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID, &encodedValue); - if (rv != SECSuccess) - return (rv); - rv = SEC_ASN1DecodeItem (NULL, retItem, SEC_OctetStringTemplate, - &encodedValue); - PORT_Free (encodedValue.data); - - return (rv); -} - -SECStatus -CERT_FindBasicConstraintExten(CERTCertificate *cert, - CERTBasicConstraints *value) -{ - SECItem encodedExtenValue; - SECStatus rv; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS, - &encodedExtenValue); - if ( rv != SECSuccess ) { - return (rv); - } - - rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue); - - /* free the raw extension data */ - PORT_Free(encodedExtenValue.data); - encodedExtenValue.data = NULL; - - return(rv); -} - -CERTAuthKeyID * -CERT_FindAuthKeyIDExten (PRArenaPool *arena, CERTCertificate *cert) -{ - SECItem encodedExtenValue; - SECStatus rv; - CERTAuthKeyID *ret; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID, - &encodedExtenValue); - if ( rv != SECSuccess ) { - return (NULL); - } - - ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue); - - PORT_Free(encodedExtenValue.data); - encodedExtenValue.data = NULL; - - return(ret); -} - -SECStatus -CERT_CheckCertUsage(CERTCertificate *cert, unsigned char usage) -{ - PRBool critical; - SECItem keyUsage; - SECStatus rv; - - /* There is no extension, v1 or v2 certificate */ - if (cert->extensions == NULL) { - return (SECSuccess); - } - - keyUsage.data = NULL; - - do { - /* if the keyUsage extension exists and is critical, make sure that the - CA certificate is used for certificate signing purpose only. If the - extension does not exist, we will assum that it can be used for - certificate signing purpose. - */ - rv = CERT_GetExtenCriticality(cert->extensions, - SEC_OID_X509_KEY_USAGE, - &critical); - if (rv == SECFailure) { - rv = (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND) ? - SECSuccess : SECFailure; - break; - } - - if (critical == PR_FALSE) { - rv = SECSuccess; - break; - } - - rv = CERT_FindKeyUsageExtension(cert, &keyUsage); - if (rv != SECSuccess) { - break; - } - if (!(keyUsage.data[0] & usage)) { - PORT_SetError (SEC_ERROR_CERT_USAGES_INVALID); - rv = SECFailure; - } - }while (0); - PORT_Free (keyUsage.data); - return (rv); -} diff --git a/security/nss/lib/certdb/certxutl.c b/security/nss/lib/certdb/certxutl.c deleted file mode 100644 index 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 f34ec4ccc..000000000 --- a/security/nss/lib/certdb/crl.c +++ /dev/null @@ -1,729 +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" - -const SEC_ASN1Template SEC_CERTExtensionTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertExtension) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTCertExtension,id) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ - offsetof(CERTCertExtension,critical), }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTCertExtension,value) }, - { 0, } -}; - -static const SEC_ASN1Template SEC_CERTExtensionsTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, SEC_CERTExtensionTemplate} -}; - -/* - * XXX Also, these templates, especially the Krl/FORTEZZA ones, need to - * be tested; Lisa did the obvious translation but they still should be - * verified. - */ - -const SEC_ASN1Template CERT_IssuerAndSNTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTIssuerAndSN) }, - { SEC_ASN1_SAVE, - offsetof(CERTIssuerAndSN,derIssuer) }, - { SEC_ASN1_INLINE, - offsetof(CERTIssuerAndSN,issuer), - CERT_NameTemplate }, - { SEC_ASN1_INTEGER, - offsetof(CERTIssuerAndSN,serialNumber) }, - { 0 } -}; - -static const SEC_ASN1Template cert_KrlEntryTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrlEntry) }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTCrlEntry,serialNumber) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrlEntry,revocationDate) }, - { 0 } -}; - -static const SEC_ASN1Template cert_KrlTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrl) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,signatureAlg), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_SAVE, - offsetof(CERTCrl,derName) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,name), - CERT_NameTemplate }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,lastUpdate) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,nextUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCrl,entries), - cert_KrlEntryTemplate }, - { 0 } -}; - -static const SEC_ASN1Template cert_SignedKrlTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTSignedCrl) }, - { SEC_ASN1_SAVE, - offsetof(CERTSignedCrl,signatureWrap.data) }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedCrl,crl), - cert_KrlTemplate }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedCrl,signatureWrap.signatureAlgorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(CERTSignedCrl,signatureWrap.signature) }, - { 0 } -}; - -static const SEC_ASN1Template cert_CrlKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrlKey) }, - { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(CERTCrlKey,dummy) }, - { SEC_ASN1_SKIP }, - { SEC_ASN1_ANY, offsetof(CERTCrlKey,derName) }, - { SEC_ASN1_SKIP_REST }, - { 0 } -}; - -static const SEC_ASN1Template cert_CrlEntryTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrlEntry) }, - { SEC_ASN1_INTEGER, - offsetof(CERTCrlEntry,serialNumber) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrlEntry,revocationDate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCrlEntry, extensions), - SEC_CERTExtensionTemplate}, - { 0 } -}; - -const SEC_ASN1Template CERT_CrlTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCrl) }, - { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof (CERTCrl, version) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,signatureAlg), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_SAVE, - offsetof(CERTCrl,derName) }, - { SEC_ASN1_INLINE, - offsetof(CERTCrl,name), - CERT_NameTemplate }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,lastUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,nextUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCrl,entries), - cert_CrlEntryTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_EXPLICIT | 0, - offsetof(CERTCrl,extensions), - SEC_CERTExtensionsTemplate}, - { 0 } -}; - -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_UTC_TIME, - offsetof(CERTCrl,lastUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,nextUpdate) }, - { 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_UTC_TIME }, - { SEC_ASN1_SKIP | SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME }, - { 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); -} - -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; - } - 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; - } - 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_DecodeDERCrlEx(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 ) { - 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) - break; - /* check for critical extentions */ - rv = cert_check_crl_version (&crl->crl); - 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 ((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_DecodeDERCrlEx(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....? - */ -CERTSignedCrl * -SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type) -{ - CERTSignedCrl *crl = NULL; - SECItem *derCrl; - CK_OBJECT_HANDLE crlHandle; - char *url = NULL; - - if (slot) { - PK11_ReferenceSlot(slot); - } - - derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey, type, &url); - if (derCrl == NULL) { - goto loser; - } - PORT_Assert(crlHandle != CK_INVALID_HANDLE); - - crl = CERT_DecodeDERCrl(NULL, derCrl, type); - if (crl) { - crl->slot = slot; - slot = NULL; /* adopt it */ - crl->pkcs11ID = crlHandle; - if (url) { - crl->url = PORT_ArenaStrdup(crl->arena,url); - } - } - if (url) { - PORT_Free(url); - } - -loser: - if (slot) { - PK11_FreeSlot(slot); - } - if (derCrl) { - SECITEM_FreeItem(derCrl,PR_TRUE); - } - return(crl); -} - -SECStatus SEC_DestroyCrl(CERTSignedCrl *crl); - -CERTSignedCrl * -crl_storeCRL (PK11SlotInfo *slot,char *url, - CERTSignedCrl *newCrl, SECItem *derCrl, int type) -{ - CERTSignedCrl *oldCrl = NULL, *crl = NULL; - CK_OBJECT_HANDLE crlHandle; - - oldCrl = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type); - - /* if there is an old crl, make sure the one we are installing - * is newer. If not, exit out, otherwise delete the old crl. - */ - if (oldCrl != NULL) { - /* if 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 */ - SEC_DeletePermCRL(oldCrl); - } - - /* 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) SEC_DestroyCrl(oldCrl); - - return crl; -} - -CERTSignedCrl * -SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type) -{ - return SEC_FindCrlByKeyOnSlot(NULL,crlKey,type); -} - -/* - * - * 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); -} - - -SECStatus -SEC_DestroyCrl(CERTSignedCrl *crl) -{ - if (crl) { - if (crl->referenceCount-- <= 1) { - if (crl->slot) { - PK11_FreeSlot(crl->slot); - } - 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) - diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c deleted file mode 100644 index fadf9d15f..000000000 --- a/security/nss/lib/certdb/genname.c +++ /dev/null @@ -1,1613 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "plarena.h" -#include "seccomon.h" -#include "secitem.h" -#include "secoidt.h" -#include "mcom_db.h" -#include "secasn1.h" -#include "secder.h" -#include "certt.h" -#include "cert.h" -#include "xconst.h" -#include "secerr.h" -#include "secoid.h" -#include "prprf.h" -#include "genname.h" - - - -static const SEC_ASN1Template CERTNameConstraintTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraint) }, - { SEC_ASN1_ANY, offsetof(CERTNameConstraint, DERName) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTNameConstraint, min), SEC_IntegerTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTNameConstraint, max), SEC_IntegerTemplate }, - { 0, } -}; - -const SEC_ASN1Template CERT_NameConstraintSubtreeSubTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate } -}; - - -const SEC_ASN1Template CERT_NameConstraintSubtreePermitedTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 0, 0, CERT_NameConstraintSubtreeSubTemplate } -}; - -const SEC_ASN1Template CERT_NameConstraintSubtreeExcludedTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 1, 0, CERT_NameConstraintSubtreeSubTemplate } -}; - - -static const SEC_ASN1Template CERTNameConstraintsTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTNameConstraints) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTNameConstraints, DERPermited), CERT_NameConstraintSubtreeSubTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTNameConstraints, DERExcluded), CERT_NameConstraintSubtreeSubTemplate}, - { 0, } -}; - - -static const SEC_ASN1Template CERTOthNameTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(OtherName) }, - { SEC_ASN1_OBJECT_ID, - offsetof(OtherName, oid) }, - { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, - offsetof(OtherName, name), SEC_AnyTemplate }, - { 0, } -}; - -static const SEC_ASN1Template CERTOtherNameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 0 , - offsetof(CERTGeneralName, name.OthName), CERTOthNameTemplate, - sizeof(CERTGeneralName) } -}; - -static const SEC_ASN1Template CERTOtherName2Template[] = { - { SEC_ASN1_SEQUENCE | SEC_ASN1_CONTEXT_SPECIFIC | 0 , - 0, NULL, sizeof(CERTGeneralName) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, oid) }, - { SEC_ASN1_ANY, - offsetof(CERTGeneralName, name.OthName) + offsetof(OtherName, name) }, - { 0, } -}; - -static const SEC_ASN1Template CERT_RFC822NameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 1 , - offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_DNSNameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 2 , - offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_X400AddressTemplate[] = { - { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 3, - offsetof(CERTGeneralName, name.other), SEC_AnyTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_DirectoryNameTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 4, - offsetof(CERTGeneralName, derDirectoryName), SEC_AnyTemplate, - sizeof (CERTGeneralName)} -}; - - -static const SEC_ASN1Template CERT_EDIPartyNameTemplate[] = { - { SEC_ASN1_ANY | SEC_ASN1_CONTEXT_SPECIFIC | 5, - offsetof(CERTGeneralName, name.other), SEC_AnyTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_URITemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 6 , - offsetof(CERTGeneralName, name.other), SEC_IA5StringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_IPAddressTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 7 , - offsetof(CERTGeneralName, name.other), SEC_OctetStringTemplate, - sizeof (CERTGeneralName)} -}; - -static const SEC_ASN1Template CERT_RegisteredIDTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | 8 , - offsetof(CERTGeneralName, name.other), SEC_ObjectIDTemplate, - sizeof (CERTGeneralName)} -}; - - -const SEC_ASN1Template CERT_GeneralNamesTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, SEC_AnyTemplate } -}; - - - -void -CERT_DestroyGeneralNameList(CERTGeneralNameList *list) -{ - 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 = (CERTGeneralNameList *) - PORT_ArenaZAlloc(arena, sizeof(CERTGeneralNameList)); - if (name != NULL) { - list->name = (CERTGeneralName *) - PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - list->name->l.next = list->name->l.prev = &list->name->l; - CERT_CopyGeneralName(arena, list->name, name); - } - list->lock = PZ_NewLock(nssILockList); - list->arena = arena; - list->refCount = 1; -done: - return list; -} - -CERTGeneralName * -cert_get_next_general_name(CERTGeneralName *current) -{ - PRCList *next; - - next = current->l.next; - return (CERTGeneralName *) (((char *) next) - offsetof(CERTGeneralName, l)); -} - -CERTGeneralName * -cert_get_prev_general_name(CERTGeneralName *current) -{ - PRCList *prev; - prev = current->l.prev; - return (CERTGeneralName *) (((char *) prev) - offsetof(CERTGeneralName, l)); -} - -CERTNameConstraint * -cert_get_next_name_constraint(CERTNameConstraint *current) -{ - PRCList *next; - - next = current->l.next; - return (CERTNameConstraint *) (((char *) next) - offsetof(CERTNameConstraint, l)); -} - -CERTNameConstraint * -cert_get_prev_name_constraint(CERTNameConstraint *current) -{ - PRCList *prev; - prev = current->l.prev; - return (CERTNameConstraint *) (((char *) prev) - offsetof(CERTNameConstraint, l)); -} - -SECItem * -CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PRArenaPool *arena) -{ - - - PORT_Assert(arena); - if (arena == NULL) { - goto loser; - } - if (dest == NULL) { - dest = (SECItem *) PORT_ArenaZAlloc(arena, sizeof(SECItem)); - } - switch (genName->type) { - case certURI: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_URITemplate); - break; - case certRFC822Name: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_RFC822NameTemplate); - break; - case certDNSName: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_DNSNameTemplate); - break; - case certIPAddress: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_IPAddressTemplate); - break; - case certOtherName: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERTOtherNameTemplate); - break; - case certRegisterID: - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_RegisteredIDTemplate); - break; - case certEDIPartyName: - /* for this type, we expect the value is already encoded */ - dest = SEC_ASN1EncodeItem (arena, dest, genName, - CERT_EDIPartyNameTemplate); - break; - case certX400Address: - /* for this type, we expect the value is already encoded */ - dest = SEC_ASN1EncodeItem (arena, dest, genName, - CERT_X400AddressTemplate); - break; - case certDirectoryName: - if (genName->derDirectoryName.data == NULL) { - /* The field hasn't been encoded yet. */ - SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName), - &(genName->name.directoryName), - CERT_NameTemplate); - } - if (genName->derDirectoryName.data == NULL) { - goto loser; - } - dest = SEC_ASN1EncodeItem(arena, dest, genName, - CERT_DirectoryNameTemplate); - break; - } - if (!dest) { - goto loser; - } - return dest; -loser: - return NULL; -} - - - -SECItem ** -cert_EncodeGeneralNames(PRArenaPool *arena, CERTGeneralName *names) -{ - CERTGeneralName *current_name; - SECItem **items = NULL; - int count = 0; - int i; - PRCList *head; - - PORT_Assert(arena); - current_name = names; - if (names != NULL) { - count = 1; - } - head = &(names->l); - while (current_name->l.next != head) { - current_name = cert_get_next_general_name(current_name); - ++count; - } - current_name = cert_get_next_general_name(current_name); - items = (SECItem **) PORT_ArenaAlloc(arena, sizeof(SECItem *) * (count + 1)); - - if (items == NULL) { - goto loser; - } - for (i = 0; i < count; i++) { - items[i] = CERT_EncodeGeneralName(current_name, (SECItem *) NULL, arena); - if (items[i] == NULL) { - goto loser; - } - current_name = cert_get_next_general_name(current_name); - } - items[i] = NULL; - return items; -loser: - return NULL; -} - -CERTGeneralName * -CERT_DecodeGeneralName(PRArenaPool *arena, - SECItem *encodedName, - CERTGeneralName *genName) -{ - CERTGeneralNameType genNameType; - SECStatus rv = SECSuccess; - - PORT_Assert(arena); - if (genName == NULL) { - genName = (CERTGeneralName *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - } - genNameType = (CERTGeneralNameType)((*(encodedName->data) & 0x0f) + 1); - switch (genNameType) { - case certURI: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_URITemplate, encodedName); - break; - case certRFC822Name: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_RFC822NameTemplate, encodedName); - break; - case certDNSName: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_DNSNameTemplate, encodedName); - break; - case certIPAddress: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_IPAddressTemplate, encodedName); - break; - case certOtherName: - rv = SEC_ASN1DecodeItem(arena, genName, CERTOtherNameTemplate, encodedName); - break; - case certRegisterID: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_RegisteredIDTemplate, encodedName); - break; - case certEDIPartyName: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_EDIPartyNameTemplate, encodedName); - break; - case certX400Address: - rv = SEC_ASN1DecodeItem(arena, genName, CERT_X400AddressTemplate, encodedName); - break; - case certDirectoryName: - rv = SEC_ASN1DecodeItem - (arena, genName, CERT_DirectoryNameTemplate, encodedName); - if (rv != SECSuccess) { - goto loser; - } - rv = SEC_ASN1DecodeItem - (arena, &(genName->name.directoryName), CERT_NameTemplate, - &(genName->derDirectoryName)); - break; - } - - if (rv != SECSuccess) { - goto loser; - } - genName->type = genNameType; - genName->l.next = (PRCList *) ((char *) genName) + offsetof(CERTGeneralName, l); - genName->l.prev = genName->l.next; - return genName; -loser: - return NULL; -} - -CERTGeneralName * -cert_DecodeGeneralNames (PRArenaPool *arena, - SECItem **encodedGenName) -{ - PRCList *head = NULL; - PRCList *tail = NULL; - CERTGeneralName *currentName = NULL; - - PORT_Assert(arena); - if (!encodedGenName) { - goto loser; - } - while (*encodedGenName != NULL) { - currentName = CERT_DecodeGeneralName(arena, *encodedGenName, NULL); - if (currentName == NULL) { - goto loser; - } - if (head == NULL) { - head = &(currentName->l); - tail = head; - } - currentName->l.next = head; - currentName->l.prev = tail; - tail = &(currentName->l); - (cert_get_prev_general_name(currentName))->l.next = tail; - encodedGenName++; - } - (cert_get_next_general_name(currentName))->l.prev = tail; - return cert_get_next_general_name(currentName); -loser: - return NULL; -} - -void -CERT_DestroyGeneralName(CERTGeneralName *name) -{ - cert_DestroyGeneralNames(name); -} - -SECStatus -cert_DestroyGeneralNames(CERTGeneralName *name) -{ - CERTGeneralName *first; - CERTGeneralName *next = NULL; - - - first = name; - do { - next = cert_get_next_general_name(name); - PORT_Free(name); - name = next; - } while (name != first); - return SECSuccess; -} - -SECItem * -cert_EncodeNameConstraint(CERTNameConstraint *constraint, - SECItem *dest, - PRArenaPool *arena) -{ - PORT_Assert(arena); - if (dest == NULL) { - dest = (SECItem *) PORT_ArenaZAlloc(arena, sizeof(SECItem)); - if (dest == NULL) { - return NULL; - } - } - CERT_EncodeGeneralName(&(constraint->name), &(constraint->DERName), - arena); - - dest = SEC_ASN1EncodeItem (arena, dest, constraint, - CERTNameConstraintTemplate); - return dest; -} - -SECStatus -cert_EncodeNameConstraintSubTree(CERTNameConstraint *constraints, - PRArenaPool *arena, - SECItem ***dest, - PRBool permited) -{ - CERTNameConstraint *current_constraint = constraints; - SECItem **items = NULL; - int count = 0; - int i; - PRCList *head; - - PORT_Assert(arena); - if (constraints != NULL) { - count = 1; - } - head = (PRCList *) (((char *) constraints) + offsetof(CERTNameConstraint, l)); - while (current_constraint->l.next != head) { - current_constraint = cert_get_next_name_constraint(current_constraint); - ++count; - } - current_constraint = cert_get_next_name_constraint(current_constraint); - items = (SECItem **) PORT_ArenaZAlloc(arena, sizeof(SECItem *) * (count + 1)); - - if (items == NULL) { - goto loser; - } - for (i = 0; i < count; i++) { - items[i] = cert_EncodeNameConstraint(current_constraint, - (SECItem *) NULL, arena); - if (items[i] == NULL) { - goto loser; - } - current_constraint = cert_get_next_name_constraint(current_constraint); - } - *dest = items; - if (*dest == NULL) { - goto loser; - } - return SECSuccess; -loser: - return SECFailure; -} - -SECStatus -cert_EncodeNameConstraints(CERTNameConstraints *constraints, - PRArenaPool *arena, - SECItem *dest) -{ - SECStatus rv = SECSuccess; - - PORT_Assert(arena); - if (constraints->permited != NULL) { - rv = cert_EncodeNameConstraintSubTree(constraints->permited, arena, - &constraints->DERPermited, PR_TRUE); - if (rv == SECFailure) { - goto loser; - } - } - if (constraints->excluded != NULL) { - rv = cert_EncodeNameConstraintSubTree(constraints->excluded, arena, - &constraints->DERExcluded, PR_FALSE); - if (rv == SECFailure) { - goto loser; - } - } - dest = SEC_ASN1EncodeItem(arena, dest, constraints, - CERTNameConstraintsTemplate); - if (dest == NULL) { - goto loser; - } - return SECSuccess; -loser: - return SECFailure; -} - - -CERTNameConstraint * -cert_DecodeNameConstraint(PRArenaPool *arena, - SECItem *encodedConstraint) -{ - CERTNameConstraint *constraint; - SECStatus rv = SECSuccess; - CERTGeneralName *temp; - - - - PORT_Assert(arena); - constraint = (CERTNameConstraint *) PORT_ArenaZAlloc(arena, sizeof(CERTNameConstraint)); - rv = SEC_ASN1DecodeItem(arena, constraint, CERTNameConstraintTemplate, encodedConstraint); - if (rv != SECSuccess) { - goto loser; - } - temp = CERT_DecodeGeneralName(arena, &(constraint->DERName), &(constraint->name)); - if (temp != &(constraint->name)) { - goto loser; - } - - /* ### sjlee: since the name constraint contains only one - * CERTGeneralName, the list within CERTGeneralName shouldn't - * point anywhere else. Otherwise, bad things will happen. - */ - constraint->name.l.prev = constraint->name.l.next = &(constraint->name.l); - return constraint; -loser: - return NULL; -} - - -CERTNameConstraint * -cert_DecodeNameConstraintSubTree(PRArenaPool *arena, - SECItem **subTree, - PRBool permited) -{ - CERTNameConstraint *current = NULL; - CERTNameConstraint *first = NULL; - CERTNameConstraint *last = NULL; - CERTNameConstraint *next = NULL; - int i = 0; - - while (subTree[i] != NULL) { - current = cert_DecodeNameConstraint(arena, subTree[i]); - if (current == NULL) { - goto loser; - } - if (last == NULL) { - first = last = current; - } - current->l.prev = &(last->l); - current->l.next = last->l.next; - last->l.next = &(current->l); - i++; - } - first->l.prev = &(current->l); - return first; -loser: - if (first) { - current = first; - do { - next = cert_get_next_name_constraint(current); - PORT_Free(current); - current = next; - }while (current != first); - } - return NULL; -} - -CERTNameConstraints * -cert_DecodeNameConstraints(PRArenaPool *arena, - SECItem *encodedConstraints) -{ - CERTNameConstraints *constraints; - SECStatus rv; - - PORT_Assert(arena); - PORT_Assert(encodedConstraints); - constraints = (CERTNameConstraints *) PORT_ArenaZAlloc(arena, - sizeof(CERTNameConstraints)); - if (constraints == NULL) { - goto loser; - } - rv = SEC_ASN1DecodeItem(arena, constraints, CERTNameConstraintsTemplate, - encodedConstraints); - if (rv != SECSuccess) { - goto loser; - } - if (constraints->DERPermited != NULL && constraints->DERPermited[0] != NULL) { - constraints->permited = cert_DecodeNameConstraintSubTree(arena, - constraints->DERPermited, - PR_TRUE); - if (constraints->permited == NULL) { - goto loser; - } - } - if (constraints->DERExcluded != NULL && constraints->DERExcluded[0] != NULL) { - constraints->excluded = cert_DecodeNameConstraintSubTree(arena, - constraints->DERExcluded, - PR_FALSE); - if (constraints->excluded == NULL) { - goto loser; - } - } - return constraints; -loser: - return NULL; -} - - -SECStatus -CERT_CopyGeneralName(PRArenaPool *arena, - CERTGeneralName *dest, - CERTGeneralName *src) -{ - SECStatus rv; - CERTGeneralName *destHead = dest; - CERTGeneralName *srcHead = src; - CERTGeneralName *temp; - - PORT_Assert(dest != NULL); - dest->type = src->type; - do { - switch (src->type) { - case certDirectoryName: { - rv = SECITEM_CopyItem(arena, &dest->derDirectoryName, &src->derDirectoryName); - if (rv != SECSuccess) { - return rv; - } - rv = CERT_CopyName(arena, &dest->name.directoryName, &src->name.directoryName); - break; - } - case certOtherName: { - rv = SECITEM_CopyItem(arena, &dest->name.OthName.name, &src->name.OthName.name); - if (rv != SECSuccess) { - return rv; - } - rv = SECITEM_CopyItem(arena, &dest->name.OthName.oid, &src->name.OthName.oid); - break; - } - default: { - rv = SECITEM_CopyItem(arena, &dest->name.other, &src->name.other); - } - } - src = cert_get_next_general_name(src); - /* if there is only one general name, we shouldn't do this */ - if (src != srcHead) { - if (dest->l.next == &destHead->l) { - if (arena) { - temp = (CERTGeneralName *) - PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - } else { - temp = (CERTGeneralName *) - PORT_ZAlloc(sizeof(CERTGeneralName)); - } - temp->l.next = &destHead->l; - temp->l.prev = &dest->l; - destHead->l.prev = &temp->l; - dest->l.next = &temp->l; - dest = temp; - } else { - dest = cert_get_next_general_name(dest); - } - } - } while (src != srcHead && rv == SECSuccess); - return rv; -} - - -CERTGeneralNameList * -CERT_DupGeneralNameList(CERTGeneralNameList *list) -{ - if (list != NULL) { - PZ_Lock(list->lock); - list->refCount++; - PZ_Unlock(list->lock); - } - return list; -} - -CERTNameConstraint * -CERT_CopyNameConstraint(PRArenaPool *arena, - CERTNameConstraint *dest, - CERTNameConstraint *src) -{ - SECStatus rv; - - if (dest == NULL) { - dest = (CERTNameConstraint *) PORT_ArenaZAlloc(arena, sizeof(CERTNameConstraint)); - /* mark that it is not linked */ - dest->name.l.prev = dest->name.l.next = &(dest->name.l); - } - rv = CERT_CopyGeneralName(arena, &dest->name, &src->name); - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &dest->DERName, &src->DERName); - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &dest->min, &src->min); - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &dest->max, &src->max); - if (rv != SECSuccess) { - goto loser; - } - dest->l.prev = dest->l.next = &dest->l; - return dest; -loser: - return NULL; -} - - -CERTGeneralName * -cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2) -{ - PRCList *begin1; - PRCList *begin2; - PRCList *end1; - PRCList *end2; - - if (list1 == NULL){ - return list2; - } else if (list2 == NULL) { - return list1; - } else { - begin1 = &list1->l; - begin2 = &list2->l; - end1 = list1->l.prev; - end2 = list2->l.prev; - end1->next = begin2; - end2->next = begin1; - begin1->prev = end2; - begin2->prev = end1; - return list1; - } -} - - -CERTNameConstraint * -cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2) -{ - PRCList *begin1; - PRCList *begin2; - PRCList *end1; - PRCList *end2; - - if (list1 == NULL){ - return list2; - } else if (list2 == NULL) { - return list1; - } else { - begin1 = &list1->l; - begin2 = &list2->l; - end1 = list1->l.prev; - end2 = list2->l.prev; - end1->next = begin2; - end2->next = begin1; - begin1->prev = end2; - begin2->prev = end1; - return list1; - } -} - - -CERTNameConstraint * -CERT_AddNameConstraint(CERTNameConstraint *list, - CERTNameConstraint *constraint) -{ - PORT_Assert(constraint != NULL); - constraint->l.next = constraint->l.prev = &constraint->l; - list = cert_CombineConstraintsLists(list, constraint); - return list; -} - - -SECStatus -CERT_GetNameConstriantByType (CERTNameConstraint *constraints, - CERTGeneralNameType type, - CERTNameConstraint **returnList, - PRArenaPool *arena) -{ - CERTNameConstraint *current; - CERTNameConstraint *temp; - - *returnList = NULL; - if (!constraints) - return SECSuccess; - current = constraints; - - do { - if (current->name.type == type || - (type == certDirectoryName && current->name.type == certRFC822Name)) { - temp = NULL; - temp = CERT_CopyNameConstraint(arena, temp, current); - if (temp == NULL) { - goto loser; - } - *returnList = CERT_AddNameConstraint(*returnList, temp); - } - current = cert_get_next_name_constraint(current); - } while (current != constraints); - return SECSuccess; -loser: - return SECFailure; -} - - -void * -CERT_GetGeneralNameByType (CERTGeneralName *genNames, - CERTGeneralNameType type, PRBool derFormat) -{ - CERTGeneralName *current; - - if (!genNames) - return (NULL); - current = genNames; - - do { - if (current->type == type) { - switch (type) { - case certDNSName: - case certEDIPartyName: - case certIPAddress: - case certRegisterID: - case certRFC822Name: - case certX400Address: - case certURI: { - return &(current->name.other); - } - case certOtherName: { - return &(current->name.OthName); - break; - } - case certDirectoryName: { - if (derFormat) { - return &(current->derDirectoryName); - } else{ - return &(current->name.directoryName); - } - break; - } - } - } - current = cert_get_next_general_name(current); - } while (current != genNames); - return (NULL); -} - -int -CERT_GetNamesLength(CERTGeneralName *names) -{ - int length = 0; - CERTGeneralName *first; - - first = names; - if (names != NULL) { - do { - length++; - names = cert_get_next_general_name(names); - } while (names != first); - } - return length; -} - -CERTGeneralName * -CERT_GetCertificateNames(CERTCertificate *cert, PRArenaPool *arena) -{ - CERTGeneralName *DN; - CERTGeneralName *altName; - SECItem altNameExtension; - SECStatus rv; - - - DN = (CERTGeneralName *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); - if (DN == NULL) { - goto loser; - } - rv = CERT_CopyName(arena, &DN->name.directoryName, &cert->subject); - DN->type = certDirectoryName; - DN->l.next = DN->l.prev = &DN->l; - if (rv != SECSuccess) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &DN->derDirectoryName, &cert->derSubject); - if (rv != SECSuccess) { - goto loser; - } - rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, - &altNameExtension); - if (rv != SECSuccess) { - return DN; - } - altName = CERT_DecodeAltNameExtension(arena, &altNameExtension); - PORT_Free(altNameExtension.data); - if (altName == NULL) { - goto loser; - } - DN = cert_CombineNamesLists(DN, altName); - return DN; -loser: - - return NULL; -} - -static SECStatus -compareNameToConstraint(char *name, char *constraint, PRBool substring) -{ - SECStatus rv; - - if (*constraint == '\0' && *name == '\0') { - return SECSuccess; - } - if (*constraint == '*') { - return compareNameToConstraint(name, constraint + 1, PR_TRUE); - } - if (substring) { - if (*constraint == '\0') { - return SECSuccess; - } - while (*name != *constraint) { - if (*name == '\0') { - return SECFailure; - } - name++; - } - rv = compareNameToConstraint(name + 1, constraint + 1, PR_FALSE); - if (rv == SECSuccess) { - return rv; - } - name++; - } else { - if (*name == *constraint) { - name++; - constraint++; - } else { - return SECFailure; - } - } - return compareNameToConstraint(name, constraint, substring); -} - -SECStatus -cert_CompareNameWithConstraints(CERTGeneralName *name, - CERTNameConstraint *constraints, - PRBool excluded) -{ - SECStatus rv = SECSuccess; - char *nameString = NULL; - char *constraintString = NULL; - int start; - int end; - int tag; - CERTRDN **nameRDNS, *nameRDN; - CERTRDN **constraintRDNS, *constraintRDN; - CERTAVA **nameAVAS, *nameAVA; - CERTAVA **constraintAVAS, *constraintAVA; - CERTNameConstraint *current; - SECItem *avaValue; - CERTName constraintName; - CERTName certName; - SECComparison status = SECEqual; - PRArenaPool *certNameArena; - PRArenaPool *constraintNameArena; - - certName.arena = NULL; - certName.rdns = NULL; - constraintName.arena = NULL; - constraintName.rdns = NULL; - if (constraints != NULL) { - current = constraints; - if (name->type == certDirectoryName) { - certNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(certNameArena, &certName, &name->name.directoryName); - nameRDNS = certName.rdns; - for (;;) { - nameRDN = *nameRDNS++; - nameAVAS = nameRDN->avas; - for(;;) { - nameAVA = *nameAVAS++; - tag = CERT_GetAVATag(nameAVA); - if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS || - tag == SEC_OID_RFC1274_MAIL) { - avaValue = CERT_DecodeAVAValue(&nameAVA->value); - nameString = (char*)PORT_ZAlloc(avaValue->len + 1); - nameString = PORT_Strncpy(nameString, (char *) avaValue->data, avaValue->len); - start = 0; - while(nameString[start] != '@' && nameString[start + 1] != '\0') { - start++; - } - start++; - do{ - if (current->name.type == certRFC822Name) { - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, - PR_FALSE); - - if (constraintString != NULL) { - PORT_Free(constraintString); - constraintString = NULL; - } - if (nameString != NULL) { - PORT_Free(nameString); - nameString = NULL; - } - if (rv == SECSuccess && excluded == PR_TRUE) { - goto found; - } - if (rv == SECSuccess && excluded == PR_FALSE) { - break; - } - } - current = cert_get_next_name_constraint(current); - } while (current != constraints); - } - if (rv != SECSuccess && excluded == PR_FALSE) { - goto loser; - } - if (*nameAVAS == NULL) { - break; - } - } - if (*nameRDNS == NULL) { - break; - } - } - } - current = constraints; - do { - switch (name->type) { - case certDNSName: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certRFC822Name: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - start = 0; - while(nameString[start] != '@' && nameString[start + 1] != '\0') { - start++; - } - start++; - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certURI: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - start = 0; - while(PORT_Strncmp(nameString + start, "://", 3) != 0 && - nameString[start + 3] != '\0') { - start++; - } - start +=3; - end = 0; - while(nameString[start + end] != '/' && - nameString[start + end] != '\0') { - end++; - } - nameString[start + end] = '\0'; - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certDirectoryName: - if (current->name.type == certDirectoryName) { - constraintNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(constraintNameArena, &constraintName, ¤t->name.name.directoryName); - constraintRDNS = constraintName.rdns; - for (;;) { - constraintRDN = *constraintRDNS++; - constraintAVAS = constraintRDN->avas; - for(;;) { - constraintAVA = *constraintAVAS++; - certNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(certNameArena, &certName, &name->name.directoryName); - nameRDNS = certName.rdns; - for (;;) { - nameRDN = *nameRDNS++; - nameAVAS = nameRDN->avas++; - for(;;) { - nameAVA = *nameAVAS++; - status = CERT_CompareAVA(constraintAVA, nameAVA); - if (status == SECEqual || *nameAVAS == NULL) { - break; - } - } - if (status == SECEqual || *nameRDNS == NULL) { - break; - } - } - if (status != SECEqual || *constraintAVAS == NULL) { - break; - } - } - if (status != SECEqual || *constraintRDNS == NULL) { - break; - } - } - if (status == SECEqual) { - if (excluded == PR_FALSE) { - goto found; - } else { - goto loser; - } - } - break; - } else if (current->name.type == certRFC822Name) { - current = cert_get_next_name_constraint(current); - continue; - } - default: - /* other types are not supported */ - if (excluded) { - goto found; - } else { - goto loser; - } - } - if (rv == SECSuccess && status == SECEqual) { - goto found; - } - current = cert_get_next_name_constraint(current); - } while (current !=constraints); - } else { - goto found; - } -loser: - if (certName.arena) { - CERT_DestroyName(&certName); - } - if (constraintName.arena) { - CERT_DestroyName(&constraintName); - } - return SECFailure; -found: - if (certName.arena) { - CERT_DestroyName(&certName); - } - if (constraintName.arena) { - CERT_DestroyName(&constraintName); - } - return SECSuccess; -} - - -CERTCertificate * -CERT_CompareNameSpace(CERTCertificate *cert, - CERTGeneralName *namesList, - SECItem *namesListIndex, - PRArenaPool *arena, - CERTCertDBHandle *handle) -{ - SECStatus rv; - SECItem constraintsExtension; - CERTNameConstraints *constraints; - CERTGeneralName *currentName; - int count = 0; - CERTNameConstraint *matchingConstraints; - CERTCertificate *badCert = NULL; - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, &constraintsExtension); - if (rv != SECSuccess) { - return NULL; - } - constraints = cert_DecodeNameConstraints(arena, &constraintsExtension); - currentName = namesList; - if (constraints == NULL) { - goto loser; - } - do { - if (constraints->excluded != NULL) { - rv = CERT_GetNameConstriantByType(constraints->excluded, currentName->type, - &matchingConstraints, arena); - if (rv != SECSuccess) { - goto loser; - } - if (matchingConstraints != NULL) { - rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, - PR_TRUE); - if (rv != SECFailure) { - goto loser; - } - } - } - if (constraints->permited != NULL) { - rv = CERT_GetNameConstriantByType(constraints->permited, currentName->type, - &matchingConstraints, arena); - if (rv != SECSuccess) { - goto loser; - } - if (matchingConstraints != NULL) { - rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, - PR_FALSE); - if (rv != SECSuccess) { - goto loser; - } - } else { - goto loser; - } - } - currentName = cert_get_next_general_name(currentName); - count ++; - } while (currentName != namesList); - return NULL; -loser: - badCert = CERT_FindCertByName (handle, &namesListIndex[count]); - return badCert; -} - - - -/* 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; -} - - -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; -} - -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 = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); - if (item != NULL) { - 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 = (OtherName *)PORT_ArenaAlloc(arena, - sizeof(OtherName)); - } else { - tmpOther = (OtherName *) PORT_Alloc(sizeof(OtherName)); - } - if (tmpOther != NULL) { - SECITEM_CopyItem(arena, &tmpOther->oid, &other->oid); - SECITEM_CopyItem(arena, &tmpOther->name, &other->name); - } - PZ_Unlock(list->lock); - return tmpOther; - case certDirectoryName: - if (arena == NULL) { - PZ_Unlock(list->lock); - return NULL; - } else { - name = (CERTName *) PORT_ArenaZAlloc(list->arena, - sizeof(CERTName)); - if (name != NULL) { - CERT_CopyName(arena, name, (CERTName *) data); - } - PZ_Unlock(list->lock); - return name; - } - } - } - PZ_Unlock(list->lock); - return NULL; -} - -void -CERT_AddGeneralNameToList(CERTGeneralNameList *list, - CERTGeneralNameType type, - void *data, SECItem *oid) -{ - CERTGeneralName *name; - - if (list != NULL && data != NULL) { - PZ_Lock(list->lock); - name = (CERTGeneralName *) - PORT_ArenaZAlloc(list->arena, sizeof(CERTGeneralName)); - name->type = type; - switch (type) { - case certDNSName: - case certEDIPartyName: - case certIPAddress: - case certRegisterID: - case certRFC822Name: - case certX400Address: - case certURI: - SECITEM_CopyItem(list->arena, &name->name.other, (SECItem *)data); - break; - case certOtherName: - SECITEM_CopyItem(list->arena, &name->name.OthName.name, - (SECItem *) data); - SECITEM_CopyItem(list->arena, &name->name.OthName.oid, - oid); - break; - case certDirectoryName: - CERT_CopyName(list->arena, &name->name.directoryName, - (CERTName *) data); - break; - } - name->l.prev = name->l.next = &name->l; - list->name = cert_CombineNamesLists(list->name, name); - list->len++; - PZ_Unlock(list->lock); - } - return; -} diff --git a/security/nss/lib/certdb/genname.h b/security/nss/lib/certdb/genname.h deleted file mode 100644 index 8e3a58619..000000000 --- a/security/nss/lib/certdb/genname.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#ifndef _GENAME_H_ -#define _GENAME_H_ - -#include "plarena.h" -#include "seccomon.h" -#include "secoidt.h" -#include "secasn1.h" -#include "secder.h" -#include "certt.h" - -/************************************************************************/ -SEC_BEGIN_PROTOS - -extern const SEC_ASN1Template CERT_GeneralNamesTemplate[]; - -extern CERTGeneralName * -cert_get_next_general_name(CERTGeneralName *current); - -extern CERTGeneralName * -cert_get_prev_general_name(CERTGeneralName *current); - -extern SECItem * -CERT_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, - PRArenaPool *arena); - -extern SECItem ** -cert_EncodeGeneralNames(PRArenaPool *arena, CERTGeneralName *names); - -extern CERTGeneralName * -CERT_DecodeGeneralName(PRArenaPool *arena, SECItem *encodedName, - CERTGeneralName *genName); - -extern CERTGeneralName * -cert_DecodeGeneralNames(PRArenaPool *arena, SECItem **encodedGenName); - -extern SECStatus -cert_DestroyGeneralNames(CERTGeneralName *name); - -extern SECStatus -cert_EncodeNameConstraints(CERTNameConstraints *constraints, PRArenaPool *arena, - SECItem *dest); - -extern CERTNameConstraints * -cert_DecodeNameConstraints(PRArenaPool *arena, SECItem *encodedConstraints); - -extern CERTGeneralName * -cert_CombineNamesLists(CERTGeneralName *list1, CERTGeneralName *list2); - -extern CERTNameConstraint * -cert_CombineConstraintsLists(CERTNameConstraint *list1, CERTNameConstraint *list2); - -SECStatus -CERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b); - -SECStatus -CERT_CopyGeneralName(PRArenaPool *arena, - CERTGeneralName *dest, - CERTGeneralName *src); - -/* General Name Lists are a thread safe, reference counting layer to - * general names */ - -void -CERT_DestroyGeneralNameList(CERTGeneralNameList *list); - -CERTGeneralNameList * -CERT_CreateGeneralNameList(CERTGeneralName *name); - -SECStatus -CERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b); - -void * -CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list, - CERTGeneralNameType type, - PRArenaPool *arena); - -void -CERT_AddGeneralNameToList(CERTGeneralNameList *list, - CERTGeneralNameType type, - void *data, SECItem *oid); - - -CERTGeneralNameList * -CERT_DupGeneralNameList(CERTGeneralNameList *list); - - -int -CERT_GetNamesLength(CERTGeneralName *names); -/************************************************************************/ -SEC_END_PROTOS - -#endif diff --git a/security/nss/lib/certdb/manifest.mn b/security/nss/lib/certdb/manifest.mn deleted file mode 100644 index 8a3cc395a..000000000 --- a/security/nss/lib/certdb/manifest.mn +++ /dev/null @@ -1,71 +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 \ - $(NULL) - -NO_EXPORTS = \ - certdb.h \ - $(NULL) - -NO_PRIVATE_EXPORTS = \ - genname.h \ - xconst.h \ - certxutl.h \ - $(NULL) - -MODULE = softoken - -CSRCS = $(NULL) - -NO_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 \ - -REQUIRES = security 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 3fe018a44..000000000 --- a/security/nss/lib/certdb/polcyxtn.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * Support for various policy related extensions - * - * $Id$ - */ - -#include "seccomon.h" -#include "secport.h" -#include "secder.h" -#include "cert.h" -#include "secoid.h" -#include "secasn1.h" -#include "secerr.h" -#include "nspr.h" - -const SEC_ASN1Template CERT_NoticeReferenceTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTNoticeReference) }, -/* NOTE: this should be a choice */ - { SEC_ASN1_IA5_STRING, - offsetof(CERTNoticeReference, organization) }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTNoticeReference, noticeNumbers), - SEC_IntegerTemplate }, - { 0 } -}; - -/* this template can not be encoded because of the option inline */ -const SEC_ASN1Template CERT_UserNoticeTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTUserNotice) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED, - offsetof(CERTUserNotice, derNoticeReference) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, - offsetof(CERTUserNotice, displayText) }, - { 0 } -}; - -const SEC_ASN1Template CERT_PolicyQualifierTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTPolicyQualifier) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTPolicyQualifier, qualifierID) }, - { SEC_ASN1_ANY, - offsetof(CERTPolicyQualifier, qualifierValue) }, - { 0 } -}; - -const SEC_ASN1Template CERT_PolicyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTPolicyInfo) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTPolicyInfo, policyID) }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTPolicyInfo, policyQualifiers), - CERT_PolicyQualifierTemplate }, - { 0 } -}; - -const SEC_ASN1Template CERT_CertificatePoliciesTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTCertificatePolicies, policyInfos), - CERT_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) } -}; - -static void -breakLines(char *string) -{ - char *tmpstr; - char *lastspace = NULL; - int curlen = 0; - int c; - - tmpstr = string; - - while ( ( c = *tmpstr ) != '\0' ) { - switch ( c ) { - case ' ': - lastspace = tmpstr; - break; - case '\n': - lastspace = NULL; - curlen = 0; - break; - } - - if ( ( curlen >= 55 ) && ( lastspace != NULL ) ) { - *lastspace = '\n'; - curlen = ( tmpstr - lastspace ); - lastspace = NULL; - } - - curlen++; - tmpstr++; - } - - return; -} - -CERTCertificatePolicies * -CERT_DecodeCertificatePoliciesExtension(SECItem *extnValue) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - CERTCertificatePolicies *policies; - CERTPolicyInfo **policyInfos, *policyInfo; - CERTPolicyQualifier **policyQualifiers, *policyQualifier; - - /* make a new arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - goto loser; - } - - /* allocate the certifiate policies structure */ - policies = (CERTCertificatePolicies *) - PORT_ArenaZAlloc(arena, sizeof(CERTCertificatePolicies)); - - if ( policies == NULL ) { - goto loser; - } - - policies->arena = arena; - - /* decode the policy info */ - rv = SEC_QuickDERDecodeItem(arena, policies, CERT_CertificatePoliciesTemplate, - extnValue); - - if ( rv != SECSuccess ) { - goto loser; - } - - /* initialize the oid tags */ - policyInfos = policies->policyInfos; - while (*policyInfos != NULL ) { - policyInfo = *policyInfos; - policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID); - policyQualifiers = policyInfo->policyQualifiers; - while ( *policyQualifiers != NULL ) { - policyQualifier = *policyQualifiers; - policyQualifier->oid = - SECOID_FindOIDTag(&policyQualifier->qualifierID); - policyQualifiers++; - } - policyInfos++; - } - - return(policies); - -loser: - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -void -CERT_DestroyCertificatePoliciesExtension(CERTCertificatePolicies *policies) -{ - if ( policies != NULL ) { - PORT_FreeArena(policies->arena, PR_FALSE); - } - return; -} - - -CERTUserNotice * -CERT_DecodeUserNotice(SECItem *noticeItem) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - CERTUserNotice *userNotice; - - /* make a new arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - goto loser; - } - - /* allocate the userNotice structure */ - userNotice = (CERTUserNotice *)PORT_ArenaZAlloc(arena, - sizeof(CERTUserNotice)); - - if ( userNotice == NULL ) { - goto loser; - } - - userNotice->arena = arena; - - /* decode the user notice */ - rv = SEC_QuickDERDecodeItem(arena, userNotice, CERT_UserNoticeTemplate, - noticeItem); - - if ( rv != SECSuccess ) { - goto loser; - } - - if (userNotice->derNoticeReference.data != NULL) { - /* sigh, the asn1 parser stripped the sequence encoding, re add it - * before we decode. - */ - SECItem tmpbuf; - int newBytes; - - newBytes = SEC_ASN1LengthLength(userNotice->derNoticeReference.len)+1; - tmpbuf.len = newBytes + userNotice->derNoticeReference.len; - tmpbuf.data = PORT_ZAlloc(tmpbuf.len); - if (tmpbuf.data == NULL) { - goto loser; - } - tmpbuf.data[0] = SEC_ASN1_SEQUENCE | SEC_ASN1_CONSTRUCTED; - SEC_ASN1EncodeLength(&tmpbuf.data[1],userNotice->derNoticeReference.len); - PORT_Memcpy(&tmpbuf.data[newBytes],userNotice->derNoticeReference.data, - userNotice->derNoticeReference.len); - - /* OK, no decode it */ - rv = SEC_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; - - /* make a new arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - goto loser; - } - - /* allocate the userNotice structure */ - oidSeq = (CERTOidSequence *)PORT_ArenaZAlloc(arena, - sizeof(CERTOidSequence)); - - if ( oidSeq == NULL ) { - goto loser; - } - - oidSeq->arena = arena; - - /* decode the user notice */ - rv = SEC_QuickDERDecodeItem(arena, oidSeq, CERT_OidSeqTemplate, seqItem); - - if ( rv != SECSuccess ) { - goto loser; - } - - return(oidSeq); - -loser: - return(NULL); -} - - -void -CERT_DestroyOidSequence(CERTOidSequence *oidSeq) -{ - if ( oidSeq != NULL ) { - PORT_FreeArena(oidSeq->arena, PR_FALSE); - } - return; -} - -PRBool -CERT_GovtApprovedBitSet(CERTCertificate *cert) -{ - SECStatus rv; - SECItem extItem; - CERTOidSequence *oidSeq = NULL; - PRBool ret; - SECItem **oids; - SECItem *oid; - SECOidTag oidTag; - - extItem.data = NULL; - rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, &extItem); - if ( rv != SECSuccess ) { - goto loser; - } - - oidSeq = CERT_DecodeOidSequence(&extItem); - if ( oidSeq == NULL ) { - goto loser; - } - - oids = oidSeq->oids; - while ( oids != NULL && *oids != NULL ) { - oid = *oids; - - oidTag = SECOID_FindOIDTag(oid); - - if ( oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED ) { - goto success; - } - - oids++; - } - -loser: - ret = PR_FALSE; - goto done; -success: - ret = PR_TRUE; -done: - if ( oidSeq != NULL ) { - CERT_DestroyOidSequence(oidSeq); - } - if (extItem.data != NULL) { - PORT_Free(extItem.data); - } - return(ret); -} diff --git a/security/nss/lib/certdb/secname.c b/security/nss/lib/certdb/secname.c deleted file mode 100644 index 002c481c4..000000000 --- a/security/nss/lib/certdb/secname.c +++ /dev/null @@ -1,646 +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" - -static const SEC_ASN1Template cert_AVATemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTAVA) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTAVA,type), }, - { SEC_ASN1_ANY, - offsetof(CERTAVA,value), }, - { 0, } -}; - -const SEC_ASN1Template CERT_RDNTemplate[] = { - { SEC_ASN1_SET_OF, - offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) } -}; - - -static int -CountArray(void **array) -{ - int count = 0; - if (array) { - while (*array++) { - count++; - } - } - return count; -} - -static void -**AddToArray(PRArenaPool *arena, void **array, void *element) -{ - unsigned count; - void **ap; - - /* Count up number of slots already in use in the array */ - count = 0; - ap = array; - if (ap) { - while (*ap++) { - count++; - } - } - - if (array) { - array = (void**) PORT_ArenaGrow(arena, array, - (count + 1) * sizeof(void *), - (count + 2) * sizeof(void *)); - } else { - array = (void**) PORT_ArenaAlloc(arena, (count + 2) * sizeof(void *)); - } - if (array) { - array[count] = element; - array[count+1] = 0; - } - return array; -} - -#if 0 -static void -**RemoveFromArray(void **array, void *element) -{ - unsigned count; - void **ap; - int slot; - - /* Look for element */ - ap = array; - if (ap) { - count = 1; /* count the null at the end */ - slot = -1; - for (; *ap; ap++, count++) { - if (*ap == element) { - /* Found it */ - slot = ap - array; - } - } - if (slot >= 0) { - /* Found it. Squish array down */ - PORT_Memmove((void*) (array + slot), (void*) (array + slot + 1), - (count - slot - 1) * sizeof(void*)); - /* Don't bother reallocing the memory */ - } - } - return array; -} -#endif /* 0 */ - -SECOidTag -CERT_GetAVATag(CERTAVA *ava) -{ - SECOidData *oid; - if (!ava->type.data) return (SECOidTag)-1; - - oid = SECOID_FindOID(&ava->type); - - if ( oid ) { - return(oid->offset); - } - return (SECOidTag)-1; -} - -static SECStatus -SetupAVAType(PRArenaPool *arena, SECOidTag type, SECItem *it, unsigned *maxLenp) -{ - unsigned char *oid; - unsigned oidLen; - unsigned char *cp; - unsigned maxLen; - SECOidData *oidrec; - - oidrec = SECOID_FindOIDByTag(type); - if (oidrec == NULL) - return SECFailure; - - oid = oidrec->oid.data; - oidLen = oidrec->oid.len; - - switch (type) { - case SEC_OID_AVA_COUNTRY_NAME: - maxLen = 2; - break; - case SEC_OID_AVA_ORGANIZATION_NAME: - maxLen = 64; - break; - case SEC_OID_AVA_COMMON_NAME: - maxLen = 64; - break; - case SEC_OID_AVA_LOCALITY: - maxLen = 128; - break; - case SEC_OID_AVA_STATE_OR_PROVINCE: - maxLen = 128; - break; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - maxLen = 64; - break; - case SEC_OID_AVA_DC: - maxLen = 128; - break; - case SEC_OID_AVA_DN_QUALIFIER: - maxLen = 0x7fff; - break; - case SEC_OID_PKCS9_EMAIL_ADDRESS: - maxLen = 128; - break; - case SEC_OID_RFC1274_UID: - maxLen = 256; /* RFC 1274 specifies 256 */ - break; - case SEC_OID_RFC1274_MAIL: - maxLen = 256; /* RFC 1274 specifies 256 */ - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, oidLen); - if (cp == NULL) { - return SECFailure; - } - it->len = oidLen; - PORT_Memcpy(cp, oid, oidLen); - *maxLenp = maxLen; - return SECSuccess; -} - -static SECStatus -SetupAVAValue(PRArenaPool *arena, int valueType, char *value, SECItem *it, - unsigned maxLen) -{ - unsigned valueLen, valueLenLen, total; - unsigned ucs4Len = 0, ucs4MaxLen; - unsigned char *cp, *ucs4Val; - - switch (valueType) { - case SEC_ASN1_PRINTABLE_STRING: - case SEC_ASN1_IA5_STRING: - case SEC_ASN1_T61_STRING: - valueLen = PORT_Strlen(value); - break; - case SEC_ASN1_UNIVERSAL_STRING: - valueLen = PORT_Strlen(value); - ucs4Val = (unsigned char *)PORT_ArenaZAlloc(arena, - PORT_Strlen(value) * 6); - ucs4MaxLen = PORT_Strlen(value) * 6; - if(!ucs4Val || !PORT_UCS4_UTF8Conversion(PR_TRUE, (unsigned char *)value, valueLen, - ucs4Val, ucs4MaxLen, &ucs4Len)) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - value = (char *)ucs4Val; - valueLen = ucs4Len; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (((valueType != SEC_ASN1_UNIVERSAL_STRING) && (valueLen > maxLen)) || - ((valueType == SEC_ASN1_UNIVERSAL_STRING) && (valueLen > (maxLen * 4)))) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - valueLenLen = DER_LengthLength(valueLen); - total = 1 + valueLenLen + valueLen; - it->data = cp = (unsigned char*) PORT_ArenaAlloc(arena, total); - if (!cp) { - return SECFailure; - } - it->len = total; - cp = (unsigned char*) DER_StoreHeader(cp, valueType, valueLen); - PORT_Memcpy(cp, value, valueLen); - return SECSuccess; -} - -CERTAVA * -CERT_CreateAVA(PRArenaPool *arena, SECOidTag kind, int valueType, char *value) -{ - CERTAVA *ava; - int rv; - unsigned maxLen; - - ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); - if (ava) { - rv = SetupAVAType(arena, kind, &ava->type, &maxLen); - if (rv) { - /* Illegal AVA type */ - return 0; - } - rv = SetupAVAValue(arena, valueType, value, &ava->value, maxLen); - if (rv) { - /* Illegal value type */ - return 0; - } - } - return ava; -} - -CERTAVA * -CERT_CopyAVA(PRArenaPool *arena, CERTAVA *from) -{ - CERTAVA *ava; - int rv; - - ava = (CERTAVA*) PORT_ArenaZAlloc(arena, sizeof(CERTAVA)); - if (ava) { - rv = SECITEM_CopyItem(arena, &ava->type, &from->type); - if (rv) goto loser; - rv = SECITEM_CopyItem(arena, &ava->value, &from->value); - if (rv) goto loser; - } - return ava; - - loser: - return 0; -} - -/************************************************************************/ -/* XXX This template needs to go away in favor of the new SEC_ASN1 version. */ -static const SEC_ASN1Template cert_RDNTemplate[] = { - { SEC_ASN1_SET_OF, - offsetof(CERTRDN,avas), cert_AVATemplate, sizeof(CERTRDN) } -}; - - -CERTRDN * -CERT_CreateRDN(PRArenaPool *arena, CERTAVA *ava0, ...) -{ - CERTAVA *ava; - CERTRDN *rdn; - va_list ap; - unsigned count; - CERTAVA **avap; - - rdn = (CERTRDN*) PORT_ArenaAlloc(arena, sizeof(CERTRDN)); - if (rdn) { - /* Count number of avas going into the rdn */ - count = 1; - va_start(ap, ava0); - while ((ava = va_arg(ap, CERTAVA*)) != 0) { - count++; - } - va_end(ap); - - /* Now fill in the pointers */ - rdn->avas = avap = - (CERTAVA**) PORT_ArenaAlloc( arena, (count + 1)*sizeof(CERTAVA*)); - if (!avap) { - return 0; - } - *avap++ = ava0; - va_start(ap, ava0); - while ((ava = va_arg(ap, CERTAVA*)) != 0) { - *avap++ = ava; - } - va_end(ap); - *avap++ = 0; - } - return rdn; -} - -SECStatus -CERT_AddAVA(PRArenaPool *arena, CERTRDN *rdn, CERTAVA *ava) -{ - rdn->avas = (CERTAVA**) AddToArray(arena, (void**) rdn->avas, ava); - return rdn->avas ? SECSuccess : SECFailure; -} - -SECStatus -CERT_CopyRDN(PRArenaPool *arena, CERTRDN *to, CERTRDN *from) -{ - CERTAVA **avas, *fava, *tava; - SECStatus rv; - - /* Copy each ava from from */ - avas = from->avas; - while ((fava = *avas++) != 0) { - tava = CERT_CopyAVA(arena, fava); - if (!tava) return SECFailure; - rv = CERT_AddAVA(arena, to, tava); - if (rv) return rv; - } - return SECSuccess; -} - -/************************************************************************/ - -const SEC_ASN1Template CERT_NameTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, - offsetof(CERTName,rdns), CERT_RDNTemplate, sizeof(CERTName) } -}; - -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; - - CERT_DestroyName(to); - to->arena = arena; - - /* Copy each rdn from from */ - rdns = from->rdns; - while ((frdn = *rdns++) != 0) { - trdn = CERT_CreateRDN(arena, 0); - if ( trdn == NULL ) { - return(SECFailure); - } - rv = CERT_CopyRDN(arena, trdn, frdn); - if (rv) return rv; - rv = CERT_AddRDN(to, trdn); - if (rv) return rv; - } - return SECSuccess; -} - -/************************************************************************/ - -SECComparison -CERT_CompareAVA(CERTAVA *a, CERTAVA *b) -{ - SECComparison rv; - - rv = SECITEM_CompareItem(&a->type, &b->type); - if (rv) { - /* - ** XXX for now we are going to just assume that a bitwise - ** comparison of the value codes will do the trick. - */ - } - rv = SECITEM_CompareItem(&a->value, &b->value); - return rv; -} - -SECComparison -CERT_CompareRDN(CERTRDN *a, CERTRDN *b) -{ - CERTAVA **aavas, *aava; - CERTAVA **bavas, *bava; - int ac, bc; - SECComparison rv = SECEqual; - - aavas = a->avas; - bavas = b->avas; - - /* - ** Make sure array of ava's are the same length. If not, then we are - ** not equal - */ - ac = CountArray((void**) aavas); - bc = CountArray((void**) bavas); - if (ac < bc) return SECLessThan; - if (ac > bc) return SECGreaterThan; - - for (;;) { - aava = *aavas++; - bava = *bavas++; - if (!aava) { - break; - } - rv = CERT_CompareAVA(aava, bava); - if (rv) return rv; - } - return rv; -} - -SECComparison -CERT_CompareName(CERTName *a, CERTName *b) -{ - CERTRDN **ardns, *ardn; - CERTRDN **brdns, *brdn; - int ac, bc; - SECComparison rv = SECEqual; - - ardns = a->rdns; - brdns = b->rdns; - - /* - ** Make sure array of rdn's are the same length. If not, then we are - ** not equal - */ - ac = CountArray((void**) ardns); - bc = CountArray((void**) brdns); - if (ac < bc) return SECLessThan; - if (ac > bc) return SECGreaterThan; - - for (;;) { - ardn = *ardns++; - brdn = *brdns++; - if (!ardn) { - break; - } - rv = CERT_CompareRDN(ardn, brdn); - if (rv) return rv; - } - return rv; -} - -/* Moved from certhtml.c */ -SECItem * -CERT_DecodeAVAValue(SECItem *derAVAValue) -{ - SECItem *retItem; - const SEC_ASN1Template *theTemplate = NULL; - PRBool convertUCS4toUTF8 = PR_FALSE; - PRBool convertUCS2toUTF8 = PR_FALSE; - SECItem avaValue = {siBuffer, 0}; - PRArenaPool* newarena = NULL; - - if(!derAVAValue) { - return NULL; - } - - switch(derAVAValue->data[0]) { - case SEC_ASN1_UNIVERSAL_STRING: - convertUCS4toUTF8 = PR_TRUE; - theTemplate = SEC_UniversalStringTemplate; - break; - case SEC_ASN1_IA5_STRING: - theTemplate = SEC_IA5StringTemplate; - break; - case SEC_ASN1_PRINTABLE_STRING: - theTemplate = SEC_PrintableStringTemplate; - break; - case SEC_ASN1_T61_STRING: - theTemplate = SEC_T61StringTemplate; - break; - case SEC_ASN1_BMP_STRING: - convertUCS2toUTF8 = PR_TRUE; - theTemplate = SEC_BMPStringTemplate; - break; - 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) { - return NULL; - } - - if (convertUCS4toUTF8) { - unsigned int utf8ValLen = avaValue.len * 3; - unsigned char *utf8Val = (unsigned char*)PORT_ZAlloc(utf8ValLen); - - if(!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, - utf8Val, utf8ValLen, &utf8ValLen)) { - PORT_Free(utf8Val); - PORT_FreeArena(newarena, PR_FALSE); - return NULL; - } - - PORT_FreeArena(newarena, PR_FALSE); - avaValue.data = utf8Val; - avaValue.len = utf8ValLen; - - } else if (convertUCS2toUTF8) { - - unsigned int utf8ValLen = avaValue.len * 3; - unsigned char *utf8Val = (unsigned char*)PORT_ZAlloc(utf8ValLen); - - if(!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data, avaValue.len, - utf8Val, utf8ValLen, &utf8ValLen)) { - PORT_Free(utf8Val); - PORT_FreeArena(newarena, PR_FALSE); - return NULL; - } - - PORT_FreeArena(newarena, PR_FALSE); - 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 6226ed923..000000000 --- a/security/nss/lib/certdb/stanpcertdb.c +++ /dev/null @@ -1,977 +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); - nssrv = NSSCertificate_DeleteStoredObject(c, NULL); - nssTrustDomain_RemoveCertFromCache(td, c); - 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; -} - -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) { - 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_Remove(context->certStore, c); - 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) { - 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 PR_SUCCESS; - } - 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); - } - 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) { - return NULL; - } - 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) { - 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; - usage.anyUsage = PR_TRUE; - cc = STAN_GetDefaultCryptoContext(); - ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, - NULL, &usage, NULL); - if (!ct) { - ct = NSSCryptoContext_FindBestCertificateByEmail(cc, name, - NULL, &usage, NULL); - } - 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) -{ - int refCount; - CERTCertDBHandle *handle; - if ( cert ) { - NSSCertificate *tmp = STAN_GetNSSCertificate(cert); - handle = cert->dbhandle; -#ifdef NSS_CLASSIC - CERT_LockCertRefCount(cert); - PORT_Assert(cert->referenceCount > 0); - refCount = --cert->referenceCount; - CERT_UnlockCertRefCount(cert); - if ( ( refCount == 0 ) && !cert->keepSession ) { - PRArenaPool *arena = cert->arena; - /* zero cert before freeing. Any stale references to this cert - * after this point will probably cause an exception. */ - PORT_Memset(cert, 0, sizeof *cert); - cert = NULL; - /* free the arena that contains the cert. */ - PORT_FreeArena(arena, PR_FALSE); - } -#else - if (tmp) { - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - refCount = (int)tmp->object.refCount; - /* This is a hack. For 3.4, there are persistent references - * to 4.0 certificates during the lifetime of a cert. In the - * case of a temp cert, the persistent reference is in the - * cert store of the global crypto context. For a perm cert, - * the persistent reference is in the cache. Thus, the last - * external reference is really the penultimate NSS reference. - * When the count drops to two, it is really one, but the - * persistent reference must be explicitly deleted. In 4.0, - * this ugliness will not appear. Crypto contexts will remove - * their own cert references, and the cache will have its - * own management code also. - */ - if (refCount == 2) { - NSSCryptoContext *cc = tmp->object.cryptoContext; - if (cc != NULL) { - nssCertificateStore_Remove(cc->certStore, tmp); - } else { - nssTrustDomain_RemoveCertFromCache(td, tmp); - } - } - /* delete the NSSCertificate */ - NSSCertificate_Destroy(tmp); - } else { - PORT_FreeArena(cert->arena, PR_FALSE); - } -#endif - } - 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; -} - -/* - * - * Manage S/MIME profiles - * - */ - -SECStatus -CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, - SECItem *profileTime) -{ - int64 oldtime; - int64 newtime; - SECStatus rv = SECFailure; - PRBool saveit; - char *emailAddr; - SECItem oldprof, oldproftime; - SECItem *oldProfile = NULL; - SECItem *oldProfileTime = NULL; - PK11SlotInfo *slot = NULL; - NSSCertificate *c; - NSSCryptoContext *cc; - nssSMIMEProfile *stanProfile = NULL; - PRBool freeOldProfile = PR_FALSE; - - 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; - } - } - - emailAddr = cert->emailAddr; - - if ( emailAddr == NULL ) { - goto loser; - } - - 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, 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, 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); -} - -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 6e84f579d..000000000 --- a/security/nss/lib/certdb/xauthkid.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * X.509 v3 Subject Key Usage Extension - * - */ - -#include "prtypes.h" -#include "mcom_db.h" -#include "seccomon.h" -#include "secdert.h" -#include "secoidt.h" -#include "secasn1t.h" -#include "secasn1.h" -#include "secport.h" -#include "certt.h" -#include "genname.h" -#include "secerr.h" - - -const SEC_ASN1Template CERTAuthKeyIDTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTAuthKeyID,keyID), SEC_OctetStringTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(CERTAuthKeyID,authCertSerialNumber), SEC_IntegerTemplate}, - { 0 } -}; - - - -SECStatus CERT_EncodeAuthKeyID (PRArenaPool *arena, CERTAuthKeyID *value, SECItem *encodedValue) -{ - SECStatus rv = SECFailure; - - PORT_Assert (value); - PORT_Assert (arena); - PORT_Assert (value->DERAuthCertIssuer == NULL); - PORT_Assert (encodedValue); - - do { - - /* If both of the authCertIssuer and the serial number exist, encode - the name first. Otherwise, it is an error if one exist and the other - is not. - */ - if (value->authCertIssuer) { - if (!value->authCertSerialNumber.data) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - - value->DERAuthCertIssuer = cert_EncodeGeneralNames - (arena, value->authCertIssuer); - if (!value->DERAuthCertIssuer) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - } - else if (value->authCertSerialNumber.data) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - - if (SEC_ASN1EncodeItem (arena, encodedValue, value, - CERTAuthKeyIDTemplate) == NULL) - break; - rv = SECSuccess; - - } while (0); - return(rv); -} - -CERTAuthKeyID * -CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue) -{ - CERTAuthKeyID * value = NULL; - SECStatus rv = SECFailure; - void * mark; - - PORT_Assert (arena); - - do { - mark = PORT_ArenaMark (arena); - value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); - value->DERAuthCertIssuer = NULL; - if (value == NULL) - break; - rv = SEC_QuickDERDecodeItem - (arena, value, CERTAuthKeyIDTemplate, encodedValue); - if (rv != SECSuccess) - break; - - value->authCertIssuer = cert_DecodeGeneralNames (arena, value->DERAuthCertIssuer); - if (value->authCertIssuer == NULL) - break; - - /* what if the general name contains other format but not URI ? - hl - */ - if ((value->authCertSerialNumber.data && !value->authCertIssuer) || - (!value->authCertSerialNumber.data && value->authCertIssuer)){ - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - } while (0); - - if (rv != SECSuccess) { - PORT_ArenaRelease (arena, mark); - return ((CERTAuthKeyID *)NULL); - } - PORT_ArenaUnmark(arena, mark); - return (value); -} diff --git a/security/nss/lib/certdb/xbsconst.c b/security/nss/lib/certdb/xbsconst.c deleted file mode 100644 index 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 74a4de08b..000000000 --- a/security/nss/lib/certdb/xconst.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -/* - * X.509 Extension Encoding - */ - -#include "prtypes.h" -#include "mcom_db.h" -#include "seccomon.h" -#include "secdert.h" -#include "secoidt.h" -#include "secasn1t.h" -#include "secasn1.h" -#include "certt.h" -#include "secder.h" -#include "prprf.h" -#include "xconst.h" -#include "genname.h" -#include "secasn1.h" - - - -static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = { -{ SEC_ASN1_OCTET_STRING } -}; - - -static const SEC_ASN1Template CERTIA5TypeTemplate[] = { -{ SEC_ASN1_IA5_STRING } -}; - - -static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(PKUPEncodedContext) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(PKUPEncodedContext, notBefore), SEC_GeneralizedTimeTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(PKUPEncodedContext, notAfter), SEC_GeneralizedTimeTemplate}, - { 0, } -}; - - -const SEC_ASN1Template CERTAltNameTemplate[] = { - { SEC_ASN1_CONSTRUCTED, offsetof(AltNameEncodedContext, encodedGenName), - CERT_GeneralNamesTemplate} -}; - -const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTAuthInfoAccess) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTAuthInfoAccess, method) }, - { SEC_ASN1_ANY, - offsetof(CERTAuthInfoAccess, derLocation) }, - { 0, } -}; - -const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate } -}; - - -SECStatus -CERT_EncodeSubjectKeyID(PRArenaPool *arena, char *value, int len, SECItem *encodedValue) -{ - SECItem encodeContext; - SECStatus rv = SECSuccess; - - - PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); - - if (value != NULL) { - encodeContext.data = (unsigned char *)value; - encodeContext.len = len; - } - if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, - CERTSubjectKeyIDTemplate) == NULL) { - rv = SECFailure; - } - - return(rv); -} - - -SECStatus -CERT_EncodePublicKeyUsagePeriod(PRArenaPool *arena, PKUPEncodedContext *pkup, SECItem *encodedValue) -{ - SECStatus rv = SECSuccess; - - if (SEC_ASN1EncodeItem (arena, encodedValue, pkup, - CERTPrivateKeyUsagePeriodTemplate) == NULL) { - rv = SECFailure; - } - return(rv); -} - - -SECStatus -CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedValue) -{ - SECItem encodeContext; - SECStatus rv = SECSuccess; - - - PORT_Memset (&encodeContext, 0, sizeof (encodeContext)); - - if (value != NULL) { - encodeContext.data = (unsigned char *)value; - encodeContext.len = strlen(value); - } - if (SEC_ASN1EncodeItem (arena, encodedValue, &encodeContext, - CERTIA5TypeTemplate) == NULL) { - rv = SECFailure; - } - - return(rv); -} - -SECStatus -CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue) -{ - SECItem **encodedGenName; - SECStatus rv = SECSuccess; - - encodedGenName = cert_EncodeGeneralNames(arena, value); - if (SEC_ASN1EncodeItem (arena, encodedValue, &encodedGenName, - CERT_GeneralNamesTemplate) == NULL) { - rv = SECFailure; - } - - return rv; -} - -CERTGeneralName * -CERT_DecodeAltNameExtension(PRArenaPool *arena, SECItem *EncodedAltName) -{ - SECStatus rv = SECSuccess; - AltNameEncodedContext encodedContext; - - encodedContext.encodedGenName = NULL; - PORT_Memset(&encodedContext, 0, sizeof(AltNameEncodedContext)); - rv = SEC_ASN1DecodeItem (arena, &encodedContext, CERT_GeneralNamesTemplate, - EncodedAltName); - if (rv == SECFailure) { - goto loser; - } - return cert_DecodeGeneralNames(arena, encodedContext.encodedGenName); -loser: - return NULL; -} - - -SECStatus -CERT_EncodeNameConstraintsExtension(PRArenaPool *arena, - CERTNameConstraints *value, - SECItem *encodedValue) -{ - SECStatus rv = SECSuccess; - - rv = cert_EncodeNameConstraints(value, arena, encodedValue); - return rv; -} - - -CERTNameConstraints * -CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, - SECItem *encodedConstraints) -{ - return cert_DecodeNameConstraints(arena, encodedConstraints); -} - - -CERTAuthInfoAccess ** -cert_DecodeAuthInfoAccessExtension(PRArenaPool *arena, - SECItem *encodedExtension) -{ - CERTAuthInfoAccess **info = NULL; - SECStatus rv; - int i; - - rv = SEC_ASN1DecodeItem(arena, &info, CERTAuthInfoAccessTemplate, - encodedExtension); - if (rv != SECSuccess || info == NULL) { - return NULL; - } - - for (i = 0; info[i] != NULL; i++) { - info[i]->location = CERT_DecodeGeneralName(arena, - &(info[i]->derLocation), - NULL); - } - return info; -} - -SECStatus -cert_EncodeAuthInfoAccessExtension(PRArenaPool *arena, - CERTAuthInfoAccess **info, - SECItem *dest) -{ - SECItem *dummy; - int i; - - PORT_Assert(info != NULL); - PORT_Assert(dest != NULL); - if (info == NULL || dest == NULL) { - return SECFailure; - } - - for (i = 0; info[i] != NULL; i++) { - if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation), - arena) == NULL) - /* Note that this may leave some of the locations filled in. */ - return SECFailure; - } - dummy = SEC_ASN1EncodeItem(arena, dest, &info, - CERTAuthInfoAccessTemplate); - if (dummy == NULL) { - return SECFailure; - } - return SECSuccess; -} diff --git a/security/nss/lib/certdb/xconst.h b/security/nss/lib/certdb/xconst.h deleted file mode 100644 index 42c49f2e4..000000000 --- a/security/nss/lib/certdb/xconst.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "certt.h" - -typedef struct PKUPEncodedContext{ - SECItem notBefore; - SECItem notAfter; - /* SECItem encodedValue; */ - PRArenaPool *arena; -}PKUPEncodedContext; - -typedef struct AltNameEncodedContext{ - SECItem **encodedGenName; -}AltNameEncodedContext; - - -typedef struct NameConstraint{ - CERTGeneralName generalName; - int min; - int max; -}NameConstraint; - - - -extern SECStatus -CERT_EncodePublicKeyUsagePeriod(PRArenaPool *arena, PKUPEncodedContext *pkup, - SECItem *encodedValue); - -extern SECStatus -CERT_EncodeAltNameExtension(PRArenaPool *arena, CERTGeneralName *value, SECItem *encodedValue); - -extern SECStatus -CERT_EncodeNameConstraintsExtension(PRArenaPool *arena, CERTNameConstraints *value, - SECItem *encodedValue); -extern CERTGeneralName * -CERT_DecodeAltNameExtension(PRArenaPool *arena, SECItem *EncodedAltName); - -extern CERTNameConstraints * -CERT_DecodeNameConstraintsExtension(PRArenaPool *arena, SECItem *encodedConstraints); - -extern SECStatus -CERT_EncodeSubjectKeyID(PRArenaPool *arena, char *value, int len, SECItem *encodedValue); - -extern SECStatus -CERT_EncodeIA5TypeExtension(PRArenaPool *arena, char *value, SECItem *encodedValue); - -CERTAuthInfoAccess ** -cert_DecodeAuthInfoAccessExtension(PRArenaPool *arena, - SECItem *encodedExtension); - -SECStatus -cert_EncodeAuthInfoAccessExtension(PRArenaPool *arena, - CERTAuthInfoAccess **info, - SECItem *dest); diff --git a/security/nss/lib/certhigh/Makefile b/security/nss/lib/certhigh/Makefile deleted file mode 100644 index 08b7137d5..000000000 --- a/security/nss/lib/certhigh/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/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c deleted file mode 100644 index 6c8831aae..000000000 --- a/security/nss/lib/certhigh/certhigh.c +++ /dev/null @@ -1,1218 +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 "nspr.h" -#include "secerr.h" -#include "secasn1.h" -#include "seccomon.h" -#include "pk11func.h" -#include "certdb.h" -#include "certt.h" -#include "cert.h" -#include "certxutl.h" - -#ifndef NSS_3_4_CODE -#define NSS_3_4_CODE -#endif -#include "nsspki.h" -#include "pki.h" -#include "pkit.h" -#include "pkitm.h" -#include "pki3hack.h" - - -PRBool -CERT_MatchNickname(char *name1, char *name2) { - char *nickname1= NULL; - char *nickname2 = NULL; - char *token1; - char *token2; - char *token = NULL; - int len; - - /* first deal with the straight comparison */ - if (PORT_Strcmp(name1, name2) == 0) { - return PR_TRUE; - } - /* we need to handle the case where one name has an explicit token and the other - * doesn't */ - token1 = PORT_Strchr(name1,':'); - token2 = PORT_Strchr(name2,':'); - if ((token1 && token2) || (!token1 && !token2)) { - /* either both token names are specified or neither are, not match */ - return PR_FALSE; - } - if (token1) { - token=name1; - nickname1=token1; - nickname2=name2; - } else { - token=name2; - nickname1=token2; - nickname2=name1; - } - len = nickname1-token; - nickname1++; - if (PORT_Strcmp(nickname1,nickname2) != 0) { - return PR_FALSE; - } - /* compare the other token with the internal slot here */ - return PR_TRUE; -} - -static SECStatus -cert_UserCertsOnly(CERTCertList *certList) -{ - CERTCertListNode *node, *freenode; - CERTCertificate *cert; - - node = CERT_LIST_HEAD(certList); - - while ( ! CERT_LIST_END(node, certList) ) { - cert = node->cert; - if ( !( cert->trust->sslFlags & CERTDB_USER ) && - !( cert->trust->emailFlags & CERTDB_USER ) && - !( cert->trust->objectSigningFlags & CERTDB_USER ) ) { - /* 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); -} - -/* - * 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) -{ - CERTCertNicknames *nicknames = NULL; - char **nnptr; - int nn; - CERTCertificate *cert = NULL; - CERTCertList *certList = NULL; - SECStatus rv; - int64 time; - CERTCertListNode *node = NULL; - CERTCertListNode *freenode = NULL; - int n; - - time = PR_Now(); - - nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER, - proto_win); - - if ( ( nicknames == NULL ) || ( nicknames->numnicknames == 0 ) ) { - goto loser; - } - - nnptr = nicknames->nicknames; - nn = nicknames->numnicknames; - - while ( nn > 0 ) { - cert = NULL; - /* use the pk11 call so that we pick up any certs on tokens, - * which may require login - */ - if ( proto_win != NULL ) { - cert = PK11_FindCertFromNickname(*nnptr,proto_win); - } - - /* Sigh, It turns out if the cert is already in the temp db, because - * it's in the perm db, then the nickname lookup doesn't work. - * since we already have the cert here, though, than we can just call - * CERT_CreateSubjectCertList directly. For those cases where we didn't - * find the cert in pkcs #11 (because we didn't have a password arg, - * or because the nickname is for a peer, server, or CA cert, then we - * go look the cert up. - */ - if (cert == NULL) { - cert = CERT_FindCertByNickname(handle,*nnptr); - } - - if ( cert != NULL ) { - /* collect certs for this nickname, sorting them into the list */ - certList = CERT_CreateSubjectCertList(certList, handle, - &cert->derSubject, time, validOnly); - - cert_UserCertsOnly(certList); - - /* drop the extra reference */ - CERT_DestroyCertificate(cert); - } - - nnptr++; - nn--; - } - - /* remove certs with incorrect usage */ - rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE); - - if ( rv != SECSuccess ) { - goto loser; - } - - /* remove any extra certs for each name */ - if ( oneCertPerName ) { - PRBool *flags; - - nn = nicknames->numnicknames; - nnptr = nicknames->nicknames; - - flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn); - if ( flags == NULL ) { - goto loser; - } - - node = CERT_LIST_HEAD(certList); - - /* treverse all certs in the list */ - while ( !CERT_LIST_END(node, certList) ) { - - /* find matching nickname index */ - for ( n = 0; n < nn; n++ ) { - if ( CERT_MatchNickname(nnptr[n], node->cert->nickname) ) { - /* We found a match. If this is the first one, then - * set the flag and move on to the next cert. If this - * is not the first one then delete it from the list. - */ - if ( flags[n] ) { - /* We have already seen a cert with this nickname, - * so delete this one. - */ - freenode = node; - node = CERT_LIST_NEXT(node); - CERT_RemoveCertListNode(freenode); - } else { - /* keep the first cert for each nickname, but set the - * flag so we know to delete any others with the same - * nickname. - */ - flags[n] = PR_TRUE; - node = CERT_LIST_NEXT(node); - } - break; - } - } - if ( n == nn ) { - /* if we get here it means that we didn't find a matching - * nickname, which should not happen. - */ - PORT_Assert(0); - node = CERT_LIST_NEXT(node); - } - } - PORT_Free(flags); - } - - goto done; - -loser: - if ( certList != NULL ) { - CERT_DestroyCertList(certList); - certList = NULL; - } - -done: - if ( nicknames != NULL ) { - CERT_FreeNicknames(nicknames); - } - - return(certList); -} - -/* - * 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) -{ - CERTCertificate *cert = NULL; - CERTCertList *certList = NULL; - SECStatus rv; - int64 time; - - time = PR_Now(); - - /* use the pk11 call so that we pick up any certs on tokens, - * which may require login - */ - /* XXX - why is this restricted? */ - if ( proto_win != NULL ) { - cert = PK11_FindCertFromNickname(nickname,proto_win); - } - - - /* sigh, There are still problems find smart cards from the temp - * db. This will get smart cards working again. The real fix - * is to make sure we can search the temp db by their token nickname. - */ - if (cert == NULL) { - cert = CERT_FindCertByNickname(handle,nickname); - } - - if ( cert != NULL ) { - /* collect certs for this nickname, sorting them into the list */ - certList = CERT_CreateSubjectCertList(certList, handle, - &cert->derSubject, time, validOnly); - - cert_UserCertsOnly(certList); - - /* drop the extra reference */ - CERT_DestroyCertificate(cert); - cert = NULL; - } - - if ( certList == NULL ) { - goto loser; - } - - /* remove certs with incorrect usage */ - rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE); - - if ( rv != SECSuccess ) { - goto loser; - } - - if ( ! CERT_LIST_END(CERT_LIST_HEAD(certList), certList) ) { - cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert); - } - -loser: - if ( certList != NULL ) { - CERT_DestroyCertList(certList); - } - - return(cert); -} - -CERTCertList * -CERT_MatchUserCert(CERTCertDBHandle *handle, - SECCertUsage usage, - int nCANames, char **caNames, - void *proto_win) -{ - CERTCertList *certList = NULL; - SECStatus rv; - - certList = CERT_FindUserCertsByUsage(handle, usage, PR_TRUE, PR_TRUE, - proto_win); - if ( certList == NULL ) { - goto loser; - } - - rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage); - if ( rv != SECSuccess ) { - goto loser; - } - - goto done; - -loser: - if ( certList != NULL ) { - CERT_DestroyCertList(certList); - certList = NULL; - } - -done: - - return(certList); -} - - -typedef struct stringNode { - struct stringNode *next; - char *string; -} stringNode; - -static SECStatus -CollectNicknames( NSSCertificate *c, void *data) -{ - CERTCertNicknames *names; - PRBool saveit = PR_FALSE; - stringNode *node; - int len; - NSSTrustDomain *td; - NSSTrust *trust; - char *stanNickname; - char *nickname = NULL; - - names = (CERTCertNicknames *)data; - - stanNickname = nssCertificate_GetNickname(c,NULL); - - if ( stanNickname ) { - if (names->what == SEC_CERT_NICKNAMES_USER) { - saveit = NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL); - } -#ifdef notdef - else { - td = NSSCertificate_GetTrustDomain(c); - if (!td) { - return SECSuccess; - } - trust = nssTrustDomain_FindTrustForCertificate(td,c); - - switch(names->what) { - case SEC_CERT_NICKNAMES_ALL: - if ((trust->sslFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) || - (trust->emailFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) || - (trust->objectSigningFlags & - (CERTDB_VALID_CA|CERTDB_VALID_PEER))) { - saveit = PR_TRUE; - } - - break; - case SEC_CERT_NICKNAMES_SERVER: - if ( trust->sslFlags & CERTDB_VALID_PEER ) { - saveit = PR_TRUE; - } - - break; - case SEC_CERT_NICKNAMES_CA: - if (((trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA)|| - ((trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA) || - ((trust->objectSigningFlags & CERTDB_VALID_CA ) - == CERTDB_VALID_CA)) { - saveit = PR_TRUE; - } - break; - } - } -#endif - } - - /* traverse the list of collected nicknames and make sure we don't make - * a duplicate - */ - if ( saveit ) { - nickname = STAN_GetCERTCertificateName(c); - /* nickname can only be NULL here if we are having memory - * alloc problems */ - if (nickname == NULL) { - return SECFailure; - } - node = (stringNode *)names->head; - while ( node != NULL ) { - if ( PORT_Strcmp(nickname, node->string) == 0 ) { - /* if the string matches, then don't save this one */ - saveit = PR_FALSE; - break; - } - node = node->next; - } - } - - if ( saveit ) { - - /* allocate the node */ - node = (stringNode*)PORT_ArenaAlloc(names->arena, sizeof(stringNode)); - if ( node == NULL ) { - return(SECFailure); - } - - /* copy the string */ - len = PORT_Strlen(nickname) + 1; - node->string = (char*)PORT_ArenaAlloc(names->arena, len); - if ( node->string == NULL ) { - if (nickname) PORT_Free(nickname); - return(SECFailure); - } - PORT_Memcpy(node->string, nickname, len); - - /* link it into the list */ - node->next = (stringNode *)names->head; - names->head = (void *)node; - - /* bump the count */ - names->numnicknames++; - } - - if (nickname) PORT_Free(nickname); - return(SECSuccess); -} - -CERTCertNicknames * -CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx) -{ - PRArenaPool *arena; - CERTCertNicknames *names; - int i; - stringNode *node; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(NULL); - } - - names = (CERTCertNicknames *)PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames)); - if ( names == NULL ) { - goto loser; - } - - names->arena = arena; - names->head = NULL; - names->numnicknames = 0; - names->nicknames = NULL; - names->what = what; - names->totallen = 0; - - /* make sure we are logged in */ - (void) pk11_TraverseAllSlots(NULL, NULL, wincx); - - NSSTrustDomain_TraverseCertificates(handle, - CollectNicknames, (void *)names); - if ( names->numnicknames ) { - names->nicknames = (char**)PORT_ArenaAlloc(arena, - names->numnicknames * sizeof(char *)); - - if ( names->nicknames == NULL ) { - goto loser; - } - - node = (stringNode *)names->head; - - for ( i = 0; i < names->numnicknames; i++ ) { - PORT_Assert(node != NULL); - - names->nicknames[i] = node->string; - names->totallen += PORT_Strlen(node->string); - node = node->next; - } - - PORT_Assert(node == NULL); - } - - return(names); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(NULL); -} - -void -CERT_FreeNicknames(CERTCertNicknames *nicknames) -{ - PORT_FreeArena(nicknames->arena, PR_FALSE); - - return; -} - -/* [ FROM pcertdb.c ] */ - -typedef struct dnameNode { - struct dnameNode *next; - SECItem name; -} dnameNode; - -void -CERT_FreeDistNames(CERTDistNames *names) -{ - PORT_FreeArena(names->arena, PR_FALSE); - - return; -} - -static SECStatus -CollectDistNames( CERTCertificate *cert, SECItem *k, void *data) -{ - CERTDistNames *names; - PRBool saveit = PR_FALSE; - CERTCertTrust *trust; - dnameNode *node; - int len; - - names = (CERTDistNames *)data; - - if ( cert->trust ) { - trust = cert->trust; - - /* only collect names of CAs trusted for issuing SSL clients */ - if ( trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ) { - saveit = PR_TRUE; - } - } - - if ( saveit ) { - /* allocate the node */ - node = (dnameNode*)PORT_ArenaAlloc(names->arena, sizeof(dnameNode)); - if ( node == NULL ) { - return(SECFailure); - } - - /* copy the name */ - node->name.len = len = cert->derSubject.len; - node->name.type = siBuffer; - node->name.data = (unsigned char*)PORT_ArenaAlloc(names->arena, len); - if ( node->name.data == NULL ) { - return(SECFailure); - } - PORT_Memcpy(node->name.data, cert->derSubject.data, len); - - /* link it into the list */ - node->next = (dnameNode *)names->head; - names->head = (void *)node; - - /* bump the count */ - names->nnames++; - } - - return(SECSuccess); -} - -/* - * Return all of the CAs that are "trusted" for SSL. - */ -CERTDistNames * -CERT_GetSSLCACerts(CERTCertDBHandle *handle) -{ - PRArenaPool *arena; - CERTDistNames *names; - int i; - SECStatus rv; - dnameNode *node; - - /* allocate an arena to use */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(NULL); - } - - /* allocate the header structure */ - names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames)); - if ( names == NULL ) { - goto loser; - } - - /* initialize the header struct */ - names->arena = arena; - names->head = NULL; - names->nnames = 0; - names->names = NULL; - - /* collect the names from the database */ - rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL); - if ( rv ) { - goto loser; - } - - /* construct the array from the list */ - if ( names->nnames ) { - names->names = (SECItem*)PORT_ArenaAlloc(arena, names->nnames * sizeof(SECItem)); - - if ( names->names == NULL ) { - goto loser; - } - - node = (dnameNode *)names->head; - - for ( i = 0; i < names->nnames; i++ ) { - PORT_Assert(node != NULL); - - names->names[i] = node->name; - node = node->next; - } - - PORT_Assert(node == NULL); - } - - return(names); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(NULL); -} - -CERTDistNames * -CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames, - int nnames) -{ - CERTDistNames *dnames = NULL; - PRArenaPool *arena; - int i, rv; - SECItem *names = NULL; - CERTCertificate *cert = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) goto loser; - dnames = (CERTDistNames*)PORT_Alloc(sizeof(CERTDistNames)); - if (dnames == NULL) goto loser; - - dnames->arena = arena; - dnames->nnames = nnames; - dnames->names = names = (SECItem*)PORT_Alloc(nnames * sizeof(SECItem)); - if (names == NULL) goto loser; - - for (i = 0; i < nnames; i++) { - cert = CERT_FindCertByNicknameOrEmailAddr(handle, nicknames[i]); - if (cert == NULL) goto loser; - rv = SECITEM_CopyItem(arena, &names[i], &cert->derSubject); - if (rv == SECFailure) goto loser; - CERT_DestroyCertificate(cert); - } - return dnames; - -loser: - if (cert != NULL) - CERT_DestroyCertificate(cert); - if (arena != NULL) - PORT_FreeArena(arena, PR_FALSE); - return NULL; -} - -/* [ from pcertdb.c - calls Ascii to Name ] */ -/* - * Lookup a certificate in the database by name - */ -CERTCertificate * -CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr) -{ - CERTName *name; - SECItem *nameItem; - CERTCertificate *cert = NULL; - PRArenaPool *arena = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( arena == NULL ) { - goto loser; - } - - name = CERT_AsciiToName(nameStr); - - if ( name ) { - nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name, - CERT_NameTemplate); - if ( nameItem == NULL ) { - goto loser; - } - - cert = CERT_FindCertByName(handle, nameItem); - CERT_DestroyName(name); - } - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(cert); -} - -/* From certv3.c */ - -CERTCrlDistributionPoints * -CERT_FindCRLDistributionPoints (CERTCertificate *cert) -{ - SECItem encodedExtenValue; - SECStatus rv; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS, - &encodedExtenValue); - if ( rv != SECSuccess ) { - return (NULL); - } - - return (CERT_DecodeCRLDistributionPoints (cert->arena, - &encodedExtenValue)); -} - -/* From crl.c */ -CERTSignedCrl * CERT_ImportCRL - (CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx) -{ - CERTSignedCrl* retCrl = NULL; - PK11SlotInfo* slot = PK11_GetInternalKeySlot(); - retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx, - CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS); - PK11_FreeSlot(slot); - - return retCrl; -} - -/* From certdb.c */ -static SECStatus -cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool trusted) -{ - SECStatus rv; - SECItem *derCert; - PRArenaPool *arena; - CERTCertificate *cert = NULL; - CERTCertificate *newcert = NULL; - CERTCertDBHandle *handle; - CERTCertTrust trust; - PRBool isca; - char *nickname; - unsigned int certtype; - - handle = CERT_GetDefaultCertDB(); - - arena = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( ! arena ) { - goto loser; - } - - while (numcerts--) { - derCert = certs; - certs++; - - /* decode my certificate */ - /* This use is ok -- only looks at decoded parts, calls NewTemp later */ - newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); - if ( newcert == NULL ) { - goto loser; - } - - if (!trusted) { - /* make sure that cert is valid */ - rv = CERT_CertTimesValid(newcert); - if ( rv == SECFailure ) { - goto endloop; - } - } - - /* does it have the CA extension */ - - /* - * Make sure that if this is an intermediate CA in the chain that - * it was given permission by its signer to be a CA. - */ - isca = CERT_IsCACert(newcert, &certtype); - - if ( !isca ) { - if (!trusted) { - goto endloop; - } - trust.sslFlags = CERTDB_VALID_CA; - trust.emailFlags = CERTDB_VALID_CA; - trust.objectSigningFlags = CERTDB_VALID_CA; - } else { - /* SSL ca's must have the ssl bit set */ - if ( ( certUsage == certUsageSSLCA ) && - (( certtype & NS_CERT_TYPE_SSL_CA ) != NS_CERT_TYPE_SSL_CA )) { - goto endloop; - } - - /* it passed all of the tests, so lets add it to the database */ - /* mark it as a CA */ - PORT_Memset((void *)&trust, 0, sizeof(trust)); - switch ( certUsage ) { - case certUsageSSLCA: - trust.sslFlags = CERTDB_VALID_CA; - break; - case certUsageUserCertImport: - if ((certtype & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) { - trust.sslFlags = CERTDB_VALID_CA; - } - if ((certtype & NS_CERT_TYPE_EMAIL_CA) - == NS_CERT_TYPE_EMAIL_CA ) { - trust.emailFlags = CERTDB_VALID_CA; - } - if ( ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) == - NS_CERT_TYPE_OBJECT_SIGNING_CA ) { - trust.objectSigningFlags = CERTDB_VALID_CA; - } - break; - default: - PORT_Assert(0); - break; - } - } - - cert = CERT_NewTempCertificate(handle, derCert, NULL, - PR_FALSE, PR_FALSE); - if ( cert == NULL ) { - goto loser; - } - - /* get a default nickname for it */ - nickname = CERT_MakeCANickname(cert); - - rv = CERT_AddTempCertToPerm(cert, nickname, &trust); - - /* free the nickname */ - if ( nickname ) { - PORT_Free(nickname); - } - - CERT_DestroyCertificate(cert); - cert = NULL; - - if ( rv != SECSuccess ) { - goto loser; - } - -endloop: - if ( newcert ) { - CERT_DestroyCertificate(newcert); - newcert = NULL; - } - - } - - rv = SECSuccess; - goto done; -loser: - rv = SECFailure; -done: - - if ( newcert ) { - CERT_DestroyCertificate(newcert); - newcert = NULL; - } - - if ( cert ) { - CERT_DestroyCertificate(cert); - cert = NULL; - } - - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(rv); -} - -SECStatus -CERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage) -{ - return cert_ImportCAChain(certs, numcerts, certUsage, PR_FALSE); -} - -SECStatus -CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage) { - return cert_ImportCAChain(certs, numcerts, certUsage, PR_TRUE); -} - -/* Moved from certdb.c */ -/* -** CERT_CertChainFromCert -** -** Construct a CERTCertificateList consisting of the given certificate and all -** of the issuer certs until we either get to a self-signed cert or can't find -** an issuer. Since we don't know how many certs are in the chain we have to -** build a linked list first as we count them. -*/ - -typedef struct certNode { - struct certNode *next; - CERTCertificate *cert; -} certNode; - -CERTCertificateList * -CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, - PRBool includeRoot) -{ -#ifdef NSS_CLASSIC - CERTCertificateList *chain = NULL; - CERTCertificate *c; - SECItem *p; - int rv, len = 0; - PRArenaPool *tmpArena, *arena; - certNode *head, *tail, *node; - - /* - * Initialize stuff so we can goto loser. - */ - head = NULL; - arena = NULL; - - /* arena for linked list */ - tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (tmpArena == NULL) goto no_memory; - - /* arena for SecCertificateList */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) goto no_memory; - - head = tail = (certNode*)PORT_ArenaZAlloc(tmpArena, sizeof(certNode)); - if (head == NULL) goto no_memory; - - /* put primary cert first in the linked list */ - head->cert = c = CERT_DupCertificate(cert); - if (head->cert == NULL) goto loser; - len++; - - /* add certs until we come to a self-signed one */ - while(SECITEM_CompareItem(&c->derIssuer, &c->derSubject) != SECEqual) { - c = CERT_FindCertIssuer(tail->cert, PR_Now(), usage); - if (c == NULL) { - /* no root is found, so make sure we don't attempt to delete one - * below - */ - includeRoot = PR_TRUE; - break; - } - - tail->next = (certNode*)PORT_ArenaZAlloc(tmpArena, sizeof(certNode)); - tail = tail->next; - if (tail == NULL) goto no_memory; - - tail->cert = c; - len++; - } - - /* now build the CERTCertificateList */ - chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList)); - if (chain == NULL) goto no_memory; - chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); - if (chain->certs == NULL) goto no_memory; - - for(node = head, p = chain->certs; node; node = node->next, p++) { - rv = SECITEM_CopyItem(arena, p, &node->cert->derCert); - CERT_DestroyCertificate(node->cert); - node->cert = NULL; - if (rv < 0) goto loser; - } - if ( !includeRoot && len > 1) { - chain->len = len - 1; - } else { - chain->len = len; - } - - chain->arena = arena; - - PORT_FreeArena(tmpArena, PR_FALSE); - - return chain; - -no_memory: - PORT_SetError(SEC_ERROR_NO_MEMORY); -loser: - if (head != NULL) { - for (node = head; node; node = node->next) { - if (node->cert != NULL) - CERT_DestroyCertificate(node->cert); - } - } - - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - - if (tmpArena != NULL) { - PORT_FreeArena(tmpArena, PR_FALSE); - } - - return NULL; -#else - CERTCertificateList *chain = NULL; - NSSCertificate **stanChain; - NSSCertificate *stanCert; - PRArenaPool *arena; - NSSUsage nssUsage; - int i, len; - - stanCert = STAN_GetNSSCertificate(cert); - nssUsage.anyUsage = PR_FALSE; - nssUsage.nss3usage = usage; - stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL, - NULL, 0, NULL, NULL); - if (!stanChain) { - return NULL; - } - - len = 0; - stanCert = stanChain[0]; - while (stanCert) { - stanCert = stanChain[++len]; - } - - arena = PORT_NewArena(4096); - if (arena == NULL) { - goto loser; - } - - chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, - sizeof(CERTCertificateList)); - if (!chain) goto loser; - chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); - if (!chain->certs) goto loser; - i = 0; - stanCert = stanChain[i]; - while (stanCert) { - SECItem derCert; - CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); - if (!cCert) { - goto loser; - } - derCert.len = (unsigned int)stanCert->encoding.size; - derCert.data = (unsigned char *)stanCert->encoding.data; - derCert.type = siBuffer; - SECITEM_CopyItem(arena, &chain->certs[i], &derCert); - CERT_DestroyCertificate(cCert); - stanCert = stanChain[++i]; - } - if ( !includeRoot && len > 1) { - chain->len = len - 1; - } else { - chain->len = len; - } - - chain->arena = arena; - nss_ZFreeIf(stanChain); - return chain; -loser: - i = 0; - stanCert = stanChain[i]; - while (stanCert) { - CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); - if (cCert) { - CERT_DestroyCertificate(cCert); - } - stanCert = stanChain[++i]; - } - nss_ZFreeIf(stanChain); - if (arena) { - PORT_FreeArena(arena, PR_FALSE); - } - return NULL; -#endif -} - -/* Builds a CERTCertificateList holding just one DER-encoded cert, namely -** the one for the cert passed as an argument. -*/ -CERTCertificateList * -CERT_CertListFromCert(CERTCertificate *cert) -{ - CERTCertificateList *chain = NULL; - int rv; - PRArenaPool *arena; - - /* arena for SecCertificateList */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) goto no_memory; - - /* build the CERTCertificateList */ - chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList)); - if (chain == NULL) goto no_memory; - chain->certs = (SECItem*)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem)); - if (chain->certs == NULL) goto no_memory; - rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert)); - if (rv < 0) goto loser; - chain->len = 1; - chain->arena = arena; - - return chain; - -no_memory: - PORT_SetError(SEC_ERROR_NO_MEMORY); -loser: - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return NULL; -} - -CERTCertificateList * -CERT_DupCertList(CERTCertificateList * oldList) -{ - CERTCertificateList *newList = NULL; - PRArenaPool *arena = NULL; - SECItem *newItem; - SECItem *oldItem; - int len = oldList->len; - int rv; - - /* arena for SecCertificateList */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) - goto no_memory; - - /* now build the CERTCertificateList */ - newList = PORT_ArenaNew(arena, CERTCertificateList); - if (newList == NULL) - goto no_memory; - newList->arena = arena; - newItem = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); - if (newItem == NULL) - goto no_memory; - newList->certs = newItem; - newList->len = len; - - for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) { - rv = SECITEM_CopyItem(arena, newItem, oldItem); - if (rv < 0) - goto loser; - } - return newList; - -no_memory: - PORT_SetError(SEC_ERROR_NO_MEMORY); -loser: - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return NULL; -} - -void -CERT_DestroyCertificateList(CERTCertificateList *list) -{ - PORT_FreeArena(list->arena, PR_FALSE); -} - diff --git a/security/nss/lib/certhigh/certhtml.c b/security/nss/lib/certhigh/certhtml.c deleted file mode 100644 index ff5f3c82d..000000000 --- a/security/nss/lib/certhigh/certhtml.c +++ /dev/null @@ -1,605 +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. - */ - -/* - * certhtml.c --- convert a cert to html - * - * $Id$ - */ - -#include "seccomon.h" -#include "secitem.h" -#include "sechash.h" -#include "cert.h" -#include "keyhi.h" -#include "secder.h" -#include "prprf.h" -#include "secport.h" -#include "secasn1.h" -#include "pk11func.h" - -static char *hex = "0123456789ABCDEF"; - -/* -** Convert a der-encoded integer to a hex printable string form -*/ -char *CERT_Hexify (SECItem *i, int do_colon) -{ - unsigned char *cp, *end; - char *rv, *o; - - if (!i->len) { - return PORT_Strdup("00"); - } - - rv = o = (char*) PORT_Alloc(i->len * 3); - if (!rv) return rv; - - cp = i->data; - end = cp + i->len; - while (cp < end) { - unsigned char ch = *cp++; - *o++ = hex[(ch >> 4) & 0xf]; - *o++ = hex[ch & 0xf]; - if (cp != end) { - if (do_colon) { - *o++ = ':'; - } - } - } - *o = 0; /* Null terminate the string */ - return rv; -} - -static char * -gatherStrings(char **strings) -{ - char **strs; - int len; - char *ret; - char *s; - - /* find total length of all strings */ - strs = strings; - len = 0; - while ( *strs ) { - len += PORT_Strlen(*strs); - strs++; - } - - /* alloc enough memory for it */ - ret = (char*)PORT_Alloc(len + 1); - if ( !ret ) { - return(ret); - } - - s = ret; - - /* copy the strings */ - strs = strings; - while ( *strs ) { - PORT_Strcpy(s, *strs); - s += PORT_Strlen(*strs); - strs++; - } - - return( ret ); -} - -#define BREAK "<br>" -#define BREAKLEN 4 -#define COMMA ", " -#define COMMALEN 2 - -#define MAX_OUS 20 -#define MAX_DC MAX_OUS - - -char *CERT_FormatName (CERTName *name) -{ - CERTRDN** rdns; - CERTRDN * rdn; - CERTAVA** avas; - CERTAVA* ava; - char * buf = 0; - char * tmpbuf = 0; - SECItem * cn = 0; - SECItem * email = 0; - SECItem * org = 0; - SECItem * loc = 0; - SECItem * state = 0; - SECItem * country = 0; - SECItem * dq = 0; - - unsigned len = 0; - int tag; - int i; - int ou_count = 0; - int dc_count = 0; - PRBool first; - SECItem * orgunit[MAX_OUS]; - SECItem * dc[MAX_DC]; - - /* Loop over name components and gather the interesting ones */ - rdns = name->rdns; - while ((rdn = *rdns++) != 0) { - avas = rdn->avas; - while ((ava = *avas++) != 0) { - tag = CERT_GetAVATag(ava); - switch(tag) { - case SEC_OID_AVA_COMMON_NAME: - cn = CERT_DecodeAVAValue(&ava->value); - len += cn->len; - break; - case SEC_OID_AVA_COUNTRY_NAME: - country = CERT_DecodeAVAValue(&ava->value); - len += country->len; - break; - case SEC_OID_AVA_LOCALITY: - loc = CERT_DecodeAVAValue(&ava->value); - len += loc->len; - break; - case SEC_OID_AVA_STATE_OR_PROVINCE: - state = CERT_DecodeAVAValue(&ava->value); - len += state->len; - break; - case SEC_OID_AVA_ORGANIZATION_NAME: - org = CERT_DecodeAVAValue(&ava->value); - len += org->len; - break; - case SEC_OID_AVA_DN_QUALIFIER: - dq = CERT_DecodeAVAValue(&ava->value); - len += dq->len; - break; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - if (ou_count < MAX_OUS) { - orgunit[ou_count] = CERT_DecodeAVAValue(&ava->value); - len += orgunit[ou_count++]->len; - } - break; - case SEC_OID_AVA_DC: - if (dc_count < MAX_DC) { - dc[dc_count] = CERT_DecodeAVAValue(&ava->value); - len += dc[dc_count++]->len; - } - break; - case SEC_OID_PKCS9_EMAIL_ADDRESS: - case SEC_OID_RFC1274_MAIL: - email = CERT_DecodeAVAValue(&ava->value); - len += email->len; - break; - default: - break; - } - } - } - - /* XXX - add some for formatting */ - len += 128; - - /* allocate buffer */ - buf = (char *)PORT_Alloc(len); - if ( !buf ) { - return(0); - } - - tmpbuf = buf; - - if ( cn ) { - PORT_Memcpy(tmpbuf, cn->data, cn->len); - tmpbuf += cn->len; - PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); - tmpbuf += BREAKLEN; - SECITEM_FreeItem(cn, PR_TRUE); - } - if ( email ) { - PORT_Memcpy(tmpbuf, email->data, email->len); - tmpbuf += ( email->len ); - PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); - tmpbuf += BREAKLEN; - SECITEM_FreeItem(email, PR_TRUE); - } - for (i=ou_count-1; i >= 0; i--) { - PORT_Memcpy(tmpbuf, orgunit[i]->data, orgunit[i]->len); - tmpbuf += ( orgunit[i]->len ); - PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); - tmpbuf += BREAKLEN; - SECITEM_FreeItem(orgunit[i], PR_TRUE); - } - if ( dq ) { - PORT_Memcpy(tmpbuf, dq->data, dq->len); - tmpbuf += ( dq->len ); - PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); - tmpbuf += BREAKLEN; - SECITEM_FreeItem(dq, PR_TRUE); - } - if ( org ) { - PORT_Memcpy(tmpbuf, org->data, org->len); - tmpbuf += ( org->len ); - PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); - tmpbuf += BREAKLEN; - SECITEM_FreeItem(org, PR_TRUE); - } - for (i=dc_count-1; i >= 0; i--) { - PORT_Memcpy(tmpbuf, dc[i]->data, dc[i]->len); - tmpbuf += ( dc[i]->len ); - PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); - tmpbuf += BREAKLEN; - SECITEM_FreeItem(dc[i], PR_TRUE); - } - first = PR_TRUE; - if ( loc ) { - PORT_Memcpy(tmpbuf, loc->data, loc->len); - tmpbuf += ( loc->len ); - first = PR_FALSE; - SECITEM_FreeItem(loc, PR_TRUE); - } - if ( state ) { - if ( !first ) { - PORT_Memcpy(tmpbuf, COMMA, COMMALEN); - tmpbuf += COMMALEN; - } - PORT_Memcpy(tmpbuf, state->data, state->len); - tmpbuf += ( state->len ); - first = PR_FALSE; - SECITEM_FreeItem(state, PR_TRUE); - } - if ( country ) { - if ( !first ) { - PORT_Memcpy(tmpbuf, COMMA, COMMALEN); - tmpbuf += COMMALEN; - } - PORT_Memcpy(tmpbuf, country->data, country->len); - tmpbuf += ( country->len ); - first = PR_FALSE; - SECITEM_FreeItem(country, PR_TRUE); - } - if ( !first ) { - PORT_Memcpy(tmpbuf, BREAK, BREAKLEN); - tmpbuf += BREAKLEN; - } - - *tmpbuf = 0; - - return(buf); -} - -static char *sec_FortezzaClearance(SECItem *clearance) { - unsigned char clr = 0; - - if (clearance->len > 0) { clr = clearance->data[0]; } - - if (clr & 0x4) return "Top Secret"; - if (clr & 0x8) return "Secret"; - if (clr & 0x10) return "Confidential"; - if (clr & 0x20) return "Sensitive"; - if (clr & 0x40) return "Unclassified"; - return "None"; -} - -static char *sec_FortezzaMessagePrivilege(SECItem *priv) { - unsigned char clr = 0; - - if (priv->len > 0) { clr = (priv->data[0]) & 0x78; } - - if (clr == 0x00) { - return "None"; - } else { - - return PR_smprintf("%s%s%s%s%s%s%s", - - clr&0x40?"Critical/Flash":"", - (clr&0x40) && (clr&0x38) ? ", " : "" , - - clr&0x20?"Immediate/Priority":"", - (clr&0x20) && (clr&0x18) ? ", " : "" , - - clr&0x10?"Routine/Deferred":"", - (clr&0x10) && (clr&0x08) ? ", " : "" , - - clr&0x08?"Rekey Agent":""); - } - -} - -static char *sec_FortezzaCertPrivilege(SECItem *priv) { - unsigned char clr = 0; - - if (priv->len > 0) { clr = priv->data[0]; } - - return PR_smprintf("%s%s%s%s%s%s%s%s%s%s%s%s", - clr&0x40?"Organizational Releaser":"", - (clr&0x40) && (clr&0x3e) ? "," : "" , - clr&0x20?"Policy Creation Authority":"", - (clr&0x20) && (clr&0x1e) ? "," : "" , - clr&0x10?"Certificate Authority":"", - (clr&0x10) && (clr&0x0e) ? "," : "" , - clr&0x08?"Local Managment Authority":"", - (clr&0x08) && (clr&0x06) ? "," : "" , - clr&0x04?"Configuration Vector Authority":"", - (clr&0x04) && (clr&0x02) ? "," : "" , - clr&0x02?"No Signature Capability":"", - clr&0x7e?"":"Signing Only" - ); -} - -static char *htmlcertstrings[] = { - "<table border=0 cellspacing=0 cellpadding=0><tr><td valign=top>" - "<font size=2><b>This Certificate belongs to:</b><br>" - "<table border=0 cellspacing=0 cellpadding=0><tr><td>", - 0, /* image goes here */ - 0, - 0, - "</td><td width=10> </td><td><font size=2>", - 0, /* subject name goes here */ - "</td></tr></table></font></td><td width=20> </td><td valign=top>" - "<font size=2><b>This Certificate was issued by:</b><br>" - "<table border=0 cellspacing=0 cellpadding=0><tr><td>", - 0, /* image goes here */ - 0, - 0, - "</td><td width=10> </td><td><font size=2>", - 0, /* issuer name goes here */ - "</td></tr></table></font></td></tr></table>" - "<b>Serial Number:</b> ", - 0, - "<br><b>This Certificate is valid from ", - 0, /* notBefore goes here */ - " to ", - 0, /* notAfter does here */ - "</b><br><b>Clearance:</b>", - 0, - "<br><b>DSS Privileges:</b>", - 0, - "<br><b>KEA Privileges:</b>", - 0, - "<br><b>KMID:</b>", - 0, - "<br><b>Certificate Fingerprint:</b>" - "<table border=0 cellspacing=0 cellpadding=0><tr>" - "<td width=10> </td><td><font size=2>", - 0, /* fingerprint goes here */ - "</td></tr></table>", - 0, /* comment header goes here */ - 0, /* comment goes here */ - 0, /* comment trailer goes here */ - 0 -}; - -char * -CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, PRBool showIssuer) -{ - SECStatus rv; - char *issuer, *subject, *serialNumber, *version; - char *notBefore, *notAfter; - char *ret; - char *nickname; - SECItem dummyitem; - unsigned char fingerprint[16]; /* result of MD5, always 16 bytes */ - char *fpstr; - SECItem fpitem; - char *commentstring = NULL; - SECKEYPublicKey *pubk; - char *DSSPriv; - char *KMID = NULL; - char *servername; - - if (!cert) { - return(0); - } - - issuer = CERT_FormatName (&cert->issuer); - subject = CERT_FormatName (&cert->subject); - version = CERT_Hexify (&cert->version,1); - serialNumber = CERT_Hexify (&cert->serialNumber,1); - notBefore = DER_UTCDayToAscii(&cert->validity.notBefore); - notAfter = DER_UTCDayToAscii(&cert->validity.notAfter); - servername = CERT_FindNSStringExtension(cert, - SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME); - - nickname = cert->nickname; - if ( nickname == NULL ) { - showImages = PR_FALSE; - } - - dummyitem.data = NULL; - rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_SUBJECT_LOGO, - &dummyitem); - if ( dummyitem.data ) { - PORT_Free(dummyitem.data); - } - - if ( rv || !showImages ) { - htmlcertstrings[1] = ""; - htmlcertstrings[2] = ""; - htmlcertstrings[3] = ""; - } else { - htmlcertstrings[1] = "<img src=\"about:security?subject-logo="; - htmlcertstrings[2] = nickname; - htmlcertstrings[3] = "\">"; - } - - if ( servername ) { - char *tmpstr; - tmpstr = (char *)PORT_Alloc(PORT_Strlen(subject) + - PORT_Strlen(servername) + - sizeof("<br>") + 1); - if ( tmpstr ) { - PORT_Strcpy(tmpstr, servername); - PORT_Strcat(tmpstr, "<br>"); - PORT_Strcat(tmpstr, subject); - PORT_Free(subject); - subject = tmpstr; - } - } - - htmlcertstrings[5] = subject; - - dummyitem.data = NULL; - - rv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_ISSUER_LOGO, - &dummyitem); - if ( dummyitem.data ) { - PORT_Free(dummyitem.data); - } - - if ( rv || !showImages ) { - htmlcertstrings[7] = ""; - htmlcertstrings[8] = ""; - htmlcertstrings[9] = ""; - } else { - htmlcertstrings[7] = "<img src=\"about:security?issuer-logo="; - htmlcertstrings[8] = nickname; - htmlcertstrings[9] = "\">"; - } - - - if (showIssuer == PR_TRUE) { - htmlcertstrings[11] = issuer; - } else { - htmlcertstrings[11] = ""; - } - - htmlcertstrings[13] = serialNumber; - htmlcertstrings[15] = notBefore; - htmlcertstrings[17] = notAfter; - - pubk = CERT_ExtractPublicKey(cert); - DSSPriv = NULL; - if (pubk && (pubk->keyType == fortezzaKey)) { - htmlcertstrings[18] = "</b><br><b>Clearance:</b>"; - htmlcertstrings[19] = sec_FortezzaClearance( - &pubk->u.fortezza.clearance); - htmlcertstrings[20] = "<br><b>DSS Privileges:</b>"; - DSSPriv = sec_FortezzaCertPrivilege( - &pubk->u.fortezza.DSSpriviledge); - htmlcertstrings[21] = DSSPriv; - htmlcertstrings[22] = "<br><b>KEA Privileges:</b>"; - htmlcertstrings[23] = sec_FortezzaMessagePrivilege( - &pubk->u.fortezza.KEApriviledge); - htmlcertstrings[24] = "<br><b>KMID:</b>"; - dummyitem.data = &pubk->u.fortezza.KMID[0]; - dummyitem.len = sizeof(pubk->u.fortezza.KMID); - KMID = CERT_Hexify (&dummyitem,0); - htmlcertstrings[25] = KMID; - } else { - /* clear out the headers in the non-fortezza cases */ - htmlcertstrings[18] = ""; - htmlcertstrings[19] = ""; - htmlcertstrings[20] = ""; - htmlcertstrings[21] = ""; - htmlcertstrings[22] = ""; - htmlcertstrings[23] = ""; - htmlcertstrings[24] = ""; - htmlcertstrings[25] = "</b>"; - } - - if (pubk) { - SECKEY_DestroyPublicKey(pubk); - } - -#define HTML_OFF 27 - rv = PK11_HashBuf(SEC_OID_MD5, fingerprint, - cert->derCert.data, cert->derCert.len); - - fpitem.data = fingerprint; - fpitem.len = sizeof(fingerprint); - - fpstr = CERT_Hexify (&fpitem,1); - - htmlcertstrings[HTML_OFF] = fpstr; - - commentstring = CERT_GetCertCommentString(cert); - - if (commentstring == NULL) { - htmlcertstrings[HTML_OFF+2] = ""; - htmlcertstrings[HTML_OFF+3] = ""; - htmlcertstrings[HTML_OFF+4] = ""; - } else { - htmlcertstrings[HTML_OFF+2] = - "<b>Comment:</b>" - "<table border=0 cellspacing=0 cellpadding=0><tr>" - "<td width=10> </td><td><font size=3>" - "<textarea name=foobar rows=4 cols=55 onfocus=\"this.blur()\">"; - htmlcertstrings[HTML_OFF+3] = commentstring; - htmlcertstrings[HTML_OFF+4] = "</textarea></font></td></tr></table>"; - } - - ret = gatherStrings(htmlcertstrings); - - if ( issuer ) { - PORT_Free(issuer); - } - - if ( subject ) { - PORT_Free(subject); - } - - if ( version ) { - PORT_Free(version); - } - - if ( serialNumber ) { - PORT_Free(serialNumber); - } - - if ( notBefore ) { - PORT_Free(notBefore); - } - - if ( notAfter ) { - PORT_Free(notAfter); - } - - if ( fpstr ) { - PORT_Free(fpstr); - } - if (DSSPriv) { - PORT_Free(DSSPriv); - } - - if (KMID) { - PORT_Free(KMID); - } - - if ( commentstring ) { - PORT_Free(commentstring); - } - - if ( servername ) { - PORT_Free(servername); - } - - return(ret); -} - diff --git a/security/nss/lib/certhigh/certreq.c b/security/nss/lib/certhigh/certreq.c deleted file mode 100644 index 1588c1896..000000000 --- a/security/nss/lib/certhigh/certreq.c +++ /dev/null @@ -1,230 +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 "secder.h" -#include "key.h" -#include "secitem.h" -#include "secasn1.h" - -const SEC_ASN1Template CERT_AttributeTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTAttribute) }, - { SEC_ASN1_OBJECT_ID, offsetof(CERTAttribute, attrType) }, - { SEC_ASN1_SET_OF, offsetof(CERTAttribute, attrValue), - SEC_AnyTemplate }, - { 0 } -}; - -const SEC_ASN1Template CERT_SetOfAttributeTemplate[] = { - { SEC_ASN1_SET_OF, 0, CERT_AttributeTemplate }, -}; - -const SEC_ASN1Template CERT_CertificateRequestTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertificateRequest) }, - { SEC_ASN1_INTEGER, - offsetof(CERTCertificateRequest,version) }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificateRequest,subject), - CERT_NameTemplate }, - { SEC_ASN1_INLINE, - offsetof(CERTCertificateRequest,subjectPublicKeyInfo), - CERT_SubjectPublicKeyInfoTemplate }, - { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTCertificateRequest,attributes), - CERT_SetOfAttributeTemplate }, - { 0 } -}; - -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CertificateRequestTemplate) - -CERTCertificate * -CERT_CreateCertificate(unsigned long serialNumber, - CERTName *issuer, - CERTValidity *validity, - CERTCertificateRequest *req) -{ - CERTCertificate *c; - int rv; - PRArenaPool *arena; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !arena ) { - return(0); - } - - c = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate)); - - if (c) { - c->referenceCount = 1; - c->arena = arena; - - /* - * Default is a plain version 1. - * If extensions are added, it will get changed as appropriate. - */ - rv = DER_SetUInteger(arena, &c->version, SEC_CERTIFICATE_VERSION_1); - if (rv) goto loser; - - rv = DER_SetUInteger(arena, &c->serialNumber, serialNumber); - if (rv) goto loser; - - rv = CERT_CopyName(arena, &c->issuer, issuer); - if (rv) goto loser; - - rv = CERT_CopyValidity(arena, &c->validity, validity); - if (rv) goto loser; - - rv = CERT_CopyName(arena, &c->subject, &req->subject); - if (rv) goto loser; - rv = SECKEY_CopySubjectPublicKeyInfo(arena, &c->subjectPublicKeyInfo, - &req->subjectPublicKeyInfo); - if (rv) goto loser; - } - return c; - - loser: - CERT_DestroyCertificate(c); - return 0; -} - -/************************************************************************/ - -CERTCertificateRequest * -CERT_CreateCertificateRequest(CERTName *subject, - CERTSubjectPublicKeyInfo *spki, - SECItem **attributes) -{ - CERTCertificateRequest *certreq; - PRArenaPool *arena; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return NULL; - } - - certreq = (CERTCertificateRequest *) - PORT_ArenaZAlloc(arena, sizeof(CERTCertificateRequest)); - - if (certreq != NULL) { - certreq->arena = arena; - - rv = DER_SetUInteger(arena, &certreq->version, - SEC_CERTIFICATE_REQUEST_VERSION); - if (rv != SECSuccess) - goto loser; - - rv = CERT_CopyName(arena, &certreq->subject, subject); - if (rv != SECSuccess) - goto loser; - - rv = SECKEY_CopySubjectPublicKeyInfo(arena, - &certreq->subjectPublicKeyInfo, - spki); - if (rv != SECSuccess) - goto loser; - - /* Copy over attribute information */ - if (attributes) { - int i = 0; - - /* allocate space for attributes */ - while(attributes[i] != NULL) i++; - certreq->attributes = (SECItem**)PORT_ArenaZAlloc(arena, - sizeof(SECItem *) * (i + 1)); - if(!certreq->attributes) { - goto loser; - } - - /* copy attributes */ - i = 0; - while(attributes[i]) { - /* - ** Attributes are a SetOf Attribute which implies - ** lexigraphical ordering. It is assumes that the - ** attributes are passed in sorted. If we need to - ** add functionality to sort them, there is an - ** example in the PKCS 7 code. - */ - certreq->attributes[i] = (SECItem*)PORT_ArenaZAlloc(arena, - sizeof(SECItem)); - if(!certreq->attributes[i]) { - goto loser; - }; - rv = SECITEM_CopyItem(arena, certreq->attributes[i], - attributes[i]); - if (rv != SECSuccess) { - goto loser; - } - i++; - } - certreq->attributes[i] = NULL; - } else { - /* - ** Invent empty attribute information. According to the - ** pkcs#10 spec, attributes has this ASN.1 type: - ** - ** attributes [0] IMPLICIT Attributes - ** - ** Which means, we should create a NULL terminated list - ** with the first entry being NULL; - */ - certreq->attributes = (SECItem**)PORT_ArenaZAlloc(arena, sizeof(SECItem *)); - if(!certreq->attributes) { - goto loser; - } - certreq->attributes[0] = NULL; - } - } else { - PORT_FreeArena(arena, PR_FALSE); - } - - return certreq; - -loser: - CERT_DestroyCertificateRequest(certreq); - return NULL; -} - -void -CERT_DestroyCertificateRequest(CERTCertificateRequest *req) -{ - if (req && req->arena) { - PORT_FreeArena(req->arena, PR_FALSE); - } - return; -} - diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c deleted file mode 100644 index 0b303eb97..000000000 --- a/security/nss/lib/certhigh/certvfy.c +++ /dev/null @@ -1,2112 +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 "nspr.h" -#include "secerr.h" -#include "secport.h" -#include "seccomon.h" -#include "secoid.h" -#include "sslerr.h" -#include "genname.h" -#include "keyhi.h" -#include "cert.h" -#include "certdb.h" -#include "cryptohi.h" - -#ifndef NSS_3_4_CODE -#define NSS_3_4_CODE -#endif /* NSS_3_4_CODE */ -#include "nsspki.h" -#include "pkitm.h" -#include "pkim.h" -#include "pki3hack.h" -#include "base.h" - -#define PENDING_SLOP (24L*60L*60L) - -/* - * WARNING - this function is depricated, and will go away in the near future. - * It has been superseded by CERT_CheckCertValidTimes(). - * - * Check the validity times of a certificate - */ -SECStatus -CERT_CertTimesValid(CERTCertificate *c) -{ - int64 now, notBefore, notAfter, pendingSlop; - SECStatus rv; - - /* if cert is already marked OK, then don't bother to check */ - if ( c->timeOK ) { - return(SECSuccess); - } - - /* get current UTC time */ - now = PR_Now(); - rv = CERT_GetCertTimes(c, ¬Before, ¬After); - - if (rv) { - return(SECFailure); - } - - LL_I2L(pendingSlop, PENDING_SLOP); - LL_SUB(notBefore, notBefore, pendingSlop); - - if (LL_CMP(now, <, notBefore) || LL_CMP(now, >, notAfter)) { - PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE); - return(SECFailure); - } - - return(SECSuccess); -} - -/* - * verify the signature of a signed data object with the given certificate - */ -SECStatus -CERT_VerifySignedData(CERTSignedData *sd, CERTCertificate *cert, - int64 t, void *wincx) -{ - SECItem sig; - SECKEYPublicKey *pubKey = 0; - SECStatus rv; - SECCertTimeValidity validity; - SECOidTag algid; - - /* check the certificate's validity */ - validity = CERT_CheckCertValidTimes(cert, t, PR_FALSE); - if ( validity != secCertTimeValid ) { - return(SECFailure); - } - - /* get cert's public key */ - pubKey = CERT_ExtractPublicKey(cert); - if ( !pubKey ) { - return(SECFailure); - } - - /* check the signature */ - sig = sd->signature; - DER_ConvertBitString(&sig); - - algid = SECOID_GetAlgorithmTag(&sd->signatureAlgorithm); - rv = VFY_VerifyData(sd->data.data, sd->data.len, pubKey, &sig, - algid, wincx); - - SECKEY_DestroyPublicKey(pubKey); - - if ( rv ) { - return(SECFailure); - } - - return(SECSuccess); -} - - -/* - * This must only be called on a cert that is known to have an issuer - * with an invalid time - */ -CERTCertificate * -CERT_FindExpiredIssuer(CERTCertDBHandle *handle, CERTCertificate *cert) -{ - CERTCertificate *issuerCert = NULL; - CERTCertificate *subjectCert; - int count; - SECStatus rv; - SECComparison rvCompare; - - subjectCert = CERT_DupCertificate(cert); - if ( subjectCert == NULL ) { - goto loser; - } - - for ( count = 0; count < CERT_MAX_CERT_CHAIN; count++ ) { - /* find the certificate of the issuer */ - issuerCert = CERT_FindCertByName(handle, &subjectCert->derIssuer); - - if ( ! issuerCert ) { - goto loser; - } - - rv = CERT_CertTimesValid(issuerCert); - if ( rv == SECFailure ) { - /* this is the invalid issuer */ - CERT_DestroyCertificate(subjectCert); - return(issuerCert); - } - - /* make sure that the issuer is not self signed. If it is, then - * stop here to prevent looping. - */ - rvCompare = SECITEM_CompareItem(&issuerCert->derSubject, - &issuerCert->derIssuer); - if (rvCompare == SECEqual) { - PORT_Assert(0); /* No expired issuer! */ - goto loser; - } - CERT_DestroyCertificate(subjectCert); - subjectCert = issuerCert; - } - -loser: - if ( issuerCert ) { - CERT_DestroyCertificate(issuerCert); - } - - if ( subjectCert ) { - CERT_DestroyCertificate(subjectCert); - } - - return(NULL); -} - -/* Software FORTEZZA installation hack. The software fortezza installer does - * not have access to the krl and cert.db file. Accept FORTEZZA Certs without - * KRL's in this case. - */ -static int dont_use_krl = 0; -/* not a public exposed function... */ -void sec_SetCheckKRLState(int value) { dont_use_krl = value; } - -SECStatus -SEC_CheckKRL(CERTCertDBHandle *handle,SECKEYPublicKey *key, - CERTCertificate *rootCert, int64 t, void * wincx) -{ - CERTSignedCrl *crl = NULL; - SECStatus rv = SECFailure; - SECStatus rv2; - CERTCrlEntry **crlEntry; - SECCertTimeValidity validity; - CERTCertificate *issuerCert = NULL; - - if (dont_use_krl) return SECSuccess; - - /* first look up the KRL */ - crl = SEC_FindCrlByName(handle,&rootCert->derSubject, SEC_KRL_TYPE); - if (crl == NULL) { - PORT_SetError(SEC_ERROR_NO_KRL); - goto done; - } - - /* get the issuing certificate */ - issuerCert = CERT_FindCertByName(handle, &crl->crl.derName); - if (issuerCert == NULL) { - PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE); - goto done; - } - - - /* now verify the KRL signature */ - rv2 = CERT_VerifySignedData(&crl->signatureWrap, issuerCert, t, wincx); - if (rv2 != SECSuccess) { - PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE); - goto done; - } - - /* Verify the date validity of the KRL */ - validity = SEC_CheckCrlTimes(&crl->crl, t); - if (validity == secCertTimeExpired) { - PORT_SetError(SEC_ERROR_KRL_EXPIRED); - goto done; - } - - /* now make sure the key in this cert is still valid */ - if (key->keyType != fortezzaKey) { - PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN); - goto done; /* This should be an assert? */ - } - - /* now make sure the key is not on the revocation list */ - for (crlEntry = crl->crl.entries; crlEntry && *crlEntry; crlEntry++) { - if (PORT_Memcmp((*crlEntry)->serialNumber.data, - key->u.fortezza.KMID, - (*crlEntry)->serialNumber.len) == 0) { - PORT_SetError(SEC_ERROR_REVOKED_KEY); - goto done; - } - } - rv = SECSuccess; - -done: - if (issuerCert) CERT_DestroyCertificate(issuerCert); - if (crl) SEC_DestroyCrl(crl); - return rv; -} - -SECStatus -SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, - CERTCertificate *caCert, int64 t, void * wincx) -{ - CERTSignedCrl *crl = NULL; - SECStatus rv = SECSuccess; - CERTCrlEntry **crlEntry; - - /* first look up the CRL */ - crl = SEC_FindCrlByName(handle,&caCert->derSubject, SEC_CRL_TYPE); - if (crl == NULL) { - /* XXX for now no CRL is ok */ - goto done; - } - - /* now verify the CRL signature */ - rv = CERT_VerifySignedData(&crl->signatureWrap, caCert, t, wincx); - if (rv != SECSuccess) { - PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE); - rv = SECWouldBlock; /* Soft error, ask the user */ - goto done; - } - - /* now make sure the key is not on the revocation list */ - for (crlEntry = crl->crl.entries; crlEntry && *crlEntry; crlEntry++) { - if (SECITEM_CompareItem(&(*crlEntry)->serialNumber,&cert->serialNumber) == SECEqual) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - rv = SECFailure; /* cert is revoked */ - goto done; - } - } - -done: - if (crl) SEC_DestroyCrl(crl); - return rv; -} - -/* - * Find the issuer of a cert. Use the authorityKeyID if it exists. - */ -CERTCertificate * -CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage) -{ -#ifdef NSS_CLASSIC - CERTAuthKeyID * authorityKeyID = NULL; - CERTCertificate * issuerCert = NULL; - SECItem * caName; - PRArenaPool *tmpArena = NULL; - - tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - - if ( !tmpArena ) { - goto loser; - } - authorityKeyID = CERT_FindAuthKeyIDExten(tmpArena,cert); - - if ( authorityKeyID != NULL ) { - /* has the authority key ID extension */ - if ( authorityKeyID->keyID.data != NULL ) { - /* extension contains a key ID, so lookup based on it */ - issuerCert = CERT_FindCertByKeyID(cert->dbhandle, &cert->derIssuer, - &authorityKeyID->keyID); - if ( issuerCert == NULL ) { - PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); - goto loser; - } - - } else if ( authorityKeyID->authCertIssuer != NULL ) { - /* no key ID, so try issuer and serial number */ - caName = (SECItem*)CERT_GetGeneralNameByType(authorityKeyID->authCertIssuer, - certDirectoryName, PR_TRUE); - - /* - * caName is NULL when the authCertIssuer field is not - * being used, or other name form is used instead. - * If the directoryName format and serialNumber fields are - * used, we use them to find the CA cert. - * Note: - * By the time it gets here, we known for sure that if the - * authCertIssuer exists, then the authCertSerialNumber - * must also exists (CERT_DecodeAuthKeyID() ensures this). - * We don't need to check again. - */ - - if (caName != NULL) { - CERTIssuerAndSN issuerSN; - - issuerSN.derIssuer.data = caName->data; - issuerSN.derIssuer.len = caName->len; - issuerSN.serialNumber.data = - authorityKeyID->authCertSerialNumber.data; - issuerSN.serialNumber.len = - authorityKeyID->authCertSerialNumber.len; - issuerCert = CERT_FindCertByIssuerAndSN(cert->dbhandle, - &issuerSN); - if ( issuerCert == NULL ) { - PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); - goto loser; - } - } - } - } - if ( issuerCert == NULL ) { - /* if there is not authorityKeyID, then try to find the issuer */ - /* find a valid CA cert with correct usage */ - issuerCert = CERT_FindMatchingCert(cert->dbhandle, - &cert->derIssuer, - certOwnerCA, usage, PR_TRUE, - validTime, PR_TRUE); - - /* if that fails, then fall back to grabbing any cert with right name*/ - if ( issuerCert == NULL ) { - issuerCert = CERT_FindCertByName(cert->dbhandle, &cert->derIssuer); - if ( issuerCert == NULL ) { - PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); - } - } - } - -loser: - if (tmpArena != NULL) { - PORT_FreeArena(tmpArena, PR_FALSE); - tmpArena = NULL; - } - - return(issuerCert); -#else - NSSCertificate *me; - NSSTime *nssTime; - NSSUsage nssUsage; - NSSCertificate *chain[3]; - PRStatus status; - me = STAN_GetNSSCertificate(cert); - nssTime = NSSTime_SetPRTime(NULL, validTime); - nssUsage.anyUsage = PR_FALSE; - nssUsage.nss3usage = usage; - nssUsage.nss3lookingForCA = PR_TRUE; - memset(chain, 0, 3*sizeof(NSSCertificate *)); - if (!me) { - PORT_SetError (SEC_ERROR_BAD_DATABASE); - return NULL; - } - (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL, - chain, 2, NULL, &status); - nss_ZFreeIf(nssTime); - if (status == PR_SUCCESS) { - /* if it's a root, the chain will only have one cert */ - if (!chain[1]) { - /* already has a reference from the call to BuildChain */ - return cert; - } else { - CERT_DestroyCertificate(cert); /* the first cert in the chain */ - return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ - } - } else { - PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); - } - return NULL; -#endif -} - -/* - * return required trust flags for various cert usages for CAs - */ -SECStatus -CERT_TrustFlagsForCACertUsage(SECCertUsage usage, - unsigned int *retFlags, - SECTrustType *retTrustType) -{ - unsigned int requiredFlags; - SECTrustType trustType; - - switch ( usage ) { - case certUsageSSLClient: - requiredFlags = CERTDB_TRUSTED_CLIENT_CA; - trustType = trustSSL; - break; - case certUsageSSLServer: - case certUsageSSLCA: - requiredFlags = CERTDB_TRUSTED_CA; - trustType = trustSSL; - break; - case certUsageSSLServerWithStepUp: - requiredFlags = CERTDB_TRUSTED_CA | CERTDB_GOVT_APPROVED_CA; - trustType = trustSSL; - break; - case certUsageEmailSigner: - case certUsageEmailRecipient: - requiredFlags = CERTDB_TRUSTED_CA; - trustType = trustEmail; - break; - case certUsageObjectSigner: - requiredFlags = CERTDB_TRUSTED_CA; - trustType = trustObjectSigning; - break; - case certUsageVerifyCA: - case certUsageAnyCA: - case certUsageStatusResponder: - requiredFlags = CERTDB_TRUSTED_CA; - trustType = trustTypeNone; - break; - default: - PORT_Assert(0); - goto loser; - } - if ( retFlags != NULL ) { - *retFlags = requiredFlags; - } - if ( retTrustType != NULL ) { - *retTrustType = trustType; - } - - return(SECSuccess); -loser: - return(SECFailure); -} - - - - - -static void -AddToVerifyLog(CERTVerifyLog *log, CERTCertificate *cert, unsigned long error, - unsigned int depth, void *arg) -{ - CERTVerifyLogNode *node, *tnode; - - PORT_Assert(log != NULL); - - node = (CERTVerifyLogNode *)PORT_ArenaAlloc(log->arena, - sizeof(CERTVerifyLogNode)); - if ( node != NULL ) { - node->cert = CERT_DupCertificate(cert); - node->error = error; - node->depth = depth; - node->arg = arg; - - if ( log->tail == NULL ) { - /* empty list */ - log->head = log->tail = node; - node->prev = NULL; - node->next = NULL; - } else if ( depth >= log->tail->depth ) { - /* add to tail */ - node->prev = log->tail; - log->tail->next = node; - log->tail = node; - node->next = NULL; - } else if ( depth < log->head->depth ) { - /* add at head */ - node->prev = NULL; - node->next = log->head; - log->head->prev = node; - log->head = node; - } else { - /* add in middle */ - tnode = log->tail; - while ( tnode != NULL ) { - if ( depth >= tnode->depth ) { - /* insert after tnode */ - node->prev = tnode; - node->next = tnode->next; - tnode->next->prev = node; - tnode->next = node; - break; - } - - tnode = tnode->prev; - } - } - - log->count++; - } - return; -} - -#define EXIT_IF_NOT_LOGGING(log) \ - if ( log == NULL ) { \ - goto loser; \ - } - -#define LOG_ERROR_OR_EXIT(log,cert,depth,arg) \ - if ( log != NULL ) { \ - AddToVerifyLog(log, cert, PORT_GetError(), depth, (void *)arg); \ - } else { \ - goto loser; \ - } - -#define LOG_ERROR(log,cert,depth,arg) \ - if ( log != NULL ) { \ - AddToVerifyLog(log, cert, PORT_GetError(), depth, (void *)arg); \ - } - - -typedef enum { cbd_None, cbd_User, cbd_CA } cbd_FortezzaType; - -static SECStatus -cert_VerifyFortezzaV1Cert(CERTCertDBHandle *handle, CERTCertificate *cert, - cbd_FortezzaType *next_type, cbd_FortezzaType last_type, - int64 t, void *wincx) -{ - unsigned char priv = 0; - SECKEYPublicKey *key; - SECStatus rv; - - *next_type = cbd_CA; - - /* read the key */ - key = CERT_ExtractPublicKey(cert); - - /* Cant' get Key? fail. */ - if (key == NULL) { - PORT_SetError(SEC_ERROR_BAD_KEY); - return SECFailure; - } - - - /* if the issuer is not an old fortezza cert, we bail */ - if (key->keyType != fortezzaKey) { - SECKEY_DestroyPublicKey(key); - /* CA Cert not fortezza */ - PORT_SetError(SEC_ERROR_NOT_FORTEZZA_ISSUER); - return SECFailure; - } - - /* get the privilege mask */ - if (key->u.fortezza.DSSpriviledge.len > 0) { - priv = key->u.fortezza.DSSpriviledge.data[0]; - } - - /* - * make sure the CA's keys are OK - */ - - rv = SEC_CheckKRL(handle, key, NULL, t, wincx); - SECKEY_DestroyPublicKey(key); - if (rv != SECSuccess) { - return rv; - } - - switch (last_type) { - case cbd_User: - /* first check for subordination */ - /*rv = FortezzaSubordinateCheck(cert,issuerCert);*/ - rv = SECSuccess; - - /* now check for issuer privilege */ - if ((rv != SECSuccess) || ((priv & 0x10) == 0)) { - /* bail */ - PORT_SetError (SEC_ERROR_CA_CERT_INVALID); - return SECFailure; - } - break; - case cbd_CA: - if ((priv & 0x20) == 0) { - /* bail */ - PORT_SetError (SEC_ERROR_CA_CERT_INVALID); - return SECFailure; - } - break; - case cbd_None: - *next_type = (priv & 0x30) ? cbd_CA : cbd_User; - break; - default: - /* bail */ /* shouldn't ever happen */ - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - return SECFailure; - } - return SECSuccess; -} - - -static SECStatus -cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, PRBool* sigerror, - SECCertUsage certUsage, int64 t, void *wincx, - CERTVerifyLog *log, PRBool doCRL, PRBool* revoked) -{ - SECTrustType trustType; - CERTBasicConstraints basicConstraint; - CERTCertificate *issuerCert = NULL; - CERTCertificate *subjectCert = NULL; - CERTCertificate *badCert = NULL; - PRBool isca; - PRBool isFortezzaV1 = PR_FALSE; - SECStatus rv; - SECComparison rvCompare; - SECStatus rvFinal = SECSuccess; - int count; - int currentPathLen = -1; - int flags; - unsigned int caCertType; - unsigned int requiredCAKeyUsage; - unsigned int requiredFlags; - PRArenaPool *arena = NULL; - CERTGeneralName *namesList = NULL; - CERTGeneralName *subjectNameList = NULL; - SECItem *namesIndex = NULL; - int namesIndexLen = 10; - int namesCount = 0; - - cbd_FortezzaType last_type = cbd_None; - - if (revoked) { - *revoked = PR_FALSE; - } - - if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, - &requiredCAKeyUsage, - &caCertType) - != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredCAKeyUsage = 0; - caCertType = 0; - } - - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - case certUsageSSLCA: - case certUsageSSLServerWithStepUp: - case certUsageEmailSigner: - case certUsageEmailRecipient: - case certUsageObjectSigner: - case certUsageVerifyCA: - case certUsageStatusResponder: - if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, - &trustType) != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredFlags = 0; - trustType = trustSSL; - } - break; - default: - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredFlags = 0; - trustType = trustSSL;/* This used to be 0, but we need something - * that matches the enumeration type. - */ - caCertType = 0; - } - - subjectCert = CERT_DupCertificate(cert); - if ( subjectCert == NULL ) { - goto loser; - } - - /* determine if the cert is fortezza. - */ - isFortezzaV1 = (PRBool) - (CERT_GetCertKeyType(&subjectCert->subjectPublicKeyInfo) - == fortezzaKey); - - if (isFortezzaV1) { - rv = cert_VerifyFortezzaV1Cert(handle, subjectCert, &last_type, - cbd_None, t, wincx); - if (rv == SECFailure) { - /**** PORT_SetError is already set by cert_VerifyFortezzaV1Cert **/ - LOG_ERROR_OR_EXIT(log,subjectCert,0,0); - } - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto loser; - } - - namesIndex = (SECItem *) PORT_ZAlloc(sizeof(SECItem) * namesIndexLen); - if (namesIndex == NULL) { - goto loser; - } - - for ( count = 0; count < CERT_MAX_CERT_CHAIN; count++ ) { - int subjectNameListLen; - int i; - - /* Construct a list of names for the current and all previous certifcates - to be verified against the name constraints extension of the issuer - certificate. */ - subjectNameList = CERT_GetCertificateNames(subjectCert, arena); - subjectNameListLen = CERT_GetNamesLength(subjectNameList); - for (i = 0; i < subjectNameListLen; i++) { - if (namesIndexLen <= namesCount + i) { - namesIndexLen = namesIndexLen * 2; - namesIndex = (SECItem *) PORT_Realloc(namesIndex, namesIndexLen * - sizeof(SECItem)); - if (namesIndex == NULL) { - goto loser; - } - } - rv = SECITEM_CopyItem(arena, &(namesIndex[namesCount + i]), &(subjectCert->derSubject)); - } - namesCount += subjectNameListLen; - namesList = cert_CombineNamesLists(namesList, subjectNameList); - - /* find the certificate of the issuer */ - issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage); - if ( ! issuerCert ) { - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - LOG_ERROR(log,subjectCert,count,0); - goto loser; - } - - /* verify the signature on the cert */ - if ( checkSig ) { - rv = CERT_VerifySignedData(&subjectCert->signatureWrap, - issuerCert, t, wincx); - - if ( rv != SECSuccess ) { - if (sigerror) { - *sigerror = PR_TRUE; - } - if ( PORT_GetError() == SEC_ERROR_EXPIRED_CERTIFICATE ) { - PORT_SetError(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } else { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - LOG_ERROR_OR_EXIT(log,subjectCert,count,0); - } - } - } - - /* - * XXX - fortezza may need error logging stuff added - */ - if (isFortezzaV1) { - rv = cert_VerifyFortezzaV1Cert(handle, issuerCert, &last_type, - last_type, t, wincx); - if (rv == SECFailure) { - /**** PORT_SetError is already set by * - * cert_VerifyFortezzaV1Cert **/ - LOG_ERROR_OR_EXIT(log,subjectCert,0,0); - } - } - - /* If the basicConstraint extension is included in an immediate CA - * certificate, make sure that the isCA flag is on. If the - * pathLenConstraint component exists, it must be greater than the - * number of CA certificates we have seen so far. If the extension - * is omitted, we will assume that this is a CA certificate with - * an unlimited pathLenConstraint (since it already passes the - * netscape-cert-type extension checking). - * - * In the fortezza (V1) case, we've already checked the CA bits - * in the key, so we're presumed to be a CA; however we really don't - * want to bypass Basic constraint or netscape extension parsing. - * - * In Fortezza V2, basicConstraint will be set for every CA,PCA,PAA - */ - - rv = CERT_FindBasicConstraintExten(issuerCert, &basicConstraint); - if ( rv != SECSuccess ) { - if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } else { - currentPathLen = CERT_UNLIMITED_PATH_CONSTRAINT; - } - /* no basic constraints found, if we're fortezza, CA bit is already - * verified (isca = PR_TRUE). otherwise, we aren't (yet) a ca - * isca = PR_FALSE */ - isca = isFortezzaV1; - } else { - if ( basicConstraint.isCA == PR_FALSE ) { - PORT_SetError (SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } - - /* make sure that the path len constraint is properly set. - */ - if ( basicConstraint.pathLenConstraint == - CERT_UNLIMITED_PATH_CONSTRAINT ) { - currentPathLen = CERT_UNLIMITED_PATH_CONSTRAINT; - } else if ( currentPathLen == CERT_UNLIMITED_PATH_CONSTRAINT ) { - /* error if the previous CA's path length constraint is - * unlimited but its CA's path is not. - */ - PORT_SetError (SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,basicConstraint.pathLenConstraint); - } else if (basicConstraint.pathLenConstraint > currentPathLen) { - currentPathLen = basicConstraint.pathLenConstraint; - } else { - PORT_SetError (SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,basicConstraint.pathLenConstraint); - } - - isca = PR_TRUE; - } - - /* XXX - the error logging may need to go down into CRL stuff at some - * point - */ - /* check revoked list (issuer) */ - if (PR_TRUE == doCRL) { - rv = SEC_CheckCRL(handle, subjectCert, issuerCert, t, wincx); - if (rv == SECFailure) { - if (revoked) { - *revoked = PR_TRUE; - } - LOG_ERROR_OR_EXIT(log,subjectCert,count,0); - } else if (rv == SECWouldBlock) { - /* We found something fishy, so we intend to issue an - * error to the user, but the user may wish to continue - * processing, in which case we better make sure nothing - * worse has happened... so keep cranking the loop */ - rvFinal = SECFailure; - if (revoked) { - *revoked = PR_TRUE; - } - LOG_ERROR(log,subjectCert,count,0); - } - } - - - if ( issuerCert->trust ) { - /* - * check the trust parms of the issuer - */ - if ( certUsage == certUsageVerifyCA ) { - if ( subjectCert->nsCertType & NS_CERT_TYPE_EMAIL_CA ) { - trustType = trustEmail; - } else if ( subjectCert->nsCertType & NS_CERT_TYPE_SSL_CA ) { - trustType = trustSSL; - } else { - trustType = trustObjectSigning; - } - } - - flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType); - - if ( (flags & CERTDB_VALID_CA) || - (certUsage == certUsageStatusResponder)) { - if ( ( flags & requiredFlags ) == requiredFlags || - certUsage == certUsageStatusResponder ) { - /* we found a trusted one, so return */ - rv = rvFinal; - goto done; - } - } - } - - /* - * Make sure that if this is an intermediate CA in the chain that - * it was given permission by its signer to be a CA. - */ - if ( isca ) { - /* - * if basicConstraints says it is a ca, then we check the - * nsCertType. If the nsCertType has any CA bits set, then - * it must have the right one. - */ - if ( issuerCert->nsCertType & NS_CERT_TYPE_CA ) { - if ( issuerCert->nsCertType & caCertType ) { - isca = PR_TRUE; - } else { - isca = PR_FALSE; - } - } - } else { - if ( issuerCert->nsCertType & caCertType ) { - isca = PR_TRUE; - } else { - isca = PR_FALSE; - } - } - - if ( !isca ) { - PORT_SetError(SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,0); - } - - /* make sure key usage allows cert signing */ - if (CERT_CheckKeyUsage(issuerCert, requiredCAKeyUsage) != SECSuccess) { - PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); - LOG_ERROR_OR_EXIT(log,issuerCert,count+1,requiredCAKeyUsage); - } - /* make sure that the entire chain is within the name space of the current issuer - * certificate. - */ - - badCert = CERT_CompareNameSpace(issuerCert, namesList, namesIndex, arena, handle); - if (badCert != NULL) { - PORT_SetError(SEC_ERROR_CERT_NOT_IN_NAME_SPACE); - LOG_ERROR_OR_EXIT(log, badCert, count + 1, 0); - goto loser; - } - /* make sure that the issuer is not self signed. If it is, then - * stop here to prevent looping. - */ - rvCompare = SECITEM_CompareItem(&issuerCert->derSubject, - &issuerCert->derIssuer); - if (rvCompare == SECEqual) { - PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); - LOG_ERROR(log, issuerCert, count+1, 0); - goto loser; - } - - CERT_DestroyCertificate(subjectCert); - subjectCert = issuerCert; - } - - subjectCert = NULL; - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - LOG_ERROR(log,issuerCert,count,0); -loser: - rv = SECFailure; -done: - if (namesIndex != NULL) { - PORT_Free(namesIndex); - } - if ( issuerCert ) { - CERT_DestroyCertificate(issuerCert); - } - - if ( subjectCert ) { - CERT_DestroyCertificate(subjectCert); - } - - if ( arena != NULL ) { - PORT_FreeArena(arena, PR_FALSE); - } - return rv; -} - -SECStatus -CERT_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, int64 t, - void *wincx, CERTVerifyLog *log) -{ - return cert_VerifyCertChain(handle, cert, checkSig, NULL, certUsage, t, - wincx, log, PR_TRUE, NULL); -} - -/* - * verify that a CA can sign a certificate with the requested usage. - */ -SECStatus -CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, int64 t, - void *wincx, CERTVerifyLog *log) -{ - SECTrustType trustType; - CERTBasicConstraints basicConstraint; - PRBool isca; - SECStatus rv; - SECComparison rvCompare; - SECStatus rvFinal = SECSuccess; - int flags; - unsigned int caCertType; - unsigned int requiredCAKeyUsage; - unsigned int requiredFlags; - CERTCertificate *issuerCert; - - - if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE, - &requiredCAKeyUsage, - &caCertType) != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredCAKeyUsage = 0; - caCertType = 0; - } - - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - case certUsageSSLCA: - case certUsageSSLServerWithStepUp: - case certUsageEmailSigner: - case certUsageEmailRecipient: - case certUsageObjectSigner: - case certUsageVerifyCA: - case certUsageStatusResponder: - if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags, - &trustType) != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredFlags = 0; - trustType = trustSSL; - } - break; - default: - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredFlags = 0; - trustType = trustSSL;/* This used to be 0, but we need something - * that matches the enumeration type. - */ - caCertType = 0; - } - - /* If the basicConstraint extension is included in an immediate CA - * certificate, make sure that the isCA flag is on. If the - * pathLenConstraint component exists, it must be greater than the - * number of CA certificates we have seen so far. If the extension - * is omitted, we will assume that this is a CA certificate with - * an unlimited pathLenConstraint (since it already passes the - * netscape-cert-type extension checking). - * - * In the fortezza (V1) case, we've already checked the CA bits - * in the key, so we're presumed to be a CA; however we really don't - * want to bypass Basic constraint or netscape extension parsing. - * - * In Fortezza V2, basicConstraint will be set for every CA,PCA,PAA - */ - - rv = CERT_FindBasicConstraintExten(cert, &basicConstraint); - if ( rv != SECSuccess ) { - if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) { - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - /* no basic constraints found, if we're fortezza, CA bit is already - * verified (isca = PR_TRUE). otherwise, we aren't (yet) a ca - * isca = PR_FALSE */ - isca = PR_FALSE; - } else { - if ( basicConstraint.isCA == PR_FALSE ) { - PORT_SetError (SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - - /* can't check path length if we don't know the previous path */ - isca = PR_TRUE; - } - - if ( cert->trust ) { - /* - * check the trust parms of the issuer - */ - flags = SEC_GET_TRUST_FLAGS(cert->trust, trustType); - - if ( (flags & CERTDB_VALID_CA) || - (certUsage == certUsageStatusResponder)) { - if ( ( flags & requiredFlags ) == requiredFlags || - certUsage == certUsageStatusResponder ) { - /* we found a trusted one, so return */ - /* Check the special case of certUsageStatusResponder */ - if(certUsage == certUsageStatusResponder) { - issuerCert = CERT_FindCertIssuer(cert, t, certUsage); - if (issuerCert) { - if(SEC_CheckCRL(handle, cert, issuerCert, t, wincx) != SECSuccess) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - CERT_DestroyCertificate(issuerCert); - goto loser; - } - CERT_DestroyCertificate(issuerCert); - } - } - rv = rvFinal; - goto done; - } - } - } - - /* - * Make sure that if this is an intermediate CA in the chain that - * it was given permission by its signer to be a CA. - */ - if ( isca ) { - /* - * if basicConstraints says it is a ca, then we check the - * nsCertType. If the nsCertType has any CA bits set, then - * it must have the right one. - */ - if ( cert->nsCertType & NS_CERT_TYPE_CA ) { - if ( cert->nsCertType & caCertType ) { - isca = PR_TRUE; - } else { - isca = PR_FALSE; - } - } - } else { - if ( cert->nsCertType & caCertType ) { - isca = PR_TRUE; - } else { - isca = PR_FALSE; - } - } - - if ( !isca ) { - PORT_SetError(SEC_ERROR_CA_CERT_INVALID); - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - - /* make sure key usage allows cert signing */ - if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) { - PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); - LOG_ERROR_OR_EXIT(log,cert,0,requiredCAKeyUsage); - } - /* make sure that the issuer is not self signed. If it is, then - * stop here to prevent looping. - */ - rvCompare = SECITEM_CompareItem(&cert->derSubject, - &cert->derIssuer); - if (rvCompare == SECEqual) { - PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER); - LOG_ERROR(log, cert, 0, 0); - goto loser; - } - - return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t, - wincx, log); -loser: - rv = SECFailure; -done: - return rv; -} - -#define NEXT_ITERATION() { \ - i*=2; \ - certUsage++; \ - continue; \ -} - -#define VALID_USAGE() { \ - NEXT_ITERATION(); \ -} - -#define INVALID_USAGE() { \ - if (returnedUsages) { \ - *returnedUsages &= (~i); \ - } \ - if (PR_TRUE == requiredUsage) { \ - valid = SECFailure; \ - } \ - NEXT_ITERATION(); \ -} - -/* - * verify a certificate by checking if it's valid and that we - * trust the issuer. - * - * certificateUsage contains a bitfield of all cert usages that are - * required for verification to succeed - * - * a bitfield of cert usages is returned in *returnedUsages - * if requiredUsages is non-zero, the returned bitmap is only - * for those required usages, otherwise it is for all usages - * - */ -SECStatus -CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertificateUsage requiredUsages, int64 t, - void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUsages) -{ - SECStatus rv; - SECStatus valid; - unsigned int requiredKeyUsage; - unsigned int requiredCertType; - unsigned int flags; - unsigned int certType; - PRBool allowOverride; - SECCertTimeValidity validity; - CERTStatusConfig *statusConfig; - PRBool checkedChain = PR_FALSE; - PRInt32 i; - SECCertUsage certUsage = 0; - PRBool doOCSP = PR_FALSE; - PRBool checkedCRL = PR_FALSE; - PRBool checkedOCSP = PR_FALSE; - PRBool checkAllUsages = PR_FALSE; - PRBool revoked = PR_FALSE; - PRBool sigerror = PR_FALSE; - - if (!requiredUsages) { - /* there are no required usages, so the user probably wants to - get status for all usages */ - checkAllUsages = PR_TRUE; - } - - if (returnedUsages) { - *returnedUsages = 0; - } else { - /* we don't have a place to return status for all usages, - so we can skip checks for usages that aren't required */ - checkAllUsages = PR_FALSE; - } - valid = SECSuccess ; /* start off assuming cert is valid */ - -#ifdef notdef - /* check if this cert is in the Evil list */ - rv = CERT_CheckForEvilCert(cert); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - LOG_ERROR(log,cert,0,0); - return SECFailure; - } -#endif - - /* make sure that the cert is valid at time t */ - allowOverride = (PRBool)((requiredUsages & certUsageSSLServer) || - (requiredUsages & certificateUsageSSLServerWithStepUp)); - validity = CERT_CheckCertValidTimes(cert, t, allowOverride); - if ( validity != secCertTimeValid ) { - LOG_ERROR(log,cert,0,validity); - return SECFailure; - } - - /* check key usage and netscape cert type */ - CERT_GetCertType(cert); - certType = cert->nsCertType; - - for (i=1;i<=highestUsage && !(SECFailure == valid && !returnedUsages) ;) { - PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; - if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { - NEXT_ITERATION(); - } - if (returnedUsages) { - *returnedUsages |= i; /* start off assuming this usage is valid */ - } - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - case certUsageSSLServerWithStepUp: - case certUsageSSLCA: - case certUsageEmailSigner: - case certUsageEmailRecipient: - case certUsageObjectSigner: - case certUsageStatusResponder: - rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, - &requiredKeyUsage, - &requiredCertType); - if ( rv != SECSuccess ) { - PORT_Assert(0); - /* EXIT_IF_NOT_LOGGING(log); XXX ??? */ - requiredKeyUsage = 0; - requiredCertType = 0; - INVALID_USAGE(); - } - break; - - case certUsageAnyCA: - case certUsageProtectedObjectSigner: - case certUsageUserCertImport: - case certUsageVerifyCA: - /* these usages cannot be verified */ - NEXT_ITERATION(); - - default: - PORT_Assert(0); - requiredKeyUsage = 0; - requiredCertType = 0; - INVALID_USAGE(); - } - if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) { - if (PR_TRUE == requiredUsage) { - PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); - } - LOG_ERROR(log,cert,0,requiredKeyUsage); - INVALID_USAGE(); - } - if ( !( certType & requiredCertType ) ) { - if (PR_TRUE == requiredUsage) { - PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); - } - LOG_ERROR(log,cert,0,requiredCertType); - INVALID_USAGE(); - } - - /* check trust flags to see if this cert is directly trusted */ - if ( cert->trust ) { /* the cert is in the DB */ - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - flags = cert->trust->sslFlags; - - /* is the cert directly trusted or not trusted ? */ - if ( flags & CERTDB_VALID_PEER ) {/*the trust record is valid*/ - if ( flags & CERTDB_TRUSTED ) { /* trust this cert */ - VALID_USAGE(); - } else { /* don't trust this cert */ - if (PR_TRUE == requiredUsage) { - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - } - LOG_ERROR(log,cert,0,flags); - INVALID_USAGE(); - } - } - break; - case certUsageSSLServerWithStepUp: - /* XXX - step up certs can't be directly trusted */ - break; - case certUsageSSLCA: - break; - case certUsageEmailSigner: - case certUsageEmailRecipient: - flags = cert->trust->emailFlags; - - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_PEER | CERTDB_TRUSTED ) ) == - ( CERTDB_VALID_PEER | CERTDB_TRUSTED ) ) { - VALID_USAGE(); - } - break; - case certUsageObjectSigner: - flags = cert->trust->objectSigningFlags; - - /* is the cert directly trusted or not trusted ? */ - if ( flags & CERTDB_VALID_PEER ) {/*the trust record is valid*/ - if ( flags & CERTDB_TRUSTED ) { /* trust this cert */ - VALID_USAGE(); - } else { /* don't trust this cert */ - if (PR_TRUE == requiredUsage) { - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - } - LOG_ERROR(log,cert,0,flags); - INVALID_USAGE(); - } - } - break; - case certUsageVerifyCA: - case certUsageStatusResponder: - flags = cert->trust->sslFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - VALID_USAGE(); - } - flags = cert->trust->emailFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - VALID_USAGE(); - } - flags = cert->trust->objectSigningFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - VALID_USAGE(); - } - break; - case certUsageAnyCA: - case certUsageProtectedObjectSigner: - case certUsageUserCertImport: - /* XXX to make the compiler happy. Should these be - * explicitly handled? - */ - break; - } - } - - if (PR_TRUE == revoked || PR_TRUE == sigerror) { - INVALID_USAGE(); - } - - /* only check CRL and signature for the first usage check */ - rv = cert_VerifyCertChain(handle, cert, - (PR_TRUE == checkedChain) ? PR_FALSE : checkSig, &sigerror, - certUsage, t, wincx, log, - (PR_TRUE == checkedChain) ? PR_FALSE : PR_TRUE, &revoked); - checkedChain = PR_TRUE; - - if (rv != SECSuccess) { - /* EXIT_IF_NOT_LOGGING(log); XXX ???? */ - INVALID_USAGE(); - } - - /* - * Check OCSP revocation status, but only if the cert we are checking - * is not a status reponder itself. We only do this in the case - * where we checked the cert chain (above); explicit trust "wins" - * (avoids status checking, just as it avoids CRL checking) by - * bypassing this code. - */ - - if (PR_FALSE == checkedOCSP) { - checkedOCSP = PR_TRUE; /* only check OCSP once */ - statusConfig = CERT_GetStatusConfig(handle); - if ( (! (requiredUsages & certificateUsageStatusResponder)) && - statusConfig != NULL) { - if (statusConfig->statusChecker != NULL) { - rv = (* statusConfig->statusChecker)(handle, cert, - t, wincx); - if (rv != SECSuccess) { - LOG_ERROR(log,cert,0,0); - revoked = PR_TRUE; - INVALID_USAGE(); - } - } - } - } - - NEXT_ITERATION(); - } - - return(valid); -} - -/* obsolete, do not use for new code */ -SECStatus -CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, int64 t, - void *wincx, CERTVerifyLog *log) -{ - SECStatus rv; - unsigned int requiredKeyUsage; - unsigned int requiredCertType; - unsigned int flags; - unsigned int certType; - PRBool allowOverride; - SECCertTimeValidity validity; - CERTStatusConfig *statusConfig; - -#ifdef notdef - /* check if this cert is in the Evil list */ - rv = CERT_CheckForEvilCert(cert); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - LOG_ERROR_OR_EXIT(log,cert,0,0); - } -#endif - - /* make sure that the cert is valid at time t */ - allowOverride = (PRBool)((certUsage == certUsageSSLServer) || - (certUsage == certUsageSSLServerWithStepUp)); - validity = CERT_CheckCertValidTimes(cert, t, allowOverride); - if ( validity != secCertTimeValid ) { - LOG_ERROR_OR_EXIT(log,cert,0,validity); - } - - /* check key usage and netscape cert type */ - CERT_GetCertType(cert); - certType = cert->nsCertType; - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - case certUsageSSLServerWithStepUp: - case certUsageSSLCA: - case certUsageEmailSigner: - case certUsageEmailRecipient: - case certUsageObjectSigner: - case certUsageStatusResponder: - rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE, - &requiredKeyUsage, - &requiredCertType); - if ( rv != SECSuccess ) { - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredKeyUsage = 0; - requiredCertType = 0; - } - break; - case certUsageVerifyCA: - requiredKeyUsage = KU_KEY_CERT_SIGN; - requiredCertType = NS_CERT_TYPE_CA; - if ( ! ( certType & NS_CERT_TYPE_CA ) ) { - certType |= NS_CERT_TYPE_CA; - } - break; - default: - PORT_Assert(0); - EXIT_IF_NOT_LOGGING(log); - requiredKeyUsage = 0; - requiredCertType = 0; - } - if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) { - PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE); - LOG_ERROR_OR_EXIT(log,cert,0,requiredKeyUsage); - } - if ( !( certType & requiredCertType ) ) { - PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE); - LOG_ERROR_OR_EXIT(log,cert,0,requiredCertType); - } - - /* check trust flags to see if this cert is directly trusted */ - if ( cert->trust ) { /* the cert is in the DB */ - switch ( certUsage ) { - case certUsageSSLClient: - case certUsageSSLServer: - flags = cert->trust->sslFlags; - - /* is the cert directly trusted or not trusted ? */ - if ( flags & CERTDB_VALID_PEER ) {/*the trust record is valid*/ - if ( flags & CERTDB_TRUSTED ) { /* trust this cert */ - goto winner; - } else { /* don't trust this cert */ - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - LOG_ERROR_OR_EXIT(log,cert,0,flags); - } - } - break; - case certUsageSSLServerWithStepUp: - /* XXX - step up certs can't be directly trusted */ - break; - case certUsageSSLCA: - break; - case certUsageEmailSigner: - case certUsageEmailRecipient: - flags = cert->trust->emailFlags; - - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_PEER | CERTDB_TRUSTED ) ) == - ( CERTDB_VALID_PEER | CERTDB_TRUSTED ) ) { - goto winner; - } - break; - case certUsageObjectSigner: - flags = cert->trust->objectSigningFlags; - - /* is the cert directly trusted or not trusted ? */ - if ( flags & CERTDB_VALID_PEER ) {/*the trust record is valid*/ - if ( flags & CERTDB_TRUSTED ) { /* trust this cert */ - goto winner; - } else { /* don't trust this cert */ - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - LOG_ERROR_OR_EXIT(log,cert,0,flags); - } - } - break; - case certUsageVerifyCA: - case certUsageStatusResponder: - flags = cert->trust->sslFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - goto winner; - } - flags = cert->trust->emailFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - goto winner; - } - flags = cert->trust->objectSigningFlags; - /* is the cert directly trusted or not trusted ? */ - if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) == - ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) { - goto winner; - } - break; - case certUsageAnyCA: - case certUsageProtectedObjectSigner: - case certUsageUserCertImport: - /* XXX to make the compiler happy. Should these be - * explicitly handled? - */ - break; - } - } - - rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage, - t, wincx, log); - if (rv != SECSuccess) { - EXIT_IF_NOT_LOGGING(log); - } - - /* - * Check revocation status, but only if the cert we are checking - * is not a status reponder itself. We only do this in the case - * where we checked the cert chain (above); explicit trust "wins" - * (avoids status checking, just as it avoids CRL checking, which - * is all done inside VerifyCertChain) by bypassing this code. - */ - statusConfig = CERT_GetStatusConfig(handle); - if (certUsage != certUsageStatusResponder && statusConfig != NULL) { - if (statusConfig->statusChecker != NULL) { - rv = (* statusConfig->statusChecker)(handle, cert, - t, wincx); - if (rv != SECSuccess) { - LOG_ERROR_OR_EXIT(log,cert,0,0); - } - } - } - -winner: - return(SECSuccess); - -loser: - rv = SECFailure; - - return(rv); -} - -/* - * verify a certificate by checking if its valid and that we - * trust the issuer. Verify time against now. - */ -SECStatus -CERT_VerifyCertificateNow(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertificateUsage requiredUsages, - void *wincx, SECCertificateUsage* returnedUsages) -{ - return(CERT_VerifyCertificate(handle, cert, checkSig, - requiredUsages, PR_Now(), wincx, NULL, returnedUsages)); -} - -/* obsolete, do not use for new code */ -SECStatus -CERT_VerifyCertNow(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool checkSig, SECCertUsage certUsage, void *wincx) -{ - return(CERT_VerifyCert(handle, cert, checkSig, - certUsage, PR_Now(), wincx, NULL)); -} - - -/* [ FROM pcertdb.c ] */ -/* - * 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) -{ - CERTCertList *certList = NULL; - CERTCertificate *cert = NULL; - unsigned int requiredTrustFlags; - SECTrustType requiredTrustType; - unsigned int flags; - - PRBool lookingForCA = PR_FALSE; - SECStatus rv; - CERTCertListNode *node; - CERTCertificate *saveUntrustedCA = NULL; - - /* if preferTrusted is set, must be a CA cert */ - PORT_Assert( ! ( preferTrusted && ( owner != certOwnerCA ) ) ); - - if ( owner == certOwnerCA ) { - lookingForCA = PR_TRUE; - if ( preferTrusted ) { - rv = CERT_TrustFlagsForCACertUsage(usage, &requiredTrustFlags, - &requiredTrustType); - if ( rv != SECSuccess ) { - goto loser; - } - requiredTrustFlags |= CERTDB_VALID_CA; - } - } - - certList = CERT_CreateSubjectCertList(NULL, handle, derName, validTime, - validOnly); - if ( certList != NULL ) { - rv = CERT_FilterCertListByUsage(certList, usage, lookingForCA); - if ( rv != SECSuccess ) { - goto loser; - } - - node = CERT_LIST_HEAD(certList); - - while ( !CERT_LIST_END(node, certList) ) { - cert = node->cert; - - /* looking for a trusted CA cert */ - if ( ( owner == certOwnerCA ) && preferTrusted && - ( requiredTrustType != trustTypeNone ) ) { - - if ( cert->trust == NULL ) { - flags = 0; - } else { - flags = SEC_GET_TRUST_FLAGS(cert->trust, requiredTrustType); - } - - if ( ( flags & requiredTrustFlags ) != requiredTrustFlags ) { - /* cert is not trusted */ - /* if this is the first cert to get this far, then save - * it, so we can use it if we can't find a trusted one - */ - if ( saveUntrustedCA == NULL ) { - saveUntrustedCA = cert; - } - goto endloop; - } - } - /* if we got this far, then this cert meets all criteria */ - break; - -endloop: - node = CERT_LIST_NEXT(node); - cert = NULL; - } - - /* use the saved one if we have it */ - if ( cert == NULL ) { - cert = saveUntrustedCA; - } - - /* if we found one then bump the ref count before freeing the list */ - if ( cert != NULL ) { - /* bump the ref count */ - cert = CERT_DupCertificate(cert); - } - - CERT_DestroyCertList(certList); - } - - return(cert); - -loser: - if ( certList != NULL ) { - CERT_DestroyCertList(certList); - } - - return(NULL); -} - - -/* [ From certdb.c ] */ -/* - * 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) -{ - CERTCertificate *issuerCert = NULL; - CERTCertificate *subjectCert; - CERTCertListNode *node, *freenode; - CERTCertificate *cert; - int n; - char **names; - PRBool found; - int64 time; - - if ( nCANames <= 0 ) { - return(SECSuccess); - } - - time = PR_Now(); - - node = CERT_LIST_HEAD(certList); - - while ( ! CERT_LIST_END(node, certList) ) { - cert = node->cert; - - subjectCert = CERT_DupCertificate(cert); - - /* traverse the CA certs for this cert */ - found = PR_FALSE; - while ( subjectCert != NULL ) { - n = nCANames; - names = caNames; - - if (subjectCert->issuerName != NULL) { - while ( n > 0 ) { - if ( PORT_Strcmp(*names, subjectCert->issuerName) == 0 ) { - found = PR_TRUE; - break; - } - - n--; - names++; - } - } - - if ( found ) { - break; - } - - issuerCert = CERT_FindCertIssuer(subjectCert, time, usage); - if ( issuerCert == subjectCert ) { - CERT_DestroyCertificate(issuerCert); - issuerCert = NULL; - break; - } - CERT_DestroyCertificate(subjectCert); - subjectCert = issuerCert; - - } - CERT_DestroyCertificate(subjectCert); - if ( !found ) { - /* CA was not found, so remove this cert from the list */ - freenode = node; - node = CERT_LIST_NEXT(node); - CERT_RemoveCertListNode(freenode); - } else { - /* CA was found, so leave it in the list */ - node = CERT_LIST_NEXT(node); - } - } - - return(SECSuccess); -} - -/* - * 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) -{ - SECCertTimeValidity validity; - char *nickname, *tmpstr; - - validity = CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE); - - /* if the cert is good, then just use the nickname directly */ - if ( validity == secCertTimeValid ) { - if ( arena == NULL ) { - nickname = PORT_Strdup(cert->nickname); - } else { - nickname = PORT_ArenaStrdup(arena, cert->nickname); - } - - if ( nickname == NULL ) { - goto loser; - } - } else { - - /* if the cert is not valid, then tack one of the strings on the - * end - */ - if ( validity == secCertTimeExpired ) { - tmpstr = PR_smprintf("%s%s", cert->nickname, - expiredString); - } else { - /* not yet valid */ - tmpstr = PR_smprintf("%s%s", cert->nickname, - notYetGoodString); - } - if ( tmpstr == NULL ) { - goto loser; - } - - if ( arena ) { - /* copy the string into the arena and free the malloc'd one */ - nickname = PORT_ArenaStrdup(arena, tmpstr); - PORT_Free(tmpstr); - } else { - nickname = tmpstr; - } - if ( nickname == NULL ) { - goto loser; - } - } - return(nickname); - -loser: - return(NULL); -} - -/* - * 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) -{ - CERTCertNicknames *names; - PRArenaPool *arena; - CERTCertListNode *node; - char **nn; - - /* allocate an arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return(NULL); - } - - /* allocate the structure */ - names = PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames)); - if ( names == NULL ) { - goto loser; - } - - /* init the structure */ - names->arena = arena; - names->head = NULL; - names->numnicknames = 0; - names->nicknames = NULL; - names->totallen = 0; - - /* count the certs in the list */ - node = CERT_LIST_HEAD(certList); - while ( ! CERT_LIST_END(node, certList) ) { - names->numnicknames++; - node = CERT_LIST_NEXT(node); - } - - /* allocate nicknames array */ - names->nicknames = PORT_ArenaAlloc(arena, - sizeof(char *) * names->numnicknames); - if ( names->nicknames == NULL ) { - goto loser; - } - - /* just in case printf can't deal with null strings */ - if (expiredString == NULL ) { - expiredString = ""; - } - - if ( notYetGoodString == NULL ) { - notYetGoodString = ""; - } - - /* traverse the list of certs and collect the nicknames */ - nn = names->nicknames; - node = CERT_LIST_HEAD(certList); - while ( ! CERT_LIST_END(node, certList) ) { - *nn = CERT_GetCertNicknameWithValidity(arena, node->cert, - expiredString, - notYetGoodString); - if ( *nn == NULL ) { - goto loser; - } - - names->totallen += PORT_Strlen(*nn); - - nn++; - node = CERT_LIST_NEXT(node); - } - - return(names); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(NULL); -} - -/* - * 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) -{ - int explen, nyglen, namelen; - int retlen; - char *retstr; - - namelen = PORT_Strlen(namestring); - explen = PORT_Strlen(expiredString); - nyglen = PORT_Strlen(notYetGoodString); - - if ( namelen > explen ) { - if ( PORT_Strcmp(expiredString, &namestring[namelen-explen]) == 0 ) { - retlen = namelen - explen; - retstr = (char *)PORT_Alloc(retlen+1); - if ( retstr == NULL ) { - goto loser; - } - - PORT_Memcpy(retstr, namestring, retlen); - retstr[retlen] = '\0'; - goto done; - } - } - - if ( namelen > nyglen ) { - if ( PORT_Strcmp(notYetGoodString, &namestring[namelen-nyglen]) == 0) { - retlen = namelen - nyglen; - retstr = (char *)PORT_Alloc(retlen+1); - if ( retstr == NULL ) { - goto loser; - } - - PORT_Memcpy(retstr, namestring, retlen); - retstr[retlen] = '\0'; - goto done; - } - } - - /* if name string is shorter than either invalid string, then it must - * be a raw nickname - */ - retstr = PORT_Strdup(namestring); - -done: - return(retstr); - -loser: - return(NULL); -} - -CERTCertList * -CERT_GetCertChainFromCert(CERTCertificate *cert, int64 time, SECCertUsage usage) -{ - CERTCertList *chain = NULL; - - if (NULL == cert) { - return NULL; - } - - cert = CERT_DupCertificate(cert); - if (NULL == cert) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; - } - - chain = CERT_NewCertList(); - if (NULL == chain) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; - } - - while (cert != NULL) { - if (SECSuccess != CERT_AddCertToListTail(chain, cert)) { - /* return partial chain */ - PORT_SetError(SEC_ERROR_NO_MEMORY); - return chain; - } - - if (SECITEM_CompareItem(&cert->derIssuer, &cert->derSubject) - == SECEqual) { - /* return complete chain */ - return chain; - } - - cert = CERT_FindCertIssuer(cert, time, usage); - } - - /* return partial chain */ - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - return chain; -} diff --git a/security/nss/lib/certhigh/config.mk b/security/nss/lib/certhigh/config.mk deleted file mode 100644 index 0a00dc61e..000000000 --- a/security/nss/lib/certhigh/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/certhigh/crlv2.c b/security/nss/lib/certhigh/crlv2.c deleted file mode 100644 index 2600d9878..000000000 --- a/security/nss/lib/certhigh/crlv2.c +++ /dev/null @@ -1,126 +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 x.509 v3 crl and crl entries extensions. - * - * $Id$ - */ - -#include "cert.h" -#include "secitem.h" -#include "secoid.h" -#include "secoidt.h" -#include "secder.h" -#include "secasn1.h" -#include "certxutl.h" - -SECStatus -CERT_FindCRLExtensionByOID(CERTCrl *crl, SECItem *oid, SECItem *value) -{ - return (cert_FindExtensionByOID (crl->extensions, oid, value)); -} - - -SECStatus -CERT_FindCRLExtension(CERTCrl *crl, int tag, SECItem *value) -{ - return (cert_FindExtension (crl->extensions, tag, value)); -} - - -/* Callback to set extensions and adjust verison */ -static void -SetCrlExts(void *object, CERTCertExtension **exts) -{ - CERTCrl *crl = (CERTCrl *)object; - - crl->extensions = exts; - DER_SetUInteger (crl->arena, &crl->version, SEC_CRL_VERSION_2); -} - -void * -CERT_StartCRLExtensions(CERTCrl *crl) -{ - return (cert_StartExtensions ((void *)crl, crl->arena, SetCrlExts)); -} - - -SECStatus CERT_FindCRLNumberExten (CERTCrl *crl, CERTCrlNumber *value) -{ - SECItem encodedExtenValue; - SECStatus rv; - - encodedExtenValue.data = NULL; - encodedExtenValue.len = 0; - - rv = cert_FindExtension - (crl->extensions, SEC_OID_X509_CRL_NUMBER, &encodedExtenValue); - if ( rv != SECSuccess ) - return (rv); - - rv = SEC_ASN1DecodeItem (NULL, value, SEC_IntegerTemplate, - &encodedExtenValue); - PORT_Free (encodedExtenValue.data); - return (rv); -} - -SECStatus CERT_FindCRLReasonExten (CERTCrl *crl, SECItem *value) -{ - return (CERT_FindBitStringExtension - (crl->extensions, SEC_OID_X509_REASON_CODE, value)); -} - -SECStatus CERT_FindInvalidDateExten (CERTCrl *crl, int64 *value) -{ - SECItem encodedExtenValue; - SECItem decodedExtenValue = {siBuffer,0}; - SECStatus rv; - - encodedExtenValue.data = decodedExtenValue.data = NULL; - encodedExtenValue.len = decodedExtenValue.len = 0; - - rv = cert_FindExtension - (crl->extensions, SEC_OID_X509_INVALID_DATE, &encodedExtenValue); - if ( rv != SECSuccess ) - return (rv); - - rv = SEC_ASN1DecodeItem (NULL, &decodedExtenValue, - SEC_GeneralizedTimeTemplate, &encodedExtenValue); - if (rv != SECSuccess) - return (rv); - rv = DER_GeneralizedTimeToTime(value, &encodedExtenValue); - PORT_Free (decodedExtenValue.data); - PORT_Free (encodedExtenValue.data); - return (rv); -} diff --git a/security/nss/lib/certhigh/manifest.mn b/security/nss/lib/certhigh/manifest.mn deleted file mode 100644 index d7d0a2247..000000000 --- a/security/nss/lib/certhigh/manifest.mn +++ /dev/null @@ -1,59 +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 = \ - ocsp.h \ - ocspt.h \ - $(NULL) - -PRIVATE_EXPORTS = \ - ocspti.h \ - $(NULL) - -MODULE = security - -CSRCS = \ - certhtml.c \ - certreq.c \ - crlv2.c \ - ocsp.c \ - certhigh.c \ - certvfy.c \ - xcrldist.c \ - $(NULL) - -REQUIRES = security dbm - -LIBRARY_NAME = certhi - diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c deleted file mode 100644 index 4d9a8a6e3..000000000 --- a/security/nss/lib/certhigh/ocsp.c +++ /dev/null @@ -1,3994 +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. - */ - -/* - * Implementation of OCSP services, for both client and server. - * (XXX, really, mostly just for client right now, but intended to do both.) - * - * $Id$ - */ - -#include "prerror.h" -#include "prprf.h" -#include "plarena.h" -#include "prnetdb.h" - -#include "seccomon.h" -#include "secitem.h" -#include "secoidt.h" -#include "secasn1.h" -#include "secder.h" -#include "cert.h" -#include "xconst.h" -#include "secerr.h" -#include "secoid.h" -#include "hasht.h" -#include "sechash.h" -#include "secasn1.h" -#include "keyhi.h" -#include "cryptohi.h" -#include "ocsp.h" -#include "ocspti.h" -#include "genname.h" -#include "certxutl.h" -#include "pk11func.h" /* for PK11_HashBuf */ -#include <stdarg.h> - - -/* - * The following structure is only used internally. It is allocated when - * someone turns on OCSP checking, and hangs off of the status-configuration - * structure in the certdb structure. We use it to keep configuration - * information specific to OCSP checking. - */ -typedef struct ocspCheckingContextStr { - PRBool useDefaultResponder; - char *defaultResponderURI; - char *defaultResponderNickname; - CERTCertificate *defaultResponderCert; -} ocspCheckingContext; - - -/* - * Forward declarations of sub-types, so I can lay out the types in the - * same order as the ASN.1 is laid out in the OCSP spec itself. - * - * These are in alphabetical order (case-insensitive); please keep it that way! - */ -extern const SEC_ASN1Template ocsp_CertIDTemplate[]; -extern const SEC_ASN1Template ocsp_PointerToSignatureTemplate[]; -extern const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[]; -extern const SEC_ASN1Template ocsp_ResponseDataTemplate[]; -extern const SEC_ASN1Template ocsp_RevokedInfoTemplate[]; -extern const SEC_ASN1Template ocsp_SingleRequestTemplate[]; -extern const SEC_ASN1Template ocsp_SingleResponseTemplate[]; -extern const SEC_ASN1Template ocsp_TBSRequestTemplate[]; - - -/* - * Request-related templates... - */ - -/* - * OCSPRequest ::= SEQUENCE { - * tbsRequest TBSRequest, - * optionalSignature [0] EXPLICIT Signature OPTIONAL } - */ -static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTOCSPRequest) }, - { SEC_ASN1_POINTER, - offsetof(CERTOCSPRequest, tbsRequest), - ocsp_TBSRequestTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTOCSPRequest, optionalSignature), - ocsp_PointerToSignatureTemplate }, - { 0 } -}; - -/* - * TBSRequest ::= SEQUENCE { - * version [0] EXPLICIT Version DEFAULT v1, - * requestorName [1] EXPLICIT GeneralName OPTIONAL, - * requestList SEQUENCE OF Request, - * requestExtensions [2] EXPLICIT Extensions OPTIONAL } - * - * Version ::= INTEGER { v1(0) } - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_TBSRequestTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspTBSRequest) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */ - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspTBSRequest, version), - SEC_IntegerTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(ocspTBSRequest, derRequestorName), - SEC_PointerToAnyTemplate }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(ocspTBSRequest, requestList), - ocsp_SingleRequestTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(ocspTBSRequest, requestExtensions), - CERT_SequenceOfCertExtensionTemplate }, - { 0 } -}; - -/* - * Signature ::= SEQUENCE { - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING, - * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } - */ -static const SEC_ASN1Template ocsp_SignatureTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspSignature) }, - { SEC_ASN1_INLINE, - offsetof(ocspSignature, signatureAlgorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(ocspSignature, signature) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspSignature, derCerts), - SEC_SequenceOfAnyTemplate }, - { 0 } -}; - -/* - * This template is just an extra level to use in an explicitly-tagged - * reference to a Signature. - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_PointerToSignatureTemplate[] = { - { SEC_ASN1_POINTER, 0, ocsp_SignatureTemplate } -}; - -/* - * Request ::= SEQUENCE { - * reqCert CertID, - * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_SingleRequestTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspSingleRequest) }, - { SEC_ASN1_POINTER, - offsetof(ocspSingleRequest, reqCert), - ocsp_CertIDTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspSingleRequest, singleRequestExtensions), - CERT_SequenceOfCertExtensionTemplate }, - { 0 } -}; - - -/* - * This data structure and template (CertID) is used by both OCSP - * requests and responses. It is the only one that is shared. - * - * CertID ::= SEQUENCE { - * hashAlgorithm AlgorithmIdentifier, - * issuerNameHash OCTET STRING, -- Hash of Issuer DN - * issuerKeyHash OCTET STRING, -- Hash of Issuer public key - * serialNumber CertificateSerialNumber } - * - * CertificateSerialNumber ::= INTEGER - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_CertIDTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTOCSPCertID) }, - { SEC_ASN1_INLINE, - offsetof(CERTOCSPCertID, hashAlgorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTOCSPCertID, issuerNameHash) }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTOCSPCertID, issuerKeyHash) }, - { SEC_ASN1_INTEGER, - offsetof(CERTOCSPCertID, serialNumber) }, - { 0 } -}; - - -/* - * Response-related templates... - */ - -/* - * OCSPResponse ::= SEQUENCE { - * responseStatus OCSPResponseStatus, - * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } - */ -static const SEC_ASN1Template ocsp_OCSPResponseTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTOCSPResponse) }, - { SEC_ASN1_ENUMERATED, - offsetof(CERTOCSPResponse, responseStatus) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTOCSPResponse, responseBytes), - ocsp_PointerToResponseBytesTemplate }, - { 0 } -}; - -/* - * ResponseBytes ::= SEQUENCE { - * responseType OBJECT IDENTIFIER, - * response OCTET STRING } - */ -static const SEC_ASN1Template ocsp_ResponseBytesTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspResponseBytes) }, - { SEC_ASN1_OBJECT_ID, - offsetof(ocspResponseBytes, responseType) }, - { SEC_ASN1_OCTET_STRING, - offsetof(ocspResponseBytes, response) }, - { 0 } -}; - -/* - * This template is just an extra level to use in an explicitly-tagged - * reference to a ResponseBytes. - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = { - { SEC_ASN1_POINTER, 0, ocsp_ResponseBytesTemplate } -}; - -/* - * BasicOCSPResponse ::= SEQUENCE { - * tbsResponseData ResponseData, - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING, - * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } - */ -static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspBasicOCSPResponse) }, - { SEC_ASN1_POINTER, - offsetof(ocspBasicOCSPResponse, tbsResponseData), - ocsp_ResponseDataTemplate }, - { SEC_ASN1_INLINE, - offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(ocspBasicOCSPResponse, responseSignature.signature) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspBasicOCSPResponse, responseSignature.derCerts), - SEC_SequenceOfAnyTemplate }, - { 0 } -}; - -/* - * ResponseData ::= SEQUENCE { - * version [0] EXPLICIT Version DEFAULT v1, - * responderID ResponderID, - * producedAt GeneralizedTime, - * responses SEQUENCE OF SingleResponse, - * responseExtensions [1] EXPLICIT Extensions OPTIONAL } - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_ResponseDataTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspResponseData) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */ - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspResponseData, version), - SEC_IntegerTemplate }, - { SEC_ASN1_ANY, - offsetof(ocspResponseData, derResponderID) }, - { SEC_ASN1_GENERALIZED_TIME, - offsetof(ocspResponseData, producedAt) }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(ocspResponseData, responses), - ocsp_SingleResponseTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(ocspResponseData, responseExtensions), - CERT_SequenceOfCertExtensionTemplate }, - { 0 } -}; - -/* - * ResponderID ::= CHOICE { - * byName [1] EXPLICIT Name, - * byKey [2] EXPLICIT KeyHash } - * - * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key - * (excluding the tag and length fields) - * - * XXX Because the ASN.1 encoder and decoder currently do not provide - * a way to automatically handle a CHOICE, we need to do it in two - * steps, looking at the type tag and feeding the exact choice back - * to the ASN.1 code. Hopefully that will change someday and this - * can all be simplified down into a single template. Anyway, for - * now we list each choice as its own template: - */ -static const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[] = { - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(ocspResponderID, responderIDValue.name), - CERT_NameTemplate } -}; -static const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[] = { - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(ocspResponderID, responderIDValue.keyHash), - SEC_OctetStringTemplate } -}; -static const SEC_ASN1Template ocsp_ResponderIDOtherTemplate[] = { - { SEC_ASN1_ANY, - offsetof(ocspResponderID, responderIDValue.other) } -}; - -/* - * SingleResponse ::= SEQUENCE { - * certID CertID, - * certStatus CertStatus, - * thisUpdate GeneralizedTime, - * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, - * singleExtensions [1] EXPLICIT Extensions OPTIONAL } - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_SingleResponseTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTOCSPSingleResponse) }, - { SEC_ASN1_POINTER, - offsetof(CERTOCSPSingleResponse, certID), - ocsp_CertIDTemplate }, - { SEC_ASN1_ANY, - offsetof(CERTOCSPSingleResponse, derCertStatus) }, - { SEC_ASN1_GENERALIZED_TIME, - offsetof(CERTOCSPSingleResponse, thisUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTOCSPSingleResponse, nextUpdate), - SEC_PointerToGeneralizedTimeTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTOCSPSingleResponse, singleExtensions), - CERT_SequenceOfCertExtensionTemplate }, - { 0 } -}; - -/* - * CertStatus ::= CHOICE { - * good [0] IMPLICIT NULL, - * revoked [1] IMPLICIT RevokedInfo, - * unknown [2] IMPLICIT UnknownInfo } - * - * Because the ASN.1 encoder and decoder currently do not provide - * a way to automatically handle a CHOICE, we need to do it in two - * steps, looking at the type tag and feeding the exact choice back - * to the ASN.1 code. Hopefully that will change someday and this - * can all be simplified down into a single template. Anyway, for - * now we list each choice as its own template: - */ -static const SEC_ASN1Template ocsp_CertStatusGoodTemplate[] = { - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspCertStatus, certStatusInfo.goodInfo), - SEC_NullTemplate } -}; -static const SEC_ASN1Template ocsp_CertStatusRevokedTemplate[] = { - { SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(ocspCertStatus, certStatusInfo.revokedInfo), - ocsp_RevokedInfoTemplate } -}; -static const SEC_ASN1Template ocsp_CertStatusUnknownTemplate[] = { - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 2, - offsetof(ocspCertStatus, certStatusInfo.unknownInfo), - SEC_NullTemplate } -}; -static const SEC_ASN1Template ocsp_CertStatusOtherTemplate[] = { - { SEC_ASN1_POINTER, - offsetof(ocspCertStatus, certStatusInfo.otherInfo), - SEC_AnyTemplate } -}; - -/* - * RevokedInfo ::= SEQUENCE { - * revocationTime GeneralizedTime, - * revocationReason [0] EXPLICIT CRLReason OPTIONAL } - * - * Note: this should be static but the AIX compiler doesn't like it (because it - * was forward-declared above); it is not meant to be exported, but this - * is the only way it will compile. - */ -const SEC_ASN1Template ocsp_RevokedInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspRevokedInfo) }, - { SEC_ASN1_GENERALIZED_TIME, - offsetof(ocspRevokedInfo, revocationTime) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspRevokedInfo, revocationReason), - SEC_PointerToEnumeratedTemplate }, - { 0 } -}; - - -/* - * OCSP-specific extension templates: - */ - -/* - * ServiceLocator ::= SEQUENCE { - * issuer Name, - * locator AuthorityInfoAccessSyntax OPTIONAL } - */ -static const SEC_ASN1Template ocsp_ServiceLocatorTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspServiceLocator) }, - { SEC_ASN1_POINTER, - offsetof(ocspServiceLocator, issuer), - CERT_NameTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, - offsetof(ocspServiceLocator, locator) }, - { 0 } -}; - - -/* - * REQUEST SUPPORT FUNCTIONS (encode/create/decode/destroy): - */ - -/* - * FUNCTION: CERT_EncodeOCSPRequest - * DER encodes an OCSP Request, possibly adding a signature as well. - * XXX Signing is not yet supported, however; see comments in code. - * INPUTS: - * PRArenaPool *arena - * The return value is allocated from here. - * If a NULL is passed in, allocation is done from the heap instead. - * CERTOCSPRequest *request - * The request to be encoded. - * void *pwArg - * Pointer to argument for password prompting, if needed. (Definitely - * not needed if not signing.) - * RETURN: - * Returns a NULL on error and a pointer to the SECItem with the - * encoded value otherwise. Any error is likely to be low-level - * (e.g. no memory). - */ -SECItem * -CERT_EncodeOCSPRequest(PRArenaPool *arena, CERTOCSPRequest *request, - void *pwArg) -{ - ocspTBSRequest *tbsRequest; - SECStatus rv; - - /* XXX All of these should generate errors if they fail. */ - PORT_Assert(request); - PORT_Assert(request->tbsRequest); - - tbsRequest = request->tbsRequest; - - if (request->tbsRequest->extensionHandle != NULL) { - rv = CERT_FinishExtensions(request->tbsRequest->extensionHandle); - request->tbsRequest->extensionHandle = NULL; - if (rv != SECSuccess) - return NULL; - } - - /* - * XXX When signed requests are supported and request->optionalSignature - * is not NULL: - * - need to encode tbsRequest->requestorName - * - need to encode tbsRequest - * - need to sign that encoded result (using cert in sig), filling in the - * request->optionalSignature structure with the result, the signing - * algorithm and (perhaps?) the cert (and its chain?) in derCerts - */ - - return SEC_ASN1EncodeItem(arena, NULL, request, ocsp_OCSPRequestTemplate); -} - - -/* - * FUNCTION: CERT_DecodeOCSPRequest - * Decode a DER encoded OCSP Request. - * INPUTS: - * SECItem *src - * Pointer to a SECItem holding DER encoded OCSP Request. - * RETURN: - * Returns a pointer to a CERTOCSPRequest containing the decoded request. - * On error, returns NULL. Most likely error is trouble decoding - * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory). - */ -CERTOCSPRequest * -CERT_DecodeOCSPRequest(SECItem *src) -{ - PRArenaPool *arena = NULL; - SECStatus rv = SECFailure; - CERTOCSPRequest *dest = NULL; - int i; - - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto loser; - } - dest = (CERTOCSPRequest *) PORT_ArenaZAlloc(arena, - sizeof(CERTOCSPRequest)); - if (dest == NULL) { - goto loser; - } - dest->arena = arena; - - rv = SEC_QuickDERDecodeItem(arena, dest, ocsp_OCSPRequestTemplate, src); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_BAD_DER) - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); - goto loser; - } - - /* - * XXX I would like to find a way to get rid of the necessity - * of doing this copying of the arena pointer. - */ - for (i = 0; dest->tbsRequest->requestList[i] != NULL; i++) { - dest->tbsRequest->requestList[i]->arena = arena; - } - - return dest; - -loser: - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return NULL; -} - -SECStatus -CERT_DestroyOCSPCertID(CERTOCSPCertID* certID) -{ - if (certID->poolp) { - PORT_FreeArena(certID->poolp, PR_FALSE); - return SECSuccess; - } - return SECFailure; -} - - -/* - * Create and fill-in a CertID. This function fills in the hash values - * (issuerNameHash and issuerKeyHash), and is hardwired to use SHA1. - * Someday it might need to be more flexible about hash algorithm, but - * for now we have no intention/need to create anything else, and until - * we have more flexible underlying interfaces, it's just not as easy - * as it should be to just take an algorithm id and call some helper - * functions to do all the work (no algid->length translation, no function - * to hash from and into a SECItem, etc.). - * - * Error causes a null to be returned; most likely cause is trouble - * finding the certificate issuer (SEC_ERROR_UNKNOWN_ISSUER). - * Other errors are low-level problems (no memory, bad database, etc.). - */ -static CERTOCSPCertID * -ocsp_CreateCertID(PRArenaPool *arena, CERTCertificate *cert, int64 time) -{ - CERTOCSPCertID *certID; - CERTCertificate *issuerCert = NULL; - SECItem *tempItem = NULL; - void *mark = PORT_ArenaMark(arena); - SECStatus rv; - - PORT_Assert(arena != NULL); - - certID = PORT_ArenaZNew(arena, CERTOCSPCertID); - if (certID == NULL) { - goto loser; - } - - rv = SECOID_SetAlgorithmID(arena, &certID->hashAlgorithm, SEC_OID_SHA1, - NULL); - if (rv != SECSuccess) { - goto loser; - } - - issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA); - if (issuerCert == NULL) { - goto loser; - } - - tempItem = SEC_ASN1EncodeItem(NULL, NULL, &issuerCert->subject, - CERT_NameTemplate); - if (tempItem == NULL) { - goto loser; - } - - if (SECITEM_AllocItem(arena, &(certID->issuerNameHash), - SHA1_LENGTH) == NULL) { - goto loser; - } - rv = PK11_HashBuf(SEC_OID_SHA1, certID->issuerNameHash.data, - tempItem->data, tempItem->len); - if (rv != SECSuccess) { - goto loser; - } - certID->issuerSHA1NameHash.data = certID->issuerNameHash.data; - certID->issuerSHA1NameHash.len = certID->issuerNameHash.len; - /* cache the other two hash algorithms as well */ - if (SECITEM_AllocItem(arena, &(certID->issuerMD5NameHash), - MD5_LENGTH) == NULL) { - goto loser; - } - rv = PK11_HashBuf(SEC_OID_MD5, certID->issuerMD5NameHash.data, - tempItem->data, tempItem->len); - if (rv != SECSuccess) { - goto loser; - } - if (SECITEM_AllocItem(arena, &(certID->issuerMD2NameHash), - MD2_LENGTH) == NULL) { - goto loser; - } - rv = PK11_HashBuf(SEC_OID_MD2, certID->issuerMD2NameHash.data, - tempItem->data, tempItem->len); - if (rv != SECSuccess) { - goto loser; - } - - SECITEM_FreeItem(tempItem, PR_TRUE); - tempItem = NULL; - - if (CERT_SPKDigestValueForCert(arena, issuerCert, SEC_OID_SHA1, - &(certID->issuerKeyHash)) == NULL) { - goto loser; - } - certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data; - certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len; - /* cache the other two hash algorithms as well */ - if (CERT_SPKDigestValueForCert(arena, issuerCert, SEC_OID_MD5, - &(certID->issuerMD5KeyHash)) == NULL) { - goto loser; - } - if (CERT_SPKDigestValueForCert(arena, issuerCert, SEC_OID_MD2, - &(certID->issuerMD2KeyHash)) == NULL) { - goto loser; - } - - - /* now we are done with issuerCert */ - CERT_DestroyCertificate(issuerCert); - issuerCert = NULL; - - rv = SECITEM_CopyItem(arena, &certID->serialNumber, &cert->serialNumber); - if (rv != SECSuccess) { - goto loser; - } - - PORT_ArenaUnmark(arena, mark); - return certID; - -loser: - if (issuerCert != NULL) { - CERT_DestroyCertificate(issuerCert); - } - if (tempItem != NULL) { - SECITEM_FreeItem(tempItem, PR_TRUE); - } - PORT_ArenaRelease(arena, mark); - return NULL; -} - -CERTOCSPCertID* -CERT_CreateOCSPCertID(CERTCertificate *cert, int64 time) -{ - PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERTOCSPCertID *certID; - PORT_Assert(arena != NULL); - if (!arena) - return NULL; - - certID = ocsp_CreateCertID(arena, cert, time); - if (!certID) { - PORT_FreeArena(arena, PR_FALSE); - return NULL; - } - certID->poolp = arena; - return certID; -} - - - -/* - * Callback to set Extensions in request object - */ -void SetSingleReqExts(void *object, CERTCertExtension **exts) -{ - ocspSingleRequest *singleRequest = - (ocspSingleRequest *)object; - - singleRequest->singleRequestExtensions = exts; -} - -/* - * Add the Service Locator extension to the singleRequestExtensions - * for the given singleRequest. - * - * All errors are internal or low-level problems (e.g. no memory). - */ -static SECStatus -ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest, - CERTCertificate *cert) -{ - ocspServiceLocator *serviceLocator = NULL; - void *extensionHandle = NULL; - SECStatus rv = SECFailure; - - serviceLocator = PORT_ZNew(ocspServiceLocator); - if (serviceLocator == NULL) - goto loser; - - /* - * Normally it would be a bad idea to do a direct reference like - * this rather than allocate and copy the name *or* at least dup - * a reference of the cert. But all we need is to be able to read - * the issuer name during the encoding we are about to do, so a - * copy is just a waste of time. - */ - serviceLocator->issuer = &cert->issuer; - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS, - &serviceLocator->locator); - if (rv != SECSuccess) { - if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) - goto loser; - } - - /* prepare for following loser gotos */ - rv = SECFailure; - - extensionHandle = cert_StartExtensions(singleRequest, - singleRequest->arena, SetSingleReqExts); - if (extensionHandle == NULL) - goto loser; - - rv = CERT_EncodeAndAddExtension(extensionHandle, - SEC_OID_PKIX_OCSP_SERVICE_LOCATOR, - serviceLocator, PR_FALSE, - ocsp_ServiceLocatorTemplate); - -loser: - if (extensionHandle != NULL) { - /* - * Either way we have to finish out the extension context (so it gets - * freed). But careful not to override any already-set bad status. - */ - SECStatus tmprv = CERT_FinishExtensions(extensionHandle); - if (rv == SECSuccess) - rv = tmprv; - } - - /* - * Finally, free the serviceLocator structure itself and we are done. - */ - if (serviceLocator != NULL) { - if (serviceLocator->locator.data != NULL) - SECITEM_FreeItem(&serviceLocator->locator, PR_FALSE); - PORT_Free(serviceLocator); - } - - return rv; -} - -/* - * Creates an array of ocspSingleRequest based on a list of certs. - * Note that the code which later compares the request list with the - * response expects this array to be in the exact same order as the - * certs are found in the list. It would be harder to change that - * order than preserve it, but since the requirement is not obvious, - * it deserves to be mentioned. - * - * Any problem causes a null return and error set: - * SEC_ERROR_UNKNOWN_ISSUER - * Other errors are low-level problems (no memory, bad database, etc.). - */ -static ocspSingleRequest ** -ocsp_CreateSingleRequestList(PRArenaPool *arena, CERTCertList *certList, - int64 time, PRBool includeLocator) -{ - ocspSingleRequest **requestList = NULL; - CERTCertListNode *node; - int i, count; - void *mark = PORT_ArenaMark(arena); - - node = CERT_LIST_HEAD(certList); - for (count = 0; !CERT_LIST_END(node, certList); count++) { - node = CERT_LIST_NEXT(node); - } - - if (count == 0) - goto loser; - - requestList = PORT_ArenaNewArray(arena, ocspSingleRequest *, count + 1); - if (requestList == NULL) - goto loser; - - node = CERT_LIST_HEAD(certList); - for (i = 0; !CERT_LIST_END(node, certList); i++) { - requestList[i] = PORT_ArenaZNew(arena, ocspSingleRequest); - if (requestList[i] == NULL) - goto loser; - - requestList[i]->arena = arena; - requestList[i]->reqCert = ocsp_CreateCertID(arena, node->cert, time); - if (requestList[i]->reqCert == NULL) - goto loser; - - if (includeLocator == PR_TRUE) { - SECStatus rv; - - rv = ocsp_AddServiceLocatorExtension(requestList[i], node->cert); - if (rv != SECSuccess) - goto loser; - } - - node = CERT_LIST_NEXT(node); - } - - PORT_Assert(i == count); - - PORT_ArenaUnmark(arena, mark); - requestList[i] = NULL; - return requestList; - -loser: - PORT_ArenaRelease(arena, mark); - return NULL; -} - - -/* - * FUNCTION: CERT_CreateOCSPRequest - * Creates a CERTOCSPRequest, requesting the status of the certs in - * the given list. - * INPUTS: - * CERTCertList *certList - * A list of certs for which status will be requested. - * Note that all of these certificates should have the same issuer, - * or it's expected the response will be signed by a trusted responder. - * If the certs need to be broken up into multiple requests, that - * must be handled by the caller (and thus by having multiple calls - * to this routine), who knows about where the request(s) are being - * sent and whether there are any trusted responders in place. - * int64 time - * Indicates the time for which the certificate status is to be - * determined -- this may be used in the search for the cert's issuer - * but has no effect on the request itself. - * PRBool addServiceLocator - * If true, the Service Locator extension should be added to the - * single request(s) for each cert. - * CERTCertificate *signerCert - * If non-NULL, means sign the request using this cert. Otherwise, - * do not sign. - * XXX note that request signing is not yet supported; see comment in code - * RETURN: - * A pointer to a CERTOCSPRequest structure containing an OCSP request - * for the cert list. On error, null is returned, with an error set - * indicating the reason. This is likely SEC_ERROR_UNKNOWN_ISSUER. - * (The issuer is needed to create a request for the certificate.) - * Other errors are low-level problems (no memory, bad database, etc.). - */ -CERTOCSPRequest * -CERT_CreateOCSPRequest(CERTCertList *certList, int64 time, - PRBool addServiceLocator, - CERTCertificate *signerCert) -{ - PRArenaPool *arena = NULL; - CERTOCSPRequest *request = NULL; - ocspTBSRequest *tbsRequest = NULL; - - /* - * XXX This should set an error, but since it is only temporary and - * since PSM will not initially provide a way to turn on signing of - * requests anyway, I figure we can just skip defining an error that - * will be obsolete in the next release. When we are prepared to - * put signing of requests back in, this entire check will go away, - * and later in this function we will need to allocate a signature - * structure for the request, fill in the "derCerts" field in it, - * save the signerCert there, as well as fill in the "requestorName" - * field of the tbsRequest. - */ - if (signerCert != NULL) { - return NULL; - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto loser; - } - - request = PORT_ArenaZNew(arena, CERTOCSPRequest); - if (request == NULL) { - goto loser; - } - request->arena = arena; - - tbsRequest = PORT_ArenaZNew(arena, ocspTBSRequest); - if (tbsRequest == NULL) { - goto loser; - } - request->tbsRequest = tbsRequest; - - /* version 1 is the default, so we need not fill in a version number */ - - /* - * Now create the list of single requests, one for each cert. - */ - tbsRequest->requestList = ocsp_CreateSingleRequestList(arena, certList, - time, - addServiceLocator); - if (tbsRequest->requestList == NULL) { - goto loser; - } - return request; - -loser: - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return NULL; -} - - -/* - * FUNCTION: CERT_AddOCSPAcceptableResponses - * Add the AcceptableResponses extension to an OCSP Request. - * INPUTS: - * CERTOCSPRequest *request - * The request to which the extension should be added. - * ... - * A list (of one or more) of SECOidTag -- each of the response types - * to be added. The last OID *must* be SEC_OID_PKIX_OCSP_BASIC_RESPONSE. - * (This marks the end of the list, and it must be specified because a - * client conforming to the OCSP standard is required to handle the basic - * response type.) The OIDs are not checked in any way. - * RETURN: - * SECSuccess if the extension is added; SECFailure if anything goes wrong. - * All errors are internal or low-level problems (e.g. no memory). - */ - -void SetRequestExts(void *object, CERTCertExtension **exts) -{ - CERTOCSPRequest *request = (CERTOCSPRequest *)object; - - request->tbsRequest->requestExtensions = exts; -} - -SECStatus -CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request, ...) -{ - void *extHandle; - va_list ap; - int i, count; - SECOidTag responseType; - SECOidData *responseOid; - SECItem **acceptableResponses = NULL; - SECStatus rv = SECFailure; - - extHandle = request->tbsRequest->extensionHandle; - if (extHandle == NULL) { - extHandle = cert_StartExtensions(request, request->arena, SetRequestExts); - if (extHandle == NULL) - goto loser; - } - - /* Count number of OIDS going into the extension value. */ - count = 0; - va_start(ap, request); - do { - count++; - responseType = va_arg(ap, SECOidTag); - } while (responseType != SEC_OID_PKIX_OCSP_BASIC_RESPONSE); - va_end(ap); - - acceptableResponses = PORT_NewArray(SECItem *, count + 1); - if (acceptableResponses == NULL) - goto loser; - - va_start(ap, request); - for (i = 0; i < count; i++) { - responseType = va_arg(ap, SECOidTag); - responseOid = SECOID_FindOIDByTag(responseType); - acceptableResponses[i] = &(responseOid->oid); - } - va_end(ap); - acceptableResponses[i] = NULL; - - rv = CERT_EncodeAndAddExtension(extHandle, SEC_OID_PKIX_OCSP_RESPONSE, - &acceptableResponses, PR_FALSE, - SEC_SequenceOfObjectIDTemplate); - if (rv != SECSuccess) - goto loser; - - PORT_Free(acceptableResponses); - if (request->tbsRequest->extensionHandle == NULL) - request->tbsRequest->extensionHandle = extHandle; - return SECSuccess; - -loser: - if (acceptableResponses != NULL) - PORT_Free(acceptableResponses); - if (extHandle != NULL) - (void) CERT_FinishExtensions(extHandle); - return rv; -} - - -/* - * FUNCTION: CERT_DestroyOCSPRequest - * Frees an OCSP Request structure. - * INPUTS: - * CERTOCSPRequest *request - * Pointer to CERTOCSPRequest to be freed. - * RETURN: - * No return value; no errors. - */ -void -CERT_DestroyOCSPRequest(CERTOCSPRequest *request) -{ - if (request == NULL) - return; - - if (request->tbsRequest != NULL) { - if (request->tbsRequest->requestorName != NULL) - CERT_DestroyGeneralNameList(request->tbsRequest->requestorName); - if (request->tbsRequest->extensionHandle != NULL) - (void) CERT_FinishExtensions(request->tbsRequest->extensionHandle); - } - - if (request->optionalSignature != NULL) { - if (request->optionalSignature->cert != NULL) - CERT_DestroyCertificate(request->optionalSignature->cert); - - /* - * XXX Need to free derCerts? Or do they come out of arena? - * (Currently we never fill in derCerts, which is why the - * answer is not obvious. Once we do, add any necessary code - * here and remove this comment.) - */ - } - - /* - * We should actually never have a request without an arena, - * but check just in case. (If there isn't one, there is not - * much we can do about it...) - */ - PORT_Assert(request->arena != NULL); - if (request->arena != NULL) - PORT_FreeArena(request->arena, PR_FALSE); -} - - -/* - * RESPONSE SUPPORT FUNCTIONS (encode/create/decode/destroy): - */ - -/* - * Helper function for encoding or decoding a ResponderID -- based on the - * given type, return the associated template for that choice. - */ -static const SEC_ASN1Template * -ocsp_ResponderIDTemplateByType(ocspResponderIDType responderIDType) -{ - const SEC_ASN1Template *responderIDTemplate; - - switch (responderIDType) { - case ocspResponderID_byName: - responderIDTemplate = ocsp_ResponderIDByNameTemplate; - break; - case ocspResponderID_byKey: - responderIDTemplate = ocsp_ResponderIDByKeyTemplate; - break; - case ocspResponderID_other: - default: - PORT_Assert(responderIDType == ocspResponderID_other); - responderIDTemplate = ocsp_ResponderIDOtherTemplate; - break; - } - - return responderIDTemplate; -} - -/* - * Helper function for encoding or decoding a CertStatus -- based on the - * given type, return the associated template for that choice. - */ -static const SEC_ASN1Template * -ocsp_CertStatusTemplateByType(ocspCertStatusType certStatusType) -{ - const SEC_ASN1Template *certStatusTemplate; - - switch (certStatusType) { - case ocspCertStatus_good: - certStatusTemplate = ocsp_CertStatusGoodTemplate; - break; - case ocspCertStatus_revoked: - certStatusTemplate = ocsp_CertStatusRevokedTemplate; - break; - case ocspCertStatus_unknown: - certStatusTemplate = ocsp_CertStatusUnknownTemplate; - break; - case ocspCertStatus_other: - default: - PORT_Assert(certStatusType == ocspCertStatus_other); - certStatusTemplate = ocsp_CertStatusOtherTemplate; - break; - } - - return certStatusTemplate; -} - -/* - * Helper function for decoding a certStatus -- turn the actual DER tag - * into our local translation. - */ -static ocspCertStatusType -ocsp_CertStatusTypeByTag(int derTag) -{ - ocspCertStatusType certStatusType; - - switch (derTag) { - case 0: - certStatusType = ocspCertStatus_good; - break; - case 1: - certStatusType = ocspCertStatus_revoked; - break; - case 2: - certStatusType = ocspCertStatus_unknown; - break; - default: - certStatusType = ocspCertStatus_other; - break; - } - - return certStatusType; -} - -/* - * Helper function for decoding SingleResponses -- they each contain - * a status which is encoded as CHOICE, which needs to be decoded "by hand". - * - * Note -- on error, this routine does not release the memory it may - * have allocated; it expects its caller to do that. - */ -static SECStatus -ocsp_FinishDecodingSingleResponses(PRArenaPool *arena, - CERTOCSPSingleResponse **responses) -{ - ocspCertStatus *certStatus; - ocspCertStatusType certStatusType; - const SEC_ASN1Template *certStatusTemplate; - int derTag; - int i; - SECStatus rv = SECFailure; - - if (responses == NULL) /* nothing to do */ - return SECSuccess; - - for (i = 0; responses[i] != NULL; i++) { - /* - * The following assert points out internal errors (problems in - * the template definitions or in the ASN.1 decoder itself, etc.). - */ - PORT_Assert(responses[i]->derCertStatus.data != NULL); - - derTag = responses[i]->derCertStatus.data[0] & SEC_ASN1_TAGNUM_MASK; - certStatusType = ocsp_CertStatusTypeByTag(derTag); - certStatusTemplate = ocsp_CertStatusTemplateByType(certStatusType); - - certStatus = PORT_ArenaZAlloc(arena, sizeof(ocspCertStatus)); - if (certStatus == NULL) { - goto loser; - } - rv = SEC_ASN1DecodeItem(arena, certStatus, certStatusTemplate, - &responses[i]->derCertStatus); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_BAD_DER) - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); - goto loser; - } - - certStatus->certStatusType = certStatusType; - responses[i]->certStatus = certStatus; - } - - return SECSuccess; - -loser: - return rv; -} - -/* - * Helper function for decoding a responderID -- turn the actual DER tag - * into our local translation. - */ -static ocspResponderIDType -ocsp_ResponderIDTypeByTag(int derTag) -{ - ocspResponderIDType responderIDType; - - switch (derTag) { - case 1: - responderIDType = ocspResponderID_byName; - break; - case 2: - responderIDType = ocspResponderID_byKey; - break; - default: - responderIDType = ocspResponderID_other; - break; - } - - return responderIDType; -} - -/* - * Decode "src" as a BasicOCSPResponse, returning the result. - */ -static ocspBasicOCSPResponse * -ocsp_DecodeBasicOCSPResponse(PRArenaPool *arena, SECItem *src) -{ - void *mark; - ocspBasicOCSPResponse *basicResponse; - ocspResponseData *responseData; - ocspResponderID *responderID; - ocspResponderIDType responderIDType; - const SEC_ASN1Template *responderIDTemplate; - int derTag; - SECStatus rv; - - mark = PORT_ArenaMark(arena); - - basicResponse = PORT_ArenaZAlloc(arena, sizeof(ocspBasicOCSPResponse)); - if (basicResponse == NULL) { - goto loser; - } - - rv = SEC_QuickDERDecodeItem(arena, basicResponse, - ocsp_BasicOCSPResponseTemplate, src); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_BAD_DER) - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); - goto loser; - } - - responseData = basicResponse->tbsResponseData; - - /* - * The following asserts point out internal errors (problems in - * the template definitions or in the ASN.1 decoder itself, etc.). - */ - PORT_Assert(responseData != NULL); - PORT_Assert(responseData->derResponderID.data != NULL); - - /* - * XXX Because responderID is a CHOICE, which is not currently handled - * by our ASN.1 decoder, we have to decode it "by hand". - */ - derTag = responseData->derResponderID.data[0] & SEC_ASN1_TAGNUM_MASK; - responderIDType = ocsp_ResponderIDTypeByTag(derTag); - responderIDTemplate = ocsp_ResponderIDTemplateByType(responderIDType); - - responderID = PORT_ArenaZAlloc(arena, sizeof(ocspResponderID)); - if (responderID == NULL) { - goto loser; - } - rv = SEC_QuickDERDecodeItem(arena, responderID, responderIDTemplate, - &responseData->derResponderID); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_BAD_DER) - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); - goto loser; - } - - responderID->responderIDType = responderIDType; - responseData->responderID = responderID; - - /* - * XXX Each SingleResponse also contains a CHOICE, which has to be - * fixed up by hand. - */ - rv = ocsp_FinishDecodingSingleResponses(arena, responseData->responses); - if (rv != SECSuccess) { - goto loser; - } - - PORT_ArenaUnmark(arena, mark); - return basicResponse; - -loser: - PORT_ArenaRelease(arena, mark); - return NULL; -} - - -/* - * Decode the responseBytes based on the responseType found in "rbytes", - * leaving the resulting translated/decoded information in there as well. - */ -static SECStatus -ocsp_DecodeResponseBytes(PRArenaPool *arena, ocspResponseBytes *rbytes) -{ - PORT_Assert(rbytes != NULL); /* internal error, really */ - if (rbytes == NULL) - PORT_SetError(SEC_ERROR_INVALID_ARGS); /* XXX set better error? */ - - rbytes->responseTypeTag = SECOID_FindOIDTag(&rbytes->responseType); - switch (rbytes->responseTypeTag) { - case SEC_OID_PKIX_OCSP_BASIC_RESPONSE: - { - ocspBasicOCSPResponse *basicResponse; - - basicResponse = ocsp_DecodeBasicOCSPResponse(arena, - &rbytes->response); - if (basicResponse == NULL) - return SECFailure; - - rbytes->decodedResponse.basic = basicResponse; - } - break; - - /* - * Add new/future response types here. - */ - - default: - PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE); - return SECFailure; - } - - return SECSuccess; -} - - -/* - * FUNCTION: CERT_DecodeOCSPResponse - * Decode a DER encoded OCSP Response. - * INPUTS: - * SECItem *src - * Pointer to a SECItem holding DER encoded OCSP Response. - * RETURN: - * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response); - * the caller is responsible for destroying it. Or NULL if error (either - * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE), - * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE), - * or a low-level or internal error occurred). - */ -CERTOCSPResponse * -CERT_DecodeOCSPResponse(SECItem *src) -{ - PRArenaPool *arena = NULL; - CERTOCSPResponse *response = NULL; - SECStatus rv = SECFailure; - ocspResponseStatus sv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto loser; - } - response = (CERTOCSPResponse *) PORT_ArenaZAlloc(arena, - sizeof(CERTOCSPResponse)); - if (response == NULL) { - goto loser; - } - response->arena = arena; - - rv = SEC_QuickDERDecodeItem(arena, response, ocsp_OCSPResponseTemplate, src); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_BAD_DER) - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); - goto loser; - } - - sv = (ocspResponseStatus) DER_GetInteger(&response->responseStatus); - response->statusValue = sv; - if (sv != ocspResponse_successful) { - /* - * If the response status is anything but successful, then we - * are all done with decoding; the status is all there is. - */ - return response; - } - - /* - * A successful response contains much more information, still encoded. - * Now we need to decode that. - */ - rv = ocsp_DecodeResponseBytes(arena, response->responseBytes); - if (rv != SECSuccess) { - goto loser; - } - - return response; - -loser: - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return NULL; -} - -/* - * The way an OCSPResponse is defined, there are many levels to descend - * before getting to the actual response information. And along the way - * we need to check that the response *type* is recognizable, which for - * now means that it is a BasicOCSPResponse, because that is the only - * type currently defined. Rather than force all routines to perform - * a bunch of sanity checking every time they want to work on a response, - * this function isolates that and gives back the interesting part. - * Note that no copying is done, this just returns a pointer into the - * substructure of the response which is passed in. - * - * XXX This routine only works when a valid response structure is passed - * into it; this is checked with many assertions. Assuming the response - * was creating by decoding, it wouldn't make it this far without being - * okay. That is a sufficient assumption since the entire OCSP interface - * is only used internally. When this interface is officially exported, - * each assertion below will need to be followed-up with setting an error - * and returning (null). - */ -static ocspResponseData * -ocsp_GetResponseData(CERTOCSPResponse *response) -{ - ocspBasicOCSPResponse *basic; - ocspResponseData *responseData; - - PORT_Assert(response != NULL); - - PORT_Assert(response->responseBytes != NULL); - - PORT_Assert(response->responseBytes->responseTypeTag - == SEC_OID_PKIX_OCSP_BASIC_RESPONSE); - - basic = response->responseBytes->decodedResponse.basic; - PORT_Assert(basic != NULL); - - responseData = basic->tbsResponseData; - PORT_Assert(responseData != NULL); - - return responseData; -} - -/* - * Much like the routine above, except it returns the response signature. - * Again, no copy is done. - */ -static ocspSignature * -ocsp_GetResponseSignature(CERTOCSPResponse *response) -{ - ocspBasicOCSPResponse *basic; - - PORT_Assert(response != NULL); - if (NULL == response->responseBytes) { - return NULL; - } - PORT_Assert(response->responseBytes != NULL); - PORT_Assert(response->responseBytes->responseTypeTag - == SEC_OID_PKIX_OCSP_BASIC_RESPONSE); - - basic = response->responseBytes->decodedResponse.basic; - PORT_Assert(basic != NULL); - - return &(basic->responseSignature); -} - - -/* - * FUNCTION: CERT_DestroyOCSPResponse - * Frees an OCSP Response structure. - * INPUTS: - * CERTOCSPResponse *request - * Pointer to CERTOCSPResponse to be freed. - * RETURN: - * No return value; no errors. - */ -void -CERT_DestroyOCSPResponse(CERTOCSPResponse *response) -{ - if (response != NULL) { - ocspSignature *signature = ocsp_GetResponseSignature(response); - if (signature && signature->cert != NULL) - CERT_DestroyCertificate(signature->cert); - - /* - * We should actually never have a response without an arena, - * but check just in case. (If there isn't one, there is not - * much we can do about it...) - */ - PORT_Assert(response->arena != NULL); - if (response->arena != NULL) { - PORT_FreeArena(response->arena, PR_FALSE); - } - } -} - - -/* - * OVERALL OCSP CLIENT SUPPORT (make and send a request, verify a response): - */ - - -/* - * Pick apart a URL, saving the important things in the passed-in pointers. - * - * We expect to find "http://<hostname>[:<port>]/[path]", though we will - * tolerate that final slash character missing, as well as beginning and - * trailing whitespace, and any-case-characters for "http". All of that - * tolerance is what complicates this routine. What we want is just to - * pick out the hostname, the port, and the path. - * - * On a successful return, the caller will need to free the output pieces - * of hostname and path, which are copies of the values found in the url. - */ -static SECStatus -ocsp_ParseURL(char *url, char **pHostname, PRUint16 *pPort, char **pPath) -{ - unsigned short port = 80; /* default, in case not in url */ - char *hostname = NULL; - char *path = NULL; - char *save; - char c; - int len; - - if (url == NULL) - goto loser; - - /* - * Skip beginning whitespace. - */ - c = *url; - while ((c == ' ' || c == '\t') && c != '\0') { - url++; - c = *url; - } - if (c == '\0') - goto loser; - - /* - * Confirm, then skip, protocol. (Since we only know how to do http, - * that is all we will accept). - */ - if (PORT_Strncasecmp(url, "http://", 7) != 0) - goto loser; - url += 7; - - /* - * Whatever comes next is the hostname (or host IP address). We just - * save it aside and then search for its end so we can determine its - * length and copy it. - * - * XXX Note that because we treat a ':' as a terminator character - * (and below, we expect that to mean there is a port specification - * immediately following), we will not handle IPv6 addresses. That is - * apparently an acceptable limitation, for the time being. Some day, - * when there is a clear way to specify a URL with an IPv6 address that - * can be parsed unambiguously, this code should be made to do that. - */ - save = url; - c = *url; - while (c != '/' && c != ':' && c != '\0' && c != ' ' && c != '\t') { - url++; - c = *url; - } - len = url - save; - hostname = PORT_Alloc(len + 1); - if (hostname == NULL) - goto loser; - PORT_Memcpy(hostname, save, len); - hostname[len] = '\0'; - - /* - * Now we figure out if there was a port specified or not. - * If so, we need to parse it (as a number) and skip it. - */ - if (c == ':') { - url++; - port = (unsigned short) PORT_Atoi(url); - c = *url; - while (c != '/' && c != '\0' && c != ' ' && c != '\t') { - if (c < '0' || c > '9') - goto loser; - url++; - c = *url; - } - } - - /* - * Last thing to find is a path. There *should* be a slash, - * if nothing else -- but if there is not we provide one. - */ - if (c == '/') { - save = url; - while (c != '\0' && c != ' ' && c != '\t') { - url++; - c = *url; - } - len = url - save; - path = PORT_Alloc(len + 1); - if (path == NULL) - goto loser; - PORT_Memcpy(path, save, len); - path[len] = '\0'; - } else { - path = PORT_Strdup("/"); - } - - *pHostname = hostname; - *pPort = port; - *pPath = path; - return SECSuccess; - -loser: - if (hostname != NULL) - PORT_Free(hostname); - if (path != NULL) - PORT_Free(path); - PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); - return SECFailure; -} - -/* - * Open a socket to the specified host on the specified port, and return it. - * The host is either a hostname or an IP address. - */ -static PRFileDesc * -ocsp_ConnectToHost(const char *host, PRUint16 port) -{ - PRFileDesc *sock = NULL; - PRIntervalTime timeout; - PRNetAddr addr; - char *netdbbuf = NULL; - - sock = PR_NewTCPSocket(); - if (sock == NULL) - goto loser; - - /* XXX Some day need a way to set (and get?) the following value */ - timeout = PR_SecondsToInterval(30); - - /* - * If the following converts an IP address string in "dot notation" - * into a PRNetAddr. If it fails, we assume that is because we do not - * have such an address, but instead a host *name*. In that case we - * then lookup the host by name. Using the NSPR function this way - * means we do not have to have our own logic for distinguishing a - * valid numerical IP address from a hostname. - */ - if (PR_StringToNetAddr(host, &addr) != PR_SUCCESS) { - PRIntn hostIndex; - PRHostEnt hostEntry; - - netdbbuf = PORT_Alloc(PR_NETDB_BUF_SIZE); - if (netdbbuf == NULL) - goto loser; - - if (PR_GetHostByName(host, netdbbuf, PR_NETDB_BUF_SIZE, - &hostEntry) != PR_SUCCESS) - goto loser; - - hostIndex = 0; - do { - hostIndex = PR_EnumerateHostEnt(hostIndex, &hostEntry, port, &addr); - if (hostIndex < 0) - goto loser; - } while (PR_Connect(sock, &addr, timeout) != PR_SUCCESS - && hostIndex > 0); - - if (hostIndex == 0) - goto loser; - - PORT_Free(netdbbuf); - } else { - /* - * First put the port into the address, then connect. - */ - if (PR_InitializeNetAddr(PR_IpAddrNull, port, &addr) != PR_SUCCESS) - goto loser; - if (PR_Connect(sock, &addr, timeout) != PR_SUCCESS) - goto loser; - } - - return sock; - -loser: - if (sock != NULL) - PR_Close(sock); - if (netdbbuf != NULL) - PORT_Free(netdbbuf); - return NULL; -} - -/* - * Sends an encoded OCSP request to the server identified by "location", - * and returns the socket on which it was sent (so can listen for the reply). - * "location" is expected to be a valid URL -- an error parsing it produces - * SEC_ERROR_CERT_BAD_ACCESS_LOCATION. Other errors are likely problems - * connecting to it, or writing to it, or allocating memory, and the low-level - * errors appropriate to the problem will be set. - */ -static PRFileDesc * -ocsp_SendEncodedRequest(char *location, SECItem *encodedRequest) -{ - char *hostname = NULL; - char *path = NULL; - PRUint16 port; - SECStatus rv; - PRFileDesc *sock = NULL; - PRFileDesc *returnSock = NULL; - char *header = NULL; - - /* - * Take apart the location, getting the hostname, port, and path. - */ - rv = ocsp_ParseURL(location, &hostname, &port, &path); - if (rv != SECSuccess) - goto loser; - - PORT_Assert(hostname != NULL); - PORT_Assert(path != NULL); - - sock = ocsp_ConnectToHost(hostname, port); - if (sock == NULL) - goto loser; - - header = PR_smprintf("POST %s HTTP/1.0\r\n" - "Host: %s:%d\r\n" - "Content-Type: application/ocsp-request\r\n" - "Content-Length: %u\r\n\r\n", - path, hostname, port, encodedRequest->len); - if (header == NULL) - goto loser; - - /* - * The NSPR documentation promises that if it can, it will write the full - * amount; this will not return a partial value expecting us to loop. - */ - if (PR_Write(sock, header, (PRInt32) PORT_Strlen(header)) < 0) - goto loser; - - if (PR_Write(sock, encodedRequest->data, - (PRInt32) encodedRequest->len) < 0) - goto loser; - - returnSock = sock; - sock = NULL; - -loser: - if (header != NULL) - PORT_Free(header); - if (sock != NULL) - PR_Close(sock); - if (path != NULL) - PORT_Free(path); - if (hostname != NULL) - PORT_Free(hostname); - - return returnSock; -} - -/* - * Read from "fd" into "buf" -- expect/attempt to read a given number of bytes - * Obviously, stop if hit end-of-stream. Timeout is passed in. - */ - -static int -ocsp_read(PRFileDesc *fd, char *buf, int toread, PRIntervalTime timeout) -{ - int total = 0; - - while (total < toread) - { - PRInt32 got; - - got = PR_Recv(fd, buf + total, (PRInt32) (toread - total), 0, timeout); - if (got < 0) - { - if (0 == total) - { - total = -1; /* report the error if we didn't read anything yet */ - } - break; - } - else - if (got == 0) - { /* EOS */ - break; - } - - total += got; - } - - return total; -} - -#define OCSP_BUFSIZE 1024 - -#define AbortHttpDecode(error) \ -{ \ - if (inBuffer) \ - PORT_Free(inBuffer); \ - PORT_SetError(error); \ - return NULL; \ -} - - -/* - * Reads on the given socket and returns an encoded response when received. - * Properly formatted HTTP/1.0 response headers are expected to be read - * from the socket, preceding a binary-encoded OCSP response. Problems - * with parsing cause the error SEC_ERROR_OCSP_BAD_HTTP_RESPONSE to be - * set; any other problems are likely low-level i/o or memory allocation - * errors. - */ -static SECItem * -ocsp_GetEncodedResponse(PRArenaPool *arena, PRFileDesc *sock) -{ - /* first read HTTP status line and headers */ - - char* inBuffer = NULL; - PRInt32 offset = 0; - PRInt32 inBufsize = 0; - const PRInt32 bufSizeIncrement = OCSP_BUFSIZE; /* 1 KB at a time */ - const PRInt32 maxBufSize = 8 * bufSizeIncrement ; /* 8 KB max */ - const char* CRLF = "\r\n"; - const PRInt32 CRLFlen = strlen(CRLF); - const char* headerEndMark = "\r\n\r\n"; - const PRInt32 markLen = strlen(headerEndMark); - const PRIntervalTime ocsptimeout = - PR_SecondsToInterval(30); /* hardcoded to 30s for now */ - char* headerEnd = NULL; - PRBool EOS = PR_FALSE; - const char* httpprotocol = "HTTP/"; - const PRInt32 httplen = strlen(httpprotocol); - const char* httpcode = NULL; - const char* contenttype = NULL; - PRInt32 contentlength = 0; - PRInt32 bytesRead = 0; - char* statusLineEnd = NULL; - char* space = NULL; - char* nextHeader = NULL; - SECItem* result = NULL; - - /* read up to at least the end of the HTTP headers */ - do - { - inBufsize += bufSizeIncrement; - inBuffer = PORT_Realloc(inBuffer, inBufsize+1); - if (NULL == inBuffer) - { - AbortHttpDecode(SEC_ERROR_NO_MEMORY); - } - bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement, - ocsptimeout); - if (bytesRead > 0) - { - PRInt32 searchOffset = (offset - markLen) >0 ? offset-markLen : 0; - offset += bytesRead; - *(inBuffer + offset) = '\0'; /* NULL termination */ - headerEnd = strstr((const char*)inBuffer + searchOffset, headerEndMark); - if (bytesRead < bufSizeIncrement) - { - /* we read less data than requested, therefore we are at - EOS or there was a read error */ - EOS = PR_TRUE; - } - } - else - { - /* recv error or EOS */ - EOS = PR_TRUE; - } - } while ( (!headerEnd) && (PR_FALSE == EOS) && - (inBufsize < maxBufSize) ); - - if (!headerEnd) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - - /* parse the HTTP status line */ - statusLineEnd = strstr((const char*)inBuffer, CRLF); - if (!statusLineEnd) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - *statusLineEnd = '\0'; - - /* check for HTTP/ response */ - space = strchr((const char*)inBuffer, ' '); - if (!space || PORT_Strncasecmp((const char*)inBuffer, httpprotocol, httplen) != 0 ) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - - /* check the HTTP status code of 200 */ - httpcode = space +1; - space = strchr(httpcode, ' '); - if (!space) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - *space = 0; - if (0 != strcmp(httpcode, "200")) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - - /* parse the HTTP headers in the buffer . We only care about - content-type and content-length - */ - - nextHeader = statusLineEnd + CRLFlen; - *headerEnd = '\0'; /* terminate */ - do - { - char* thisHeaderEnd = NULL; - char* value = NULL; - char* colon = strchr(nextHeader, ':'); - - if (!colon) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - - *colon = '\0'; - value = colon + 1; - - /* jpierre - note : the following code will only handle the basic form - of HTTP/1.0 response headers, of the form "name: value" . Headers - split among multiple lines are not supported. This is not common - and should not be an issue, but it could become one in the - future */ - - if (*value != ' ') - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - - value++; - thisHeaderEnd = strstr(value, CRLF); - if (thisHeaderEnd ) - { - *thisHeaderEnd = '\0'; - } - - if (0 == PORT_Strcasecmp(nextHeader, "content-type")) - { - contenttype = value; - } - else - if (0 == PORT_Strcasecmp(nextHeader, "content-length")) - { - contentlength = atoi(value); - } - - if (thisHeaderEnd ) - { - nextHeader = thisHeaderEnd + CRLFlen; - } - else - { - nextHeader = NULL; - } - - } while (nextHeader && (nextHeader < (headerEnd + CRLFlen) ) ); - - /* check content-type */ - if (!contenttype || - (0 != PORT_Strcasecmp(contenttype, "application/ocsp-response")) ) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - - /* read the body of the OCSP response */ - offset = offset - (PRInt32) (headerEnd - (const char*)inBuffer) - markLen; - if (offset) - { - /* move all data to the beginning of the buffer */ - PORT_Memmove(inBuffer, headerEnd + markLen, offset); - } - - /* resize buffer to only what's needed to hold the current response */ - inBufsize = (1 + (offset-1) / bufSizeIncrement ) * bufSizeIncrement ; - - while ( (PR_FALSE == EOS) && - ( (contentlength == 0) || (offset < contentlength) ) && - (inBufsize < maxBufSize) - ) - { - /* we still need to receive more body data */ - inBufsize += bufSizeIncrement; - inBuffer = PORT_Realloc(inBuffer, inBufsize+1); - if (NULL == inBuffer) - { - AbortHttpDecode(SEC_ERROR_NO_MEMORY); - } - bytesRead = ocsp_read(sock, inBuffer + offset, bufSizeIncrement, - ocsptimeout); - if (bytesRead > 0) - { - offset += bytesRead; - if (bytesRead < bufSizeIncrement) - { - /* we read less data than requested, therefore we are at - EOS or there was a read error */ - EOS = PR_TRUE; - } - } - else - { - /* recv error or EOS */ - EOS = PR_TRUE; - } - } - - if (0 == offset) - { - AbortHttpDecode(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); - } - - /* - * Now allocate the item to hold the data. - */ - result = SECITEM_AllocItem(arena, NULL, offset); - if (NULL == result) - { - AbortHttpDecode(SEC_ERROR_NO_MEMORY); - } - - /* - * And copy the data left in the buffer. - */ - PORT_Memcpy(result->data, inBuffer, offset); - - /* and free the temporary buffer */ - PORT_Free(inBuffer); - return result; -} - - -/* - * FUNCTION: CERT_GetEncodedOCSPResponse - * Creates and sends a request to an OCSP responder, then reads and - * returns the (encoded) response. - * INPUTS: - * PRArenaPool *arena - * Pointer to arena from which return value will be allocated. - * If NULL, result will be allocated from the heap (and thus should - * be freed via SECITEM_FreeItem). - * CERTCertList *certList - * A list of certs for which status will be requested. - * Note that all of these certificates should have the same issuer, - * or it's expected the response will be signed by a trusted responder. - * If the certs need to be broken up into multiple requests, that - * must be handled by the caller (and thus by having multiple calls - * to this routine), who knows about where the request(s) are being - * sent and whether there are any trusted responders in place. - * char *location - * The location of the OCSP responder (a URL). - * int64 time - * Indicates the time for which the certificate status is to be - * determined -- this may be used in the search for the cert's issuer - * but has no other bearing on the operation. - * PRBool addServiceLocator - * If true, the Service Locator extension should be added to the - * single request(s) for each cert. - * CERTCertificate *signerCert - * If non-NULL, means sign the request using this cert. Otherwise, - * do not sign. - * void *pwArg - * Pointer to argument for password prompting, if needed. (Definitely - * not needed if not signing.) - * OUTPUTS: - * CERTOCSPRequest **pRequest - * Pointer in which to store the OCSP request created for the given - * list of certificates. It is only filled in if the entire operation - * is successful and the pointer is not null -- and in that case the - * caller is then reponsible for destroying it. - * RETURN: - * Returns a pointer to the SECItem holding the response. - * On error, returns null with error set describing the reason: - * SEC_ERROR_UNKNOWN_ISSUER - * SEC_ERROR_CERT_BAD_ACCESS_LOCATION - * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE - * Other errors are low-level problems (no memory, bad database, etc.). - */ -SECItem * -CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, - char *location, int64 time, - PRBool addServiceLocator, - CERTCertificate *signerCert, void *pwArg, - CERTOCSPRequest **pRequest) -{ - CERTOCSPRequest *request = NULL; - SECItem *encodedRequest = NULL; - SECItem *encodedResponse = NULL; - PRFileDesc *sock = NULL; - SECStatus rv; - - request = CERT_CreateOCSPRequest(certList, time, addServiceLocator, - signerCert); - if (request == NULL) - goto loser; - - rv = CERT_AddOCSPAcceptableResponses(request, - SEC_OID_PKIX_OCSP_BASIC_RESPONSE); - if (rv != SECSuccess) - goto loser; - - encodedRequest = CERT_EncodeOCSPRequest(NULL, request, pwArg); - if (encodedRequest == NULL) - goto loser; - - sock = ocsp_SendEncodedRequest(location, encodedRequest); - if (sock == NULL) - goto loser; - - encodedResponse = ocsp_GetEncodedResponse(arena, sock); - if (encodedResponse != NULL && pRequest != NULL) { - *pRequest = request; - request = NULL; /* avoid destroying below */ - } - -loser: - if (request != NULL) - CERT_DestroyOCSPRequest(request); - if (encodedRequest != NULL) - SECITEM_FreeItem(encodedRequest, PR_TRUE); - if (sock != NULL) - PR_Close(sock); - - return encodedResponse; -} - - -/* Checks a certificate for the key usage extension of OCSP signer. */ -static PRBool -ocsp_CertIsOCSPSigner(CERTCertificate *cert) -{ - SECStatus rv; - SECItem extItem; - SECItem **oids; - SECItem *oid; - SECOidTag oidTag; - PRBool retval; - CERTOidSequence *oidSeq = NULL; - - - 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 ) { - oid = *oids; - - oidTag = SECOID_FindOIDTag(oid); - - if ( oidTag == SEC_OID_OCSP_RESPONDER ) { - goto success; - } - - oids++; - } - -loser: - retval = PR_FALSE; - goto done; -success: - retval = PR_TRUE; -done: - if ( extItem.data != NULL ) { - PORT_Free(extItem.data); - } - if ( oidSeq != NULL ) { - CERT_DestroyOidSequence(oidSeq); - } - - return(retval); -} - - -#ifdef LATER /* - * XXX This function is not currently used, but will - * be needed later when we do revocation checking of - * the responder certificate. Of course, it may need - * revising then, if the cert extension interface has - * changed. (Hopefully it will!) - */ - -/* Checks a certificate to see if it has the OCSP no check extension. */ -static PRBool -ocsp_CertHasNoCheckExtension(CERTCertificate *cert) -{ - SECStatus rv; - SECItem extItem; - - extItem.data = NULL; - rv = CERT_FindCertExtension(cert, SEC_OID_PKIX_OCSP_NO_CHECK, - &extItem); - if (extItem.data != NULL) { - PORT_Free(extItem.data); - } - if (rv == SECSuccess) { - return PR_TRUE; - } - return PR_FALSE; -} -#endif /* LATER */ - -static PRBool -ocsp_matchcert(SECItem *certIndex,CERTCertificate *testCert) -{ - SECItem item; - unsigned char buf[SHA1_LENGTH]; /* MAX Hash Len */ - - item.data = buf; - item.len = SHA1_LENGTH; - - if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_SHA1, &item) == NULL) { - return PR_FALSE; - } - if (SECITEM_ItemsAreEqual(certIndex,&item)) { - return PR_TRUE; - } - if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_MD5, &item) == NULL) { - return PR_FALSE; - } - if (SECITEM_ItemsAreEqual(certIndex,&item)) { - return PR_TRUE; - } - if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_MD2, &item) == NULL) { - return PR_FALSE; - } - if (SECITEM_ItemsAreEqual(certIndex,&item)) { - return PR_TRUE; - } - - return PR_FALSE; -} - -static CERTCertificate * -ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID); - -/* - * Check the signature on some OCSP data. This is a helper function that - * can be used to check either a request or a response. The result is - * saved in the signature structure itself for future reference (to avoid - * repeating the expensive verification operation), as well as returned. - * In addition to checking the signature, the certificate (and its chain) - * are also checked for validity (at the specified time) and usage. - * - * The type of cert lookup to be performed is specified by "lookupByName": - * if true, then "certIndex" is actually a CERTName; otherwise it is a - * SECItem which contains a key hash. - * - * If the signature verifies okay, and the argument "pSignerCert" is not - * null, that parameter will be filled-in with a pointer to the signer's - * certificate. The caller is then responsible for destroying the cert. - * - * A return of SECSuccess means the verification succeeded. If not, - * an error will be set with the reason. Most likely are: - * SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found - * SEC_ERROR_BAD_SIGNATURE - the signature did not verify - * Other errors are any of the many possible failures in cert verification - * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when - * verifying the signer's cert, or low-level problems (no memory, etc.) - */ -static SECStatus -ocsp_CheckSignature(ocspSignature *signature, void *tbs, - const SEC_ASN1Template *encodeTemplate, - CERTCertDBHandle *handle, SECCertUsage certUsage, - int64 checkTime, PRBool lookupByName, void *certIndex, - void *pwArg, CERTCertificate **pSignerCert, - CERTCertificate *issuer) -{ - SECItem rawSignature; - SECItem *encodedTBS = NULL; - CERTCertificate *responder = NULL; - CERTCertificate *signerCert = NULL; - SECKEYPublicKey *signerKey = NULL; - CERTCertificate **certs = NULL; - SECStatus rv = SECFailure; - int certCount; - int i; - - /* - * If this signature has already gone through verification, just - * return the cached result. - */ - if (signature->wasChecked) { - if (signature->status == SECSuccess) { - if (pSignerCert != NULL) - *pSignerCert = CERT_DupCertificate(signature->cert); - } else { - PORT_SetError(signature->failureReason); - } - return signature->status; - } - - /* - * If the signature contains some certificates as well, temporarily - * import them in case they are needed for verification. - * - * Note that the result of this is that each cert in "certs" needs - * to be destroyed. - */ - certCount = 0; - if (signature->derCerts != NULL) { - for (; signature->derCerts[certCount] != NULL; certCount++) { - /* just counting */ - /*IMPORT CERT TO SPKI TABLE */ - } - } - rv = CERT_ImportCerts(handle, certUsage, certCount, - signature->derCerts, &certs, - PR_FALSE, PR_FALSE, NULL); - if (rv != SECSuccess) - goto finish; - - /* - * Now look up the certificate that did the signing. - * The signer can be specified either by name or by key hash. - */ - if (lookupByName) { - SECItem *encodedName; - - encodedName = SEC_ASN1EncodeItem(NULL, NULL, certIndex, - CERT_NameTemplate); - if (encodedName == NULL) - goto finish; - - signerCert = CERT_FindCertByName(handle, encodedName); - SECITEM_FreeItem(encodedName, PR_TRUE); - } else { - /* - * The signer is either 1) a known issuer CA we passed in, - * 2) the default OCSP responder, or 3) and intermediate CA - * passed in the cert list to use. Figure out which it is. - */ - responder = ocsp_CertGetDefaultResponder(handle,NULL); - if (responder && ocsp_matchcert(certIndex,responder)) { - signerCert = CERT_DupCertificate(responder); - } else if (issuer && ocsp_matchcert(certIndex,issuer)) { - signerCert = CERT_DupCertificate(issuer); - } - for (i=0; (signerCert == NULL) && (i < certCount); i++) { - if (ocsp_matchcert(certIndex,certs[i])) { - signerCert = CERT_DupCertificate(certs[i]); - } - } - } - - if (signerCert == NULL) { - rv = SECFailure; - if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) { - /* Make the error a little more specific. */ - PORT_SetError(SEC_ERROR_UNKNOWN_SIGNER); - } - goto finish; - } - - /* - * We could mark this true at the top of this function, or always - * below at "finish", but if the problem was just that we could not - * find the signer's cert, leave that as if the signature hasn't - * been checked in case a subsequent call might have better luck. - */ - signature->wasChecked = PR_TRUE; - - /* - * Just because we have a cert does not mean it is any good; check - * it for validity, trust and usage. - */ - rv = CERT_VerifyCert(handle, signerCert, PR_TRUE, certUsage, checkTime, - pwArg, NULL); - if (rv != SECSuccess) - goto finish; - - /* - * Now get the public key from the signer's certificate; we need - * it to perform the verification. - */ - signerKey = CERT_ExtractPublicKey(signerCert); - if (signerKey == NULL) - goto finish; - - /* - * Prepare the data to be verified; it needs to be DER encoded first. - */ - encodedTBS = SEC_ASN1EncodeItem(NULL, NULL, tbs, encodeTemplate); - if (encodedTBS == NULL) - goto finish; - - /* - * We copy the signature data *pointer* and length, so that we can - * modify the length without damaging the original copy. This is a - * simple copy, not a dup, so no destroy/free is necessary. - */ - rawSignature = signature->signature; - /* - * The raw signature is a bit string, but we need to represent its - * length in bytes, because that is what the verify function expects. - */ - DER_ConvertBitString(&rawSignature); - - rv = VFY_VerifyData(encodedTBS->data, encodedTBS->len, signerKey, - &rawSignature, - SECOID_GetAlgorithmTag(&signature->signatureAlgorithm), - pwArg); - -finish: - if (signature->wasChecked) - signature->status = rv; - - if (rv != SECSuccess) { - signature->failureReason = PORT_GetError(); - if (signerCert != NULL) - CERT_DestroyCertificate(signerCert); - } else { - /* - * Save signer's certificate in signature. - */ - signature->cert = signerCert; - if (pSignerCert != NULL) { - /* - * Pass pointer to signer's certificate back to our caller, - * who is also now responsible for destroying it. - */ - *pSignerCert = CERT_DupCertificate(signerCert); - } - } - - if (encodedTBS != NULL) - SECITEM_FreeItem(encodedTBS, PR_TRUE); - - if (signerKey != NULL) - SECKEY_DestroyPublicKey(signerKey); - - if (certs != NULL) - CERT_DestroyCertArray(certs, certCount); - /* Free CERTS from SPKDigest Table */ - - return rv; -} - - -/* - * FUNCTION: CERT_VerifyOCSPResponseSignature - * Check the signature on an OCSP Response. Will also perform a - * verification of the signer's certificate. Note, however, that a - * successful verification does not make any statement about the - * signer's *authority* to provide status for the certificate(s), - * that must be checked individually for each certificate. - * INPUTS: - * CERTOCSPResponse *response - * Pointer to response structure with signature to be checked. - * CERTCertDBHandle *handle - * Pointer to CERTCertDBHandle for certificate DB to use for verification. - * void *pwArg - * Pointer to argument for password prompting, if needed. - * OUTPUTS: - * CERTCertificate **pSignerCert - * Pointer in which to store signer's certificate; only filled-in if - * non-null. - * RETURN: - * Returns SECSuccess when signature is valid, anything else means invalid. - * Possible errors set: - * SEC_ERROR_OCSP_MALFORMED_RESPONSE - unknown type of ResponderID - * SEC_ERROR_INVALID_TIME - bad format of "ProducedAt" time - * SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found - * SEC_ERROR_BAD_SIGNATURE - the signature did not verify - * Other errors are any of the many possible failures in cert verification - * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when - * verifying the signer's cert, or low-level problems (no memory, etc.) - */ -SECStatus -CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response, - CERTCertDBHandle *handle, void *pwArg, - CERTCertificate **pSignerCert, - CERTCertificate *issuer) -{ - ocspResponseData *tbsData; /* this is what is signed */ - PRBool byName; - void *certIndex; - int64 producedAt; - SECStatus rv; - - tbsData = ocsp_GetResponseData(response); - - PORT_Assert(tbsData->responderID != NULL); - switch (tbsData->responderID->responderIDType) { - case ocspResponderID_byName: - byName = PR_TRUE; - certIndex = &tbsData->responderID->responderIDValue.name; - break; - case ocspResponderID_byKey: - byName = PR_FALSE; - certIndex = &tbsData->responderID->responderIDValue.keyHash; - break; - case ocspResponderID_other: - default: - PORT_Assert(0); - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); - return SECFailure; - } - - /* - * ocsp_CheckSignature will also verify the signer certificate; we - * need to tell it *when* that certificate must be valid -- for our - * purposes we expect it to be valid when the response was signed. - * The value of "producedAt" is the signing time. - */ - rv = DER_GeneralizedTimeToTime(&producedAt, &tbsData->producedAt); - if (rv != SECSuccess) - return rv; - - return ocsp_CheckSignature(ocsp_GetResponseSignature(response), - tbsData, ocsp_ResponseDataTemplate, - handle, certUsageStatusResponder, producedAt, - byName, certIndex, pwArg, pSignerCert, issuer); -} - -/* - * See if two certIDs match. This can be easy or difficult, depending - * on whether the same hash algorithm was used. - */ -static PRBool -ocsp_CertIDsMatch(CERTCertDBHandle *handle, - CERTOCSPCertID *certID1, CERTOCSPCertID *certID2) -{ - PRBool match = PR_FALSE; - SECItem *foundHash = NULL; - SECOidTag hashAlg; - SECItem *keyHash = NULL; - SECItem *nameHash = NULL; - - /* - * In order to match, they must have the same issuer and the same - * serial number. - * - * We just compare the easier things first. - */ - if (SECITEM_CompareItem(&certID1->serialNumber, - &certID2->serialNumber) != SECEqual) { - goto done; - } - - if (SECOID_CompareAlgorithmID(&certID1->hashAlgorithm, - &certID2->hashAlgorithm) == SECEqual) { - /* - * If the hash algorithms match then we can do a simple compare - * of the hash values themselves. - */ - if ((SECITEM_CompareItem(&certID1->issuerNameHash, - &certID2->issuerNameHash) == SECEqual) - && (SECITEM_CompareItem(&certID1->issuerKeyHash, - &certID2->issuerKeyHash) == SECEqual)) { - match = PR_TRUE; - } - goto done; - } - - hashAlg = SECOID_FindOIDTag(&certID2->hashAlgorithm.algorithm); - switch (hashAlg) { - case SEC_OID_SHA1: - keyHash = &certID1->issuerSHA1KeyHash; - nameHash = &certID1->issuerSHA1NameHash; - break; - case SEC_OID_MD5: - keyHash = &certID1->issuerMD5KeyHash; - nameHash = &certID1->issuerMD5NameHash; - break; - case SEC_OID_MD2: - keyHash = &certID1->issuerMD2KeyHash; - nameHash = &certID1->issuerMD2NameHash; - break; - default: - foundHash = NULL; - break; - } - - if (foundHash == NULL) { - goto done; - } - PORT_Assert(keyHash && nameHash); - - if ((SECITEM_CompareItem(nameHash, &certID2->issuerNameHash) == SECEqual) - && (SECITEM_CompareItem(keyHash, &certID2->issuerKeyHash) == SECEqual)) { - match = PR_TRUE; - } - -done: - return match; -} - -/* - * Find the single response for the cert specified by certID. - * No copying is done; this just returns a pointer to the appropriate - * response within responses, if it is found (and null otherwise). - * This is fine, of course, since this function is internal-use only. - */ -static CERTOCSPSingleResponse * -ocsp_GetSingleResponseForCertID(CERTOCSPSingleResponse **responses, - CERTCertDBHandle *handle, - CERTOCSPCertID *certID) -{ - CERTOCSPSingleResponse *single; - int i; - - if (responses == NULL) - return NULL; - - for (i = 0; responses[i] != NULL; i++) { - single = responses[i]; - if (ocsp_CertIDsMatch(handle, certID, single->certID) == PR_TRUE) { - return single; - } - } - - /* - * The OCSP server should have included a response even if it knew - * nothing about the certificate in question. Since it did not, - * this will make it look as if it had. - * - * XXX Should we make this a separate error to notice the server's - * bad behavior? - */ - PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT); - return NULL; -} - -static ocspCheckingContext * -ocsp_GetCheckingContext(CERTCertDBHandle *handle) -{ - CERTStatusConfig *statusConfig; - ocspCheckingContext *ocspcx = NULL; - - statusConfig = CERT_GetStatusConfig(handle); - if (statusConfig != NULL) { - ocspcx = statusConfig->statusContext; - - /* - * This is actually an internal error, because we should never - * have a good statusConfig without a good statusContext, too. - * For lack of anything better, though, we just assert and use - * the same error as if there were no statusConfig (set below). - */ - PORT_Assert(ocspcx != NULL); - } - - if (ocspcx == NULL) - PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED); - - return ocspcx; -} -/* - * Return true if the given signerCert is the default responder for - * the given certID. If not, or if any error, return false. - */ -static CERTCertificate * -ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID) -{ - ocspCheckingContext *ocspcx; - - ocspcx = ocsp_GetCheckingContext(handle); - if (ocspcx == NULL) - goto loser; - - /* - * Right now we have only one default responder. It applies to - * all certs when it is used, so the check is simple and certID - * has no bearing on the answer. Someday in the future we may - * allow configuration of different responders for different - * issuers, and then we would have to use the issuer specified - * in certID to determine if signerCert is the right one. - */ - if (ocspcx->useDefaultResponder) { - PORT_Assert(ocspcx->defaultResponderCert != NULL); - return ocspcx->defaultResponderCert; - } - -loser: - return NULL; -} - -/* - * Return true if the given signerCert is the default responder for - * the given certID. If not, or if any error, return false. - */ -static PRBool -ocsp_CertIsDefaultResponderForCertID(CERTCertDBHandle *handle, - CERTCertificate *signerCert, - CERTOCSPCertID *certID) -{ - CERTCertificate *defaultResponderCert; - - defaultResponderCert = ocsp_CertGetDefaultResponder(handle, certID); - return (PRBool) (defaultResponderCert == signerCert); -} - -/* - * Check that the given signer certificate is authorized to sign status - * information for the given certID. Return true if it is, false if not - * (or if there is any error along the way). If false is returned because - * the signer is not authorized, the following error will be set: - * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE - * Other errors are low-level problems (no memory, bad database, etc.). - * - * There are three ways to be authorized. In the order in which we check, - * using the terms used in the OCSP spec, the signer must be one of: - * 1. A "trusted responder" -- it matches a local configuration - * of OCSP signing authority for the certificate in question. - * 2. The CA who issued the certificate in question. - * 3. A "CA designated responder", aka an "authorized responder" -- it - * must be represented by a special cert issued by the CA who issued - * the certificate in question. - */ -static PRBool -ocsp_AuthorizedResponderForCertID(CERTCertDBHandle *handle, - CERTCertificate *signerCert, - CERTOCSPCertID *certID, - int64 thisUpdate) -{ - CERTCertificate *issuerCert = NULL; - SECItem *issuerKeyHash = NULL; - SECOidTag hashAlg; - PRBool okay = PR_FALSE; - - /* - * Check first for a trusted responder, which overrides everything else. - */ - if (ocsp_CertIsDefaultResponderForCertID(handle, signerCert, certID)) - return PR_TRUE; - - /* - * In the other two cases, we need to do an issuer comparison. - * How we do it depends on whether the signer certificate has the - * special extension (for a designated responder) or not. - */ - - if (ocsp_CertIsOCSPSigner(signerCert)) { - /* - * The signer is a designated responder. Its issuer must match - * the issuer of the cert being checked. - */ - issuerCert = CERT_FindCertIssuer(signerCert, thisUpdate, - certUsageAnyCA); - if (issuerCert == NULL) { - /* - * We could leave the SEC_ERROR_UNKNOWN_ISSUER error alone, - * but the following will give slightly more information. - * Once we have an error stack, things will be much better. - */ - PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE); - goto loser; - } - } else { - /* - * The signer must *be* the issuer of the cert being checked. - */ - issuerCert = signerCert; - } - - hashAlg = SECOID_FindOIDTag(&certID->hashAlgorithm.algorithm); - issuerKeyHash = CERT_SPKDigestValueForCert(NULL, issuerCert, hashAlg, NULL); - if (issuerKeyHash == NULL) - goto loser; - - if (SECITEM_CompareItem(issuerKeyHash, - &certID->issuerKeyHash) != SECEqual) { - PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE); - goto loser; - } - - okay = PR_TRUE; - -loser: - if (issuerKeyHash != NULL) - SECITEM_FreeItem(issuerKeyHash, PR_TRUE); - - if (issuerCert != NULL && issuerCert != signerCert) - CERT_DestroyCertificate(issuerCert); - - return okay; -} - -/* - * We need to check that a responder gives us "recent" information. - * Since a responder can pre-package responses, we need to pick an amount - * of time that is acceptable to us, and reject any response that is - * older than that. - * - * XXX This *should* be based on some configuration parameter, so that - * different usages could specify exactly what constitutes "sufficiently - * recent". But that is not going to happen right away. For now, we - * want something from within the last 24 hours. This macro defines that - * number in seconds. - */ -#define OCSP_ALLOWABLE_LAPSE_SECONDS (24L * 60L * 60L) - -static PRBool -ocsp_TimeIsRecent(int64 checkTime) -{ - int64 now = PR_Now(); - int64 lapse, tmp; - - LL_I2L(lapse, OCSP_ALLOWABLE_LAPSE_SECONDS); - LL_I2L(tmp, PR_USEC_PER_SEC); - LL_MUL(lapse, lapse, tmp); /* allowable lapse in microseconds */ - - LL_ADD(checkTime, checkTime, lapse); - if (LL_CMP(now, >, checkTime)) - return PR_FALSE; - - return PR_TRUE; -} - -#define OCSP_SLOP (5L*60L) /* OCSP responses are allowed to be 5 minutes - in the future by default */ - -static PRUint32 ocspsloptime = OCSP_SLOP; /* seconds */ - -/* - * Check that this single response is okay. A return of SECSuccess means: - * 1. The signer (represented by "signerCert") is authorized to give status - * for the cert represented by the individual response in "single". - * 2. The value of thisUpdate is earlier than now. - * 3. The value of producedAt is later than or the same as thisUpdate. - * 4. If nextUpdate is given: - * - The value of nextUpdate is later than now. - * - The value of producedAt is earlier than nextUpdate. - * Else if no nextUpdate: - * - The value of thisUpdate is fairly recent. - * - The value of producedAt is fairly recent. - * However we do not need to perform an explicit check for this last - * constraint because it is already guaranteed by checking that - * producedAt is later than thisUpdate and thisUpdate is recent. - * Oh, and any responder is "authorized" to say that a cert is unknown to it. - * - * If any of those checks fail, SECFailure is returned and an error is set: - * SEC_ERROR_OCSP_FUTURE_RESPONSE - * SEC_ERROR_OCSP_OLD_RESPONSE - * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE - * Other errors are low-level problems (no memory, bad database, etc.). - */ -static SECStatus -ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single, - CERTCertDBHandle *handle, - CERTCertificate *signerCert, - int64 producedAt) -{ - CERTOCSPCertID *certID = single->certID; - int64 now, thisUpdate, nextUpdate, tmstamp, tmp; - SECStatus rv; - - /* - * If all the responder said was that the given cert was unknown to it, - * that is a valid response. Not very interesting to us, of course, - * but all this function is concerned with is validity of the response, - * not the status of the cert. - */ - PORT_Assert(single->certStatus != NULL); - if (single->certStatus->certStatusType == ocspCertStatus_unknown) - return SECSuccess; - - /* - * We need to extract "thisUpdate" for use below and to pass along - * to AuthorizedResponderForCertID in case it needs it for doing an - * issuer look-up. - */ - rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate); - if (rv != SECSuccess) - return rv; - - /* - * First confirm that signerCert is authorized to give this status. - */ - if (ocsp_AuthorizedResponderForCertID(handle, signerCert, certID, - thisUpdate) != PR_TRUE) - return SECFailure; - - /* - * Now check the time stuff, as described above. - */ - now = PR_Now(); - /* allow slop time for future response */ - LL_UI2L(tmstamp, ocspsloptime); /* get slop time in seconds */ - LL_UI2L(tmp, PR_USEC_PER_SEC); - LL_MUL(tmstamp, tmstamp, tmp); /* convert the slop time to PRTime */ - LL_ADD(tmstamp, tmstamp, now); /* add current time to it */ - if (LL_CMP(thisUpdate, >, tmstamp) || LL_CMP(producedAt, <, thisUpdate)) { - PORT_SetError(SEC_ERROR_OCSP_FUTURE_RESPONSE); - return SECFailure; - } - if (single->nextUpdate != NULL) { - rv = DER_GeneralizedTimeToTime(&nextUpdate, single->nextUpdate); - if (rv != SECSuccess) - return rv; - - if (LL_CMP(nextUpdate, <, now) || LL_CMP(producedAt, >, nextUpdate)) { - PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE); - return SECFailure; - } - } else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) { - PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE); - return SECFailure; - } - - return SECSuccess; -} - - -/* - * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation - * Get the value of the URI of the OCSP responder for the given cert. - * This is found in the (optional) Authority Information Access extension - * in the cert. - * INPUTS: - * CERTCertificate *cert - * The certificate being examined. - * RETURN: - * char * - * A copy of the URI for the OCSP method, if found. If either the - * extension is not present or it does not contain an entry for OCSP, - * SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned. - * Any other error will also result in a NULL being returned. - * - * This result should be freed (via PORT_Free) when no longer in use. - */ -char * -CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert) -{ - CERTGeneralName *locname = NULL; - SECItem *location = NULL; - SECItem *encodedAuthInfoAccess = NULL; - CERTAuthInfoAccess **authInfoAccess = NULL; - char *locURI = NULL; - PRArenaPool *arena = NULL; - SECStatus rv; - int i; - - /* - * Allocate this one from the heap because it will get filled in - * by CERT_FindCertExtension which will also allocate from the heap, - * and we can free the entire thing on our way out. - */ - encodedAuthInfoAccess = SECITEM_AllocItem(NULL, NULL, 0); - if (encodedAuthInfoAccess == NULL) - goto loser; - - rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS, - encodedAuthInfoAccess); - if (rv == SECFailure) - goto loser; - - /* - * The rest of the things allocated in the routine will come out of - * this arena, which is temporary just for us to decode and get at the - * AIA extension. The whole thing will be destroyed on our way out, - * after we have copied the location string (url) itself (if found). - */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) - goto loser; - - authInfoAccess = cert_DecodeAuthInfoAccessExtension(arena, - encodedAuthInfoAccess); - if (authInfoAccess == NULL) - goto loser; - - for (i = 0; authInfoAccess[i] != NULL; i++) { - if (SECOID_FindOIDTag(&authInfoAccess[i]->method) == SEC_OID_PKIX_OCSP) - locname = authInfoAccess[i]->location; - } - - /* - * If we found an AIA extension, but it did not include an OCSP method, - * that should look to our caller as if we did not find the extension - * at all, because it is only an OCSP method that we care about. - * So set the same error that would be set if the AIA extension was - * not there at all. - */ - if (locname == NULL) { - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); - goto loser; - } - - /* - * The following is just a pointer back into locname (i.e. not a copy); - * thus it should not be freed. - */ - location = CERT_GetGeneralNameByType(locname, certURI, PR_FALSE); - if (location == NULL) { - /* - * XXX Appears that CERT_GetGeneralNameByType does not set an - * error if there is no name by that type. For lack of anything - * better, act as if the extension was not found. In the future - * this should probably be something more like the extension was - * badly formed. - */ - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); - goto loser; - } - - /* - * That location is really a string, but it has a specified length - * without a null-terminator. We need a real string that does have - * a null-terminator, and we need a copy of it anyway to return to - * our caller -- so allocate and copy. - */ - locURI = PORT_Alloc(location->len + 1); - if (locURI == NULL) { - goto loser; - } - PORT_Memcpy(locURI, location->data, location->len); - locURI[location->len] = '\0'; - -loser: - if (arena != NULL) - PORT_FreeArena(arena, PR_FALSE); - - if (encodedAuthInfoAccess != NULL) - SECITEM_FreeItem(encodedAuthInfoAccess, PR_TRUE); - - return locURI; -} - - -/* - * Figure out where we should go to find out the status of the given cert - * via OCSP. If a default responder is set up, that is our answer. - * If not, see if the certificate has an Authority Information Access (AIA) - * extension for OCSP, and return the value of that. Otherwise return NULL. - * We also let our caller know whether or not the responder chosen was - * a default responder or not through the output variable isDefault; - * its value has no meaning unless a good (non-null) value is returned - * for the location. - * - * The result needs to be freed (PORT_Free) when no longer in use. - */ -static char * -ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert, - PRBool *isDefault) -{ - ocspCheckingContext *ocspcx; - - ocspcx = ocsp_GetCheckingContext(handle); - if (ocspcx != NULL && ocspcx->useDefaultResponder) { - /* - * A default responder wins out, if specified. - * XXX Someday this may be a more complicated determination based - * on the cert's issuer. (That is, we could have different default - * responders configured for different issuers.) - */ - PORT_Assert(ocspcx->defaultResponderURI != NULL); - *isDefault = PR_TRUE; - return (PORT_Strdup(ocspcx->defaultResponderURI)); - } - - /* - * No default responder set up, so go see if we can find an AIA - * extension that has a value for OCSP, and get the url from that. - */ - *isDefault = PR_FALSE; - return CERT_GetOCSPAuthorityInfoAccessLocation(cert); -} - -/* - * Return SECSuccess if the cert was revoked *after* "time", - * SECFailure otherwise. - */ -static SECStatus -ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, int64 time) -{ - int64 revokedTime; - SECStatus rv; - - rv = DER_GeneralizedTimeToTime(&revokedTime, &revokedInfo->revocationTime); - if (rv != SECSuccess) - return rv; - - /* - * Set the error even if we will return success; someone might care. - */ - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - - if (LL_CMP(revokedTime, >, time)) - return SECSuccess; - - return SECFailure; -} - -/* - * See if the cert represented in the single response had a good status - * at the specified time. - */ -static SECStatus -ocsp_CertHasGoodStatus(CERTOCSPSingleResponse *single, int64 time) -{ - ocspCertStatus *status; - SECStatus rv; - - status = single->certStatus; - - switch (status->certStatusType) { - case ocspCertStatus_good: - rv = SECSuccess; - break; - case ocspCertStatus_revoked: - rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time); - break; - case ocspCertStatus_unknown: - PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT); - rv = SECFailure; - break; - case ocspCertStatus_other: - default: - PORT_Assert(0); - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE); - rv = SECFailure; - break; - } - - return rv; -} - - -/* - * FUNCTION: CERT_CheckOCSPStatus - * Checks the status of a certificate via OCSP. Will only check status for - * a certificate that has an AIA (Authority Information Access) extension - * for OCSP *or* when a "default responder" is specified and enabled. - * (If no AIA extension for OCSP and no default responder in place, the - * cert is considered to have a good status and SECSuccess is returned.) - * INPUTS: - * CERTCertDBHandle *handle - * certificate DB of the cert that is being checked - * CERTCertificate *cert - * the certificate being checked - * XXX in the long term also need a boolean parameter that specifies - * whether to check the cert chain, as well; for now we check only - * the leaf (the specified certificate) - * int64 time - * time for which status is to be determined - * void *pwArg - * argument for password prompting, if needed - * RETURN: - * Returns SECSuccess if an approved OCSP responder "knows" the cert - * *and* returns a non-revoked status for it; SECFailure otherwise, - * with an error set describing the reason: - * - * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE - * SEC_ERROR_OCSP_FUTURE_RESPONSE - * SEC_ERROR_OCSP_MALFORMED_REQUEST - * SEC_ERROR_OCSP_MALFORMED_RESPONSE - * SEC_ERROR_OCSP_OLD_RESPONSE - * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG - * SEC_ERROR_OCSP_SERVER_ERROR - * SEC_ERROR_OCSP_TRY_SERVER_LATER - * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST - * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE - * SEC_ERROR_OCSP_UNKNOWN_CERT - * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS - * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE - * - * SEC_ERROR_BAD_SIGNATURE - * SEC_ERROR_CERT_BAD_ACCESS_LOCATION - * SEC_ERROR_INVALID_TIME - * SEC_ERROR_REVOKED_CERTIFICATE - * SEC_ERROR_UNKNOWN_ISSUER - * SEC_ERROR_UNKNOWN_SIGNER - * - * Other errors are any of the many possible failures in cert verification - * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when - * verifying the signer's cert, or low-level problems (error allocating - * memory, error performing ASN.1 decoding, etc.). - */ -SECStatus -CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, - int64 time, void *pwArg) -{ - char *location = NULL; - PRBool locationIsDefault; - CERTCertList *certList = NULL; - SECItem *encodedResponse = NULL; - CERTOCSPRequest *request = NULL; - CERTOCSPResponse *response = NULL; - CERTCertificate *signerCert = NULL; - CERTCertificate *issuerCert = NULL; - CERTOCSPCertID *certID; - SECStatus rv = SECFailure; - - - /* - * The first thing we need to do is find the location of the responder. - * This will be the value of the default responder (if enabled), else - * it will come out of the AIA extension in the cert (if present). - * If we have no such location, then this cert does not "deserve" to - * be checked -- that is, we consider it a success and just return. - * The way we tell that is by looking at the error number to see if - * the problem was no AIA extension was found; any other error was - * a true failure that we unfortunately have to treat as an overall - * failure here. - */ - location = ocsp_GetResponderLocation(handle, cert, &locationIsDefault); - if (location == NULL) { - if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) - return SECSuccess; - else - return SECFailure; - } - - /* - * For now, create a cert-list of one. - * XXX In the fullness of time, we will want/need to handle a - * certificate chain. This will be done either when a new parameter - * tells us to, or some configuration variable tells us to. In any - * case, handling it is complicated because we may need to send as - * many requests (and receive as many responses) as we have certs - * in the chain. If we are going to talk to a default responder, - * and we only support one default responder, we can put all of the - * certs together into one request. Otherwise, we must break them up - * into multiple requests. (Even if all of the requests will go to - * the same location, the signature on each response will be different, - * because each issuer is different. Carefully read the OCSP spec - * if you do not understand this.) - */ - - certList = CERT_NewCertList(); - if (certList == NULL) - goto loser; - - /* dup it because freeing the list will destroy the cert, too */ - cert = CERT_DupCertificate(cert); - if (cert == NULL) - goto loser; - - if (CERT_AddCertToListTail(certList, cert) != SECSuccess) { - CERT_DestroyCertificate(cert); - goto loser; - } - - /* - * XXX If/when signing of requests is supported, that second NULL - * should be changed to be the signer certificate. Not sure if that - * should be passed into this function or retrieved via some operation - * on the handle/context. - */ - encodedResponse = CERT_GetEncodedOCSPResponse(NULL, certList, location, - time, locationIsDefault, - NULL, pwArg, &request); - if (encodedResponse == NULL) { - goto loser; - } - - response = CERT_DecodeOCSPResponse(encodedResponse); - if (response == NULL) { - goto loser; - } - - /* - * Okay, we at least have a response that *looks* like a response! - * Now see if the overall response status value is good or not. - * If not, we set an error and give up. (It means that either the - * server had a problem, or it didn't like something about our - * request. Either way there is nothing to do but give up.) - * Otherwise, we continue to find the actual per-cert status - * in the response. - */ - if (CERT_GetOCSPResponseStatus(response) != SECSuccess) { - goto loser; - } - - /* - * If we've made it this far, we expect a response with a good signature. - * So, check for that. - */ - issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA); - rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert, - issuerCert); - if (rv != SECSuccess) - goto loser; - - PORT_Assert(signerCert != NULL); /* internal consistency check */ - /* XXX probably should set error, return failure if signerCert is null */ - - - /* - * Again, we are only doing one request for one cert. - * XXX When we handle cert chains, the following code will obviously - * have to be modified, in coordation with the code above that will - * have to determine how to make multiple requests, etc. It will need - * to loop, and for each certID in the request, find the matching - * single response and check the status specified by it. - * - * We are helped here in that we know that the requests are made with - * the request list in the same order as the order of the certs we hand - * to it. This is why I can directly access the first member of the - * single request array for the one cert I care about. - */ - - certID = request->tbsRequest->requestList[0]->reqCert; - rv = CERT_GetOCSPStatusForCertID(handle, response, certID, - signerCert, time); -loser: - if (issuerCert != NULL) - CERT_DestroyCertificate(issuerCert); - if (signerCert != NULL) - CERT_DestroyCertificate(signerCert); - if (response != NULL) - CERT_DestroyOCSPResponse(response); - if (request != NULL) - CERT_DestroyOCSPRequest(request); - if (encodedResponse != NULL) - SECITEM_FreeItem(encodedResponse, PR_TRUE); - if (certList != NULL) - CERT_DestroyCertList(certList); - if (location != NULL) - PORT_Free(location); - return rv; -} - -SECStatus -CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle, - CERTOCSPResponse *response, - CERTOCSPCertID *certID, - CERTCertificate *signerCert, - int64 time) -{ - SECStatus rv; - ocspResponseData *responseData; - int64 producedAt; - CERTOCSPSingleResponse *single; - - /* - * The ResponseData part is the real guts of the response. - */ - responseData = ocsp_GetResponseData(response); - if (responseData == NULL) { - rv = SECFailure; - goto loser; - } - - /* - * There is one producedAt time for the entire response (and a separate - * thisUpdate time for each individual single response). We need to - * compare them, so get the overall time to pass into the check of each - * single response. - */ - rv = DER_GeneralizedTimeToTime(&producedAt, &responseData->producedAt); - if (rv != SECSuccess) - goto loser; - - single = ocsp_GetSingleResponseForCertID(responseData->responses, - handle, certID); - if (single == NULL) { - rv = SECFailure; - goto loser; - } - - rv = ocsp_VerifySingleResponse(single, handle, signerCert, producedAt); - if (rv != SECSuccess) - goto loser; - - /* - * Okay, the last step is to check whether the status says revoked, - * and if so how that compares to the time value passed into this routine. - */ - - rv = ocsp_CertHasGoodStatus(single, time); -loser: - return rv; -} - - -/* - * Disable status checking and destroy related structures/data. - */ -static SECStatus -ocsp_DestroyStatusChecking(CERTStatusConfig *statusConfig) -{ - ocspCheckingContext *statusContext; - - /* - * Disable OCSP checking - */ - statusConfig->statusChecker = NULL; - - statusContext = statusConfig->statusContext; - PORT_Assert(statusContext != NULL); - if (statusContext == NULL) - return SECFailure; - - if (statusContext->defaultResponderURI != NULL) - PORT_Free(statusContext->defaultResponderURI); - if (statusContext->defaultResponderNickname != NULL) - PORT_Free(statusContext->defaultResponderNickname); - - PORT_Free(statusContext); - statusConfig->statusContext = NULL; - - PORT_Free(statusConfig); - - return SECSuccess; -} - - -/* - * FUNCTION: CERT_DisableOCSPChecking - * Turns off OCSP checking for the given certificate database. - * This routine disables OCSP checking. Though it will return - * SECFailure if OCSP checking is not enabled, it is "safe" to - * call it that way and just ignore the return value, if it is - * easier to just call it than to "remember" whether it is enabled. - * INPUTS: - * CERTCertDBHandle *handle - * Certificate database for which OCSP checking will be disabled. - * RETURN: - * Returns SECFailure if an error occurred (usually means that OCSP - * checking was not enabled or status contexts were not initialized -- - * error set will be SEC_ERROR_OCSP_NOT_ENABLED); SECSuccess otherwise. - */ -SECStatus -CERT_DisableOCSPChecking(CERTCertDBHandle *handle) -{ - CERTStatusConfig *statusConfig; - ocspCheckingContext *statusContext; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - statusConfig = CERT_GetStatusConfig(handle); - statusContext = ocsp_GetCheckingContext(handle); - if (statusContext == NULL) - return SECFailure; - - if (statusConfig->statusChecker != CERT_CheckOCSPStatus) { - /* - * Status configuration is present, but either not currently - * enabled or not for OCSP. - */ - PORT_SetError(SEC_ERROR_OCSP_NOT_ENABLED); - return SECFailure; - } - - /* - * This is how we disable status checking. Everything else remains - * in place in case we are enabled again. - */ - statusConfig->statusChecker = NULL; - - return SECSuccess; -} - -/* - * Allocate and initialize the informational structures for status checking. - * This is done when some configuration of OCSP is being done or when OCSP - * checking is being turned on, whichever comes first. - */ -static SECStatus -ocsp_InitStatusChecking(CERTCertDBHandle *handle) -{ - CERTStatusConfig *statusConfig = NULL; - ocspCheckingContext *statusContext = NULL; - - PORT_Assert(CERT_GetStatusConfig(handle) == NULL); - if (CERT_GetStatusConfig(handle) != NULL) { - /* XXX or call statusConfig->statusDestroy and continue? */ - return SECFailure; - } - - statusConfig = PORT_ZNew(CERTStatusConfig); - if (statusConfig == NULL) - goto loser; - - statusContext = PORT_ZNew(ocspCheckingContext); - if (statusContext == NULL) - goto loser; - - statusConfig->statusDestroy = ocsp_DestroyStatusChecking; - statusConfig->statusContext = statusContext; - - CERT_SetStatusConfig(handle, statusConfig); - - return SECSuccess; - -loser: - if (statusContext != NULL) - PORT_Free(statusContext); - if (statusConfig != NULL) - PORT_Free(statusConfig); - return SECFailure; -} - - -/* - * FUNCTION: CERT_EnableOCSPChecking - * Turns on OCSP checking for the given certificate database. - * INPUTS: - * CERTCertDBHandle *handle - * Certificate database for which OCSP checking will be enabled. - * RETURN: - * Returns SECFailure if an error occurred (likely only problem - * allocating memory); SECSuccess otherwise. - */ -SECStatus -CERT_EnableOCSPChecking(CERTCertDBHandle *handle) -{ - CERTStatusConfig *statusConfig; - - SECStatus rv; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - statusConfig = CERT_GetStatusConfig(handle); - if (statusConfig == NULL) { - rv = ocsp_InitStatusChecking(handle); - if (rv != SECSuccess) - return rv; - - /* Get newly established value */ - statusConfig = CERT_GetStatusConfig(handle); - PORT_Assert(statusConfig != NULL); - } - - /* - * Setting the checker function is what really enables the checking - * when each cert verification is done. - */ - statusConfig->statusChecker = CERT_CheckOCSPStatus; - - return SECSuccess; -} - - -/* - * FUNCTION: CERT_SetOCSPDefaultResponder - * Specify the location and cert of the default responder. - * If OCSP checking is already enabled *and* use of a default responder - * is also already enabled, all OCSP checking from now on will go directly - * to the specified responder. If OCSP checking is not enabled, or if - * it is but use of a default responder is not enabled, the information - * will be recorded and take effect whenever both are enabled. - * INPUTS: - * CERTCertDBHandle *handle - * Cert database on which OCSP checking should use the default responder. - * char *url - * The location of the default responder (e.g. "http://foo.com:80/ocsp") - * Note that the location will not be tested until the first attempt - * to send a request there. - * char *name - * The nickname of the cert to trust (expected) to sign the OCSP responses. - * If the corresponding cert cannot be found, SECFailure is returned. - * RETURN: - * Returns SECFailure if an error occurred; SECSuccess otherwise. - * The most likely error is that the cert for "name" could not be found - * (probably SEC_ERROR_UNKNOWN_CERT). Other errors are low-level (no memory, - * bad database, etc.). - */ -SECStatus -CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle, - const char *url, const char *name) -{ - CERTCertificate *cert; - ocspCheckingContext *statusContext; - char *url_copy = NULL; - char *name_copy = NULL; - SECStatus rv; - - if (handle == NULL || url == NULL || name == NULL) { - /* - * XXX When interface is exported, probably want better errors; - * perhaps different one for each parameter. - */ - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - /* - * Find the certificate for the specified nickname. Do this first - * because it seems the most likely to fail. - * - * XXX Shouldn't need that cast if the FindCertByNickname interface - * used const to convey that it does not modify the name. Maybe someday. - */ - cert = CERT_FindCertByNickname(handle, (char *) name); - if (cert == NULL) { - /* - * look for the cert on an external token. - */ - cert = PK11_FindCertFromNickname((char *)name, NULL); - } - if (cert == NULL) - return SECFailure; - - /* - * Make a copy of the url and nickname. - */ - url_copy = PORT_Strdup(url); - name_copy = PORT_Strdup(name); - if (url_copy == NULL || name_copy == NULL) { - rv = SECFailure; - goto loser; - } - - statusContext = ocsp_GetCheckingContext(handle); - - /* - * Allocate and init the context if it doesn't already exist. - */ - if (statusContext == NULL) { - rv = ocsp_InitStatusChecking(handle); - if (rv != SECSuccess) - goto loser; - - statusContext = ocsp_GetCheckingContext(handle); - PORT_Assert(statusContext != NULL); /* extreme paranoia */ - } - - /* - * Note -- we do not touch the status context until after all of - * the steps which could cause errors. If something goes wrong, - * we want to leave things as they were. - */ - - /* - * Get rid of old url and name if there. - */ - if (statusContext->defaultResponderNickname != NULL) - PORT_Free(statusContext->defaultResponderNickname); - if (statusContext->defaultResponderURI != NULL) - PORT_Free(statusContext->defaultResponderURI); - - /* - * And replace them with the new ones. - */ - statusContext->defaultResponderURI = url_copy; - statusContext->defaultResponderNickname = name_copy; - - /* - * If there was already a cert in place, get rid of it and replace it. - * Otherwise, we are not currently enabled, so we don't want to save it; - * it will get re-found and set whenever use of a default responder is - * enabled. - */ - if (statusContext->defaultResponderCert != NULL) { - CERT_DestroyCertificate(statusContext->defaultResponderCert); - statusContext->defaultResponderCert = cert; - } else { - PORT_Assert(statusContext->useDefaultResponder == PR_FALSE); - CERT_DestroyCertificate(cert); - } - - return SECSuccess; - -loser: - CERT_DestroyCertificate(cert); - if (url_copy != NULL) - PORT_Free(url_copy); - if (name_copy != NULL) - PORT_Free(name_copy); - return rv; -} - - -/* - * FUNCTION: CERT_EnableOCSPDefaultResponder - * Turns on use of a default responder when OCSP checking. - * If OCSP checking is already enabled, this will make subsequent checks - * go directly to the default responder. (The location of the responder - * and the nickname of the responder cert must already be specified.) - * If OCSP checking is not enabled, this will be recorded and take effect - * whenever it is enabled. - * INPUTS: - * CERTCertDBHandle *handle - * Cert database on which OCSP checking should use the default responder. - * RETURN: - * Returns SECFailure if an error occurred; SECSuccess otherwise. - * No errors are especially likely unless the caller did not previously - * perform a successful call to SetOCSPDefaultResponder (in which case - * the error set will be SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER). - */ -SECStatus -CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle) -{ - ocspCheckingContext *statusContext; - CERTCertificate *cert; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - statusContext = ocsp_GetCheckingContext(handle); - - if (statusContext == NULL) { - /* - * Strictly speaking, the error already set is "correct", - * but cover over it with one more helpful in this context. - */ - PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER); - return SECFailure; - } - - if (statusContext->defaultResponderURI == NULL) { - PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER); - return SECFailure; - } - - if (statusContext->defaultResponderNickname == NULL) { - PORT_SetError(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER); - return SECFailure; - } - - /* - * Find the cert for the nickname. - */ - cert = CERT_FindCertByNickname(handle, - statusContext->defaultResponderNickname); - if (cert == NULL) { - cert = PK11_FindCertFromNickname(statusContext->defaultResponderNickname, - NULL); - } - /* - * We should never have trouble finding the cert, because its - * existence should have been proven by SetOCSPDefaultResponder. - */ - PORT_Assert(cert != NULL); - if (cert == NULL) - return SECFailure; - - /* - * And hang onto it. - */ - statusContext->defaultResponderCert = cert; - - /* - * Finally, record the fact that we now have a default responder enabled. - */ - statusContext->useDefaultResponder = PR_TRUE; - return SECSuccess; -} - - -/* - * FUNCTION: CERT_DisableOCSPDefaultResponder - * Turns off use of a default responder when OCSP checking. - * (Does nothing if use of a default responder is not enabled.) - * INPUTS: - * CERTCertDBHandle *handle - * Cert database on which OCSP checking should stop using a default - * responder. - * RETURN: - * Returns SECFailure if an error occurred; SECSuccess otherwise. - * Errors very unlikely (like random memory corruption...). - */ -SECStatus -CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle) -{ - CERTStatusConfig *statusConfig; - ocspCheckingContext *statusContext; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - statusConfig = CERT_GetStatusConfig(handle); - if (statusConfig == NULL) - return SECSuccess; - - statusContext = ocsp_GetCheckingContext(handle); - PORT_Assert(statusContext != NULL); - if (statusContext == NULL) - return SECFailure; - - if (statusContext->defaultResponderCert != NULL) { - CERT_DestroyCertificate(statusContext->defaultResponderCert); - statusContext->defaultResponderCert = NULL; - } - - /* - * Finally, record the fact. - */ - statusContext->useDefaultResponder = PR_FALSE; - return SECSuccess; -} -static const SECHashObject * -OidTagToDigestObject(SECOidTag digestAlg) -{ - const SECHashObject *rawDigestObject; - - switch (digestAlg) { - case SEC_OID_MD2: - rawDigestObject = &SECHashObjects[HASH_AlgMD2]; - break; - case SEC_OID_MD5: - rawDigestObject = &SECHashObjects[HASH_AlgMD5]; - break; - case SEC_OID_SHA1: - rawDigestObject = &SECHashObjects[HASH_AlgSHA1]; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rawDigestObject = NULL; - break; - } - return(rawDigestObject); -} - -/* - * Digest the cert's subject public key using the specified algorithm. - * The necessary storage for the digest data is allocated. If "fill" is - * non-null, the data is put there, otherwise a SECItem is allocated. - * Allocation from "arena" if it is non-null, heap otherwise. Any problem - * results in a NULL being returned (and an appropriate error set). - */ -SECItem * -CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert, - SECOidTag digestAlg, SECItem *fill) -{ - const SECHashObject *digestObject; - void *digestContext; - SECItem *result = NULL; - void *mark = NULL; - SECItem spk; - - if ( arena != NULL ) { - mark = PORT_ArenaMark(arena); - } - - digestObject = OidTagToDigestObject(digestAlg); - if ( digestObject == NULL ) { - goto loser; - } - - if ((fill == NULL) || (fill->data == NULL)) { - result = SECITEM_AllocItem(arena, fill, digestObject->length); - if ( result == NULL ) { - goto loser; - } - fill = result; - } - - /* - * Copy just the length and data pointer (nothing needs to be freed) - * of the subject public key so we can convert the length from bits - * to bytes, which is what the digest function expects. - */ - spk = cert->subjectPublicKeyInfo.subjectPublicKey; - DER_ConvertBitString(&spk); - - /* - * Now digest the value, using the specified algorithm. - */ - digestContext = digestObject->create(); - if ( digestContext == NULL ) { - goto loser; - } - digestObject->begin(digestContext); - digestObject->update(digestContext, spk.data, spk.len); - digestObject->end(digestContext, fill->data, &(fill->len), fill->len); - digestObject->destroy(digestContext, PR_TRUE); - - if ( arena != NULL ) { - PORT_ArenaUnmark(arena, mark); - } - return(fill); - -loser: - if ( arena != NULL ) { - PORT_ArenaRelease(arena, mark); - } else { - if ( result != NULL ) { - SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE); - } - } - return(NULL); -} - -SECStatus -CERT_GetOCSPResponseStatus(CERTOCSPResponse *response) -{ - PORT_Assert(response); - if (response->statusValue == ocspResponse_successful) - return SECSuccess; - - switch (response->statusValue) { - case ocspResponse_malformedRequest: - PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); - break; - case ocspResponse_internalError: - PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); - break; - case ocspResponse_tryLater: - PORT_SetError(SEC_ERROR_OCSP_TRY_SERVER_LATER); - break; - case ocspResponse_sigRequired: - /* XXX We *should* retry with a signature, if possible. */ - PORT_SetError(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG); - break; - case ocspResponse_unauthorized: - PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST); - break; - case ocspResponse_other: - case ocspResponse_unused: - default: - PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS); - break; - } - return SECFailure; -} diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h deleted file mode 100644 index 6d5ffd058..000000000 --- a/security/nss/lib/certhigh/ocsp.h +++ /dev/null @@ -1,533 +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. - */ - -/* - * Interface to the OCSP implementation. - * - * $Id$ - */ - -#ifndef _OCSP_H_ -#define _OCSP_H_ - - -#include "plarena.h" -#include "seccomon.h" -#include "secoidt.h" -#include "keyt.h" -#include "certt.h" -#include "ocspt.h" - - -/************************************************************************/ -SEC_BEGIN_PROTOS - -/* - * FUNCTION: CERT_EnableOCSPChecking - * Turns on OCSP checking for the given certificate database. - * INPUTS: - * CERTCertDBHandle *handle - * Certificate database for which OCSP checking will be enabled. - * RETURN: - * Returns SECFailure if an error occurred (likely only problem - * allocating memory); SECSuccess otherwise. - */ -extern SECStatus -CERT_EnableOCSPChecking(CERTCertDBHandle *handle); - -/* - * FUNCTION: CERT_DisableOCSPChecking - * Turns off OCSP checking for the given certificate database. - * This routine disables OCSP checking. Though it will return - * SECFailure if OCSP checking is not enabled, it is "safe" to - * call it that way and just ignore the return value, if it is - * easier to just call it than to "remember" whether it is enabled. - * INPUTS: - * CERTCertDBHandle *handle - * Certificate database for which OCSP checking will be disabled. - * RETURN: - * Returns SECFailure if an error occurred (usually means that OCSP - * checking was not enabled or status contexts were not initialized -- - * error set will be SEC_ERROR_OCSP_NOT_ENABLED); SECSuccess otherwise. - */ -extern SECStatus -CERT_DisableOCSPChecking(CERTCertDBHandle *handle); - -/* - * FUNCTION: CERT_SetOCSPDefaultResponder - * Specify the location and cert of the default responder. - * If OCSP checking is already enabled *and* use of a default responder - * is also already enabled, all OCSP checking from now on will go directly - * to the specified responder. If OCSP checking is not enabled, or if - * it is but use of a default responder is not enabled, the information - * will be recorded and take effect whenever both are enabled. - * INPUTS: - * CERTCertDBHandle *handle - * Cert database on which OCSP checking should use the default responder. - * char *url - * The location of the default responder (e.g. "http://foo.com:80/ocsp") - * Note that the location will not be tested until the first attempt - * to send a request there. - * char *name - * The nickname of the cert to trust (expected) to sign the OCSP responses. - * If the corresponding cert cannot be found, SECFailure is returned. - * RETURN: - * Returns SECFailure if an error occurred; SECSuccess otherwise. - * The most likely error is that the cert for "name" could not be found - * (probably SEC_ERROR_UNKNOWN_CERT). Other errors are low-level (no memory, - * bad database, etc.). - */ -extern SECStatus -CERT_SetOCSPDefaultResponder(CERTCertDBHandle *handle, - const char *url, const char *name); - -/* - * FUNCTION: CERT_EnableOCSPDefaultResponder - * Turns on use of a default responder when OCSP checking. - * If OCSP checking is already enabled, this will make subsequent checks - * go directly to the default responder. (The location of the responder - * and the nickname of the responder cert must already be specified.) - * If OCSP checking is not enabled, this will be recorded and take effect - * whenever it is enabled. - * INPUTS: - * CERTCertDBHandle *handle - * Cert database on which OCSP checking should use the default responder. - * RETURN: - * Returns SECFailure if an error occurred; SECSuccess otherwise. - * No errors are especially likely unless the caller did not previously - * perform a successful call to SetOCSPDefaultResponder (in which case - * the error set will be SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER). - */ -extern SECStatus -CERT_EnableOCSPDefaultResponder(CERTCertDBHandle *handle); - -/* - * FUNCTION: CERT_DisableOCSPDefaultResponder - * Turns off use of a default responder when OCSP checking. - * (Does nothing if use of a default responder is not enabled.) - * INPUTS: - * CERTCertDBHandle *handle - * Cert database on which OCSP checking should stop using a default - * responder. - * RETURN: - * Returns SECFailure if an error occurred; SECSuccess otherwise. - * Errors very unlikely (like random memory corruption...). - */ -extern SECStatus -CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle); - -/* - * ------------------------------------------------------- - * The Functions above are those expected to be used by a client - * providing OCSP status checking along with every cert verification. - * The functions below are for OCSP testing, debugging, or clients - * or servers performing more specialized OCSP tasks. - * ------------------------------------------------------- - */ - -/* - * FUNCTION: CERT_CreateOCSPRequest - * Creates a CERTOCSPRequest, requesting the status of the certs in - * the given list. - * INPUTS: - * CERTCertList *certList - * A list of certs for which status will be requested. - * Note that all of these certificates should have the same issuer, - * or it's expected the response will be signed by a trusted responder. - * If the certs need to be broken up into multiple requests, that - * must be handled by the caller (and thus by having multiple calls - * to this routine), who knows about where the request(s) are being - * sent and whether there are any trusted responders in place. - * int64 time - * Indicates the time for which the certificate status is to be - * determined -- this may be used in the search for the cert's issuer - * but has no effect on the request itself. - * PRBool addServiceLocator - * If true, the Service Locator extension should be added to the - * single request(s) for each cert. - * CERTCertificate *signerCert - * If non-NULL, means sign the request using this cert. Otherwise, - * do not sign. - * XXX note that request signing is not yet supported; see comment in code - * RETURN: - * A pointer to a CERTOCSPRequest structure containing an OCSP request - * for the cert list. On error, null is returned, with an error set - * indicating the reason. This is likely SEC_ERROR_UNKNOWN_ISSUER. - * (The issuer is needed to create a request for the certificate.) - * Other errors are low-level problems (no memory, bad database, etc.). - */ -extern CERTOCSPRequest * -CERT_CreateOCSPRequest(CERTCertList *certList, int64 time, - PRBool addServiceLocator, - CERTCertificate *signerCert); - -/* - * FUNCTION: CERT_AddOCSPAcceptableResponses - * Add the AcceptableResponses extension to an OCSP Request. - * INPUTS: - * CERTOCSPRequest *request - * The request to which the extension should be added. - * ... - * A list (of one or more) of SECOidTag -- each of the response types - * to be added. The last OID *must* be SEC_OID_PKIX_OCSP_BASIC_RESPONSE. - * (This marks the end of the list, and it must be specified because a - * client conforming to the OCSP standard is required to handle the basic - * response type.) The OIDs are not checked in any way. - * RETURN: - * SECSuccess if the extension is added; SECFailure if anything goes wrong. - * All errors are internal or low-level problems (e.g. no memory). - */ -extern SECStatus -CERT_AddOCSPAcceptableResponses(CERTOCSPRequest *request, ...); - -/* - * FUNCTION: CERT_EncodeOCSPRequest - * DER encodes an OCSP Request, possibly adding a signature as well. - * XXX Signing is not yet supported, however; see comments in code. - * INPUTS: - * PRArenaPool *arena - * The return value is allocated from here. - * If a NULL is passed in, allocation is done from the heap instead. - * CERTOCSPRequest *request - * The request to be encoded. - * void *pwArg - * Pointer to argument for password prompting, if needed. (Definitely - * not needed if not signing.) - * RETURN: - * Returns a NULL on error and a pointer to the SECItem with the - * encoded value otherwise. Any error is likely to be low-level - * (e.g. no memory). - */ -extern SECItem * -CERT_EncodeOCSPRequest(PRArenaPool *arena, CERTOCSPRequest *request, - void *pwArg); - -/* - * FUNCTION: CERT_DecodeOCSPRequest - * Decode a DER encoded OCSP Request. - * INPUTS: - * SECItem *src - * Pointer to a SECItem holding DER encoded OCSP Request. - * RETURN: - * Returns a pointer to a CERTOCSPRequest containing the decoded request. - * On error, returns NULL. Most likely error is trouble decoding - * (SEC_ERROR_OCSP_MALFORMED_REQUEST), or low-level problem (no memory). - */ -extern CERTOCSPRequest * -CERT_DecodeOCSPRequest(SECItem *src); - -/* - * FUNCTION: CERT_DestroyOCSPRequest - * Frees an OCSP Request structure. - * INPUTS: - * CERTOCSPRequest *request - * Pointer to CERTOCSPRequest to be freed. - * RETURN: - * No return value; no errors. - */ -extern void -CERT_DestroyOCSPRequest(CERTOCSPRequest *request); - -/* - * FUNCTION: CERT_DecodeOCSPResponse - * Decode a DER encoded OCSP Response. - * INPUTS: - * SECItem *src - * Pointer to a SECItem holding DER encoded OCSP Response. - * RETURN: - * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response); - * the caller is responsible for destroying it. Or NULL if error (either - * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE), - * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE), - * or a low-level or internal error occurred). - */ -extern CERTOCSPResponse * -CERT_DecodeOCSPResponse(SECItem *src); - -/* - * FUNCTION: CERT_DestroyOCSPResponse - * Frees an OCSP Response structure. - * INPUTS: - * CERTOCSPResponse *request - * Pointer to CERTOCSPResponse to be freed. - * RETURN: - * No return value; no errors. - */ -extern void -CERT_DestroyOCSPResponse(CERTOCSPResponse *response); - -/* - * FUNCTION: CERT_GetEncodedOCSPResponse - * Creates and sends a request to an OCSP responder, then reads and - * returns the (encoded) response. - * INPUTS: - * PRArenaPool *arena - * Pointer to arena from which return value will be allocated. - * If NULL, result will be allocated from the heap (and thus should - * be freed via SECITEM_FreeItem). - * CERTCertList *certList - * A list of certs for which status will be requested. - * Note that all of these certificates should have the same issuer, - * or it's expected the response will be signed by a trusted responder. - * If the certs need to be broken up into multiple requests, that - * must be handled by the caller (and thus by having multiple calls - * to this routine), who knows about where the request(s) are being - * sent and whether there are any trusted responders in place. - * char *location - * The location of the OCSP responder (a URL). - * int64 time - * Indicates the time for which the certificate status is to be - * determined -- this may be used in the search for the cert's issuer - * but has no other bearing on the operation. - * PRBool addServiceLocator - * If true, the Service Locator extension should be added to the - * single request(s) for each cert. - * CERTCertificate *signerCert - * If non-NULL, means sign the request using this cert. Otherwise, - * do not sign. - * void *pwArg - * Pointer to argument for password prompting, if needed. (Definitely - * not needed if not signing.) - * OUTPUTS: - * CERTOCSPRequest **pRequest - * Pointer in which to store the OCSP request created for the given - * list of certificates. It is only filled in if the entire operation - * is successful and the pointer is not null -- and in that case the - * caller is then reponsible for destroying it. - * RETURN: - * Returns a pointer to the SECItem holding the response. - * On error, returns null with error set describing the reason: - * SEC_ERROR_UNKNOWN_ISSUER - * SEC_ERROR_CERT_BAD_ACCESS_LOCATION - * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE - * Other errors are low-level problems (no memory, bad database, etc.). - */ -extern SECItem * -CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, - char *location, int64 time, - PRBool addServiceLocator, - CERTCertificate *signerCert, void *pwArg, - CERTOCSPRequest **pRequest); - -/* - * FUNCTION: CERT_VerifyOCSPResponseSignature - * Check the signature on an OCSP Response. Will also perform a - * verification of the signer's certificate. Note, however, that a - * successful verification does not make any statement about the - * signer's *authority* to provide status for the certificate(s), - * that must be checked individually for each certificate. - * INPUTS: - * CERTOCSPResponse *response - * Pointer to response structure with signature to be checked. - * CERTCertDBHandle *handle - * Pointer to CERTCertDBHandle for certificate DB to use for verification. - * void *pwArg - * Pointer to argument for password prompting, if needed. - * CERTCertificate *issuerCert - * Issuer of the certificate that generated the OCSP request. - * OUTPUTS: - * CERTCertificate **pSignerCert - * Pointer in which to store signer's certificate; only filled-in if - * non-null. - * RETURN: - * Returns SECSuccess when signature is valid, anything else means invalid. - * Possible errors set: - * SEC_ERROR_OCSP_MALFORMED_RESPONSE - unknown type of ResponderID - * SEC_ERROR_INVALID_TIME - bad format of "ProducedAt" time - * SEC_ERROR_UNKNOWN_SIGNER - signer's cert could not be found - * SEC_ERROR_BAD_SIGNATURE - the signature did not verify - * Other errors are any of the many possible failures in cert verification - * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when - * verifying the signer's cert, or low-level problems (no memory, etc.) - */ -extern SECStatus -CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response, - CERTCertDBHandle *handle, void *pwArg, - CERTCertificate **pSignerCert, - CERTCertificate *issuerCert); - -/* - * FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation - * Get the value of the URI of the OCSP responder for the given cert. - * This is found in the (optional) Authority Information Access extension - * in the cert. - * INPUTS: - * CERTCertificate *cert - * The certificate being examined. - * RETURN: - * char * - * A copy of the URI for the OCSP method, if found. If either the - * extension is not present or it does not contain an entry for OCSP, - * SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned. - * Any other error will also result in a NULL being returned. - * - * This result should be freed (via PORT_Free) when no longer in use. - */ -extern char * -CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert); - -/* - * FUNCTION: CERT_CheckOCSPStatus - * Checks the status of a certificate via OCSP. Will only check status for - * a certificate that has an AIA (Authority Information Access) extension - * for OCSP *or* when a "default responder" is specified and enabled. - * (If no AIA extension for OCSP and no default responder in place, the - * cert is considered to have a good status and SECSuccess is returned.) - * INPUTS: - * CERTCertDBHandle *handle - * certificate DB of the cert that is being checked - * CERTCertificate *cert - * the certificate being checked - * XXX in the long term also need a boolean parameter that specifies - * whether to check the cert chain, as well; for now we check only - * the leaf (the specified certificate) - * int64 time - * time for which status is to be determined - * void *pwArg - * argument for password prompting, if needed - * RETURN: - * Returns SECSuccess if an approved OCSP responder "knows" the cert - * *and* returns a non-revoked status for it; SECFailure otherwise, - * with an error set describing the reason: - * - * SEC_ERROR_OCSP_BAD_HTTP_RESPONSE - * SEC_ERROR_OCSP_FUTURE_RESPONSE - * SEC_ERROR_OCSP_MALFORMED_REQUEST - * SEC_ERROR_OCSP_MALFORMED_RESPONSE - * SEC_ERROR_OCSP_OLD_RESPONSE - * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG - * SEC_ERROR_OCSP_SERVER_ERROR - * SEC_ERROR_OCSP_TRY_SERVER_LATER - * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST - * SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE - * SEC_ERROR_OCSP_UNKNOWN_CERT - * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS - * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE - * - * SEC_ERROR_BAD_SIGNATURE - * SEC_ERROR_CERT_BAD_ACCESS_LOCATION - * SEC_ERROR_INVALID_TIME - * SEC_ERROR_REVOKED_CERTIFICATE - * SEC_ERROR_UNKNOWN_ISSUER - * SEC_ERROR_UNKNOWN_SIGNER - * - * Other errors are any of the many possible failures in cert verification - * (e.g. SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_UNTRUSTED_ISSUER) when - * verifying the signer's cert, or low-level problems (error allocating - * memory, error performing ASN.1 decoding, etc.). - */ -extern SECStatus -CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, - int64 time, void *pwArg); -/* - * FUNCTION: CERT_GetOCSPStatusForCertID - * Returns the OCSP status contained in the passed in paramter response - * that corresponds to the certID passed in. - * INPUTS: - * CERTCertDBHandle *handle - * certificate DB of the cert that is being checked - * CERTOCSPResponse *response - * the OCSP response we want to retrieve status from. - * CERTOCSPCertID *certID - * the ID we want to look for from the response. - * CERTCertificate *signerCert - * the certificate that was used to sign the OCSP response. - * must be obtained via a call to CERT_VerifyOCSPResponseSignature. - * int64 time - * The time at which we're checking the status for. - * RETURN: - * Return values are the same as those for CERT_CheckOCSPStatus - */ -extern SECStatus -CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle, - CERTOCSPResponse *response, - CERTOCSPCertID *certID, - CERTCertificate *signerCert, - int64 time); - -/* - * FUNCTION CERT_GetOCSPResponseStatus - * Returns the response status for the response passed. - * INPUTS: - * CERTOCSPResponse *response - * The response to query for status - * RETURN: - * Returns SECSuccess if the response has a successful status value. - * Otherwise it returns SECFailure and sets one of the following error - * codes via PORT_SetError - * SEC_ERROR_OCSP_MALFORMED_REQUEST - * SEC_ERROR_OCSP_SERVER_ERROR - * SEC_ERROR_OCSP_TRY_SERVER_LATER - * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG - * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST - * SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS - */ -extern SECStatus -CERT_GetOCSPResponseStatus(CERTOCSPResponse *response); - -/* - * FUNCTION CERT_CreateOCSPCertID - * Returns the OCSP certID for the certificate passed in. - * INPUTS: - * CERTCertificate *cert - * The certificate for which to create the certID for. - * int64 time - * The time at which the id is requested for. This is used - * to determine the appropriate issuer for the cert since - * the issuing CA may be an older expired certificate. - * RETURN: - * A new copy of a CERTOCSPCertID*. The memory for this certID - * should be freed by calling CERT_DestroyOCSPCertID when the - * certID is no longer necessary. - */ -extern CERTOCSPCertID* -CERT_CreateOCSPCertID(CERTCertificate *cert, int64 time); - -/* - * FUNCTION: CERT_DestroyOCSPCertID - * Frees the memory associated with the certID passed in. - * INPUTS: - * CERTOCSPCertID* certID - * The certID that the caller no longer needs and wants to - * free the associated memory. - * RETURN: - * SECSuccess if freeing the memory was successful. Returns - * SECFailure if the memory passed in was not allocated with - * a call to CERT_CreateOCSPCertID. - */ -extern SECStatus -CERT_DestroyOCSPCertID(CERTOCSPCertID* certID); -/************************************************************************/ -SEC_END_PROTOS - -#endif /* _OCSP_H_ */ diff --git a/security/nss/lib/certhigh/ocspt.h b/security/nss/lib/certhigh/ocspt.h deleted file mode 100644 index 3f1563855..000000000 --- a/security/nss/lib/certhigh/ocspt.h +++ /dev/null @@ -1,59 +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. - */ - -/* - * Public header for exported OCSP types. - * - * $Id$ - */ - -#ifndef _OCSPT_H_ -#define _OCSPT_H_ - -/* - * The following are all opaque types. If someone needs to get at - * a field within, then we need to fix the API. Try very hard not - * make the type available to them. - */ -typedef struct CERTOCSPRequestStr CERTOCSPRequest; -typedef struct CERTOCSPResponseStr CERTOCSPResponse; - -/* - * XXX I think only those first two above should need to be exported, - * but until I know for certain I am leaving the rest of these here, too. - */ -typedef struct CERTOCSPCertIDStr CERTOCSPCertID; -typedef struct CERTOCSPCertStatusStr CERTOCSPCertStatus; -typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse; - -#endif /* _OCSPT_H_ */ diff --git a/security/nss/lib/certhigh/ocspti.h b/security/nss/lib/certhigh/ocspti.h deleted file mode 100644 index 2bb7bfe72..000000000 --- a/security/nss/lib/certhigh/ocspti.h +++ /dev/null @@ -1,405 +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. - */ - -/* - * Private header defining OCSP types. - * - * $Id$ - */ - -#ifndef _OCSPTI_H_ -#define _OCSPTI_H_ - -#include "ocspt.h" - -#include "certt.h" -#include "plarena.h" -#include "seccomon.h" -#include "secoidt.h" - - -/* - * Some notes about naming conventions... - * - * The public data types all start with "CERTOCSP" (e.g. CERTOCSPRequest). - * (Even the public types are opaque, however. Only their names are - * "exported".) - * - * Internal-only data types drop the "CERT" prefix and use only the - * lower-case "ocsp" (e.g. ocspTBSRequest), for brevity sake. - * - * In either case, the base/suffix of the type name usually matches the - * name as defined in the OCSP specification. The exceptions to this are: - * - When there is overlap between the "OCSP" or "ocsp" prefix and - * the name used in the standard. That is, you cannot strip off the - * "CERTOCSP" or "ocsp" prefix and necessarily get the name of the - * type as it is defined in the standard; the "real" name will be - * *either* "OCSPSuffix" or just "Suffix". - * - When the name in the standard was a little too generic. (e.g. The - * standard defines "Request" but we call it a "SingleRequest".) - * In this case a comment above the type definition calls attention - * to the difference. - * - * The definitions laid out in this header file are intended to follow - * the same order as the definitions in the OCSP specification itself. - * With the OCSP standard in hand, you should be able to move through - * this file and follow along. To future modifiers of this file: please - * try to keep it that way. The only exceptions are the few cases where - * we need to define a type before it is referenced (e.g. enumerations), - * whereas in the OCSP specification these are usually defined the other - * way around (reference before definition). - */ - - -/* - * Forward-declarations of internal-only data structures. - * - * These are in alphabetical order (case-insensitive); please keep it that way! - */ -typedef struct ocspBasicOCSPResponseStr ocspBasicOCSPResponse; -typedef struct ocspCertStatusStr ocspCertStatus; -typedef struct ocspResponderIDStr ocspResponderID; -typedef struct ocspResponseBytesStr ocspResponseBytes; -typedef struct ocspResponseDataStr ocspResponseData; -typedef struct ocspRevokedInfoStr ocspRevokedInfo; -typedef struct ocspServiceLocatorStr ocspServiceLocator; -typedef struct ocspSignatureStr ocspSignature; -typedef struct ocspSingleRequestStr ocspSingleRequest; -typedef struct ocspSingleResponseStr ocspSingleResponse; -typedef struct ocspTBSRequestStr ocspTBSRequest; - - -/* - * An OCSPRequest; this is what is sent (encoded) to an OCSP responder. - */ -struct CERTOCSPRequestStr { - PRArenaPool *arena; /* local; not part of encoding */ - ocspTBSRequest *tbsRequest; - ocspSignature *optionalSignature; -}; - -/* - * A TBSRequest; when an OCSPRequest is signed, the encoding of this - * is what the signature is actually applied to. ("TBS" == To Be Signed) - * Whether signed or not, however, this structure will be present, and - * is the "meat" of the OCSPRequest. - * - * Note that the "requestorName" field cannot be encoded/decoded in the - * same pass as the entire request -- it needs to be handled with a special - * call to convert to/from our internal form of a GeneralName. Thus the - * "derRequestorName" field, which is the actual DER-encoded bytes. - * - * The "extensionHandle" field is used on creation only; it holds - * in-progress extensions as they are optionally added to the request. - */ -struct ocspTBSRequestStr { - SECItem version; /* an INTEGER */ - SECItem *derRequestorName; /* encoded GeneralName; see above */ - CERTGeneralNameList *requestorName; /* local; not part of encoding */ - ocspSingleRequest **requestList; - CERTCertExtension **requestExtensions; - void *extensionHandle; /* local; not part of encoding */ -}; - -/* - * This is the actual signature information for an OCSPRequest (applied to - * the TBSRequest structure) or for a BasicOCSPResponse (applied to a - * ResponseData structure). - * - * Note that the "signature" field itself is a BIT STRING; operations on - * it need to keep that in mind, converting the length to bytes as needed - * and back again afterward (so that the length is usually expressing bits). - * - * The "cert" field is the signer's certificate. In the case of a received - * signature, it will be filled in when the signature is verified. In the - * case of a created signature, it is filled in on creation and will be the - * cert used to create the signature when the signing-and-encoding occurs, - * as well as the cert (and its chain) to fill in derCerts if requested. - * - * The extra fields cache information about the signature after we have - * attempted a verification. "wasChecked", if true, means the signature - * has been checked against the appropriate data and thus that "status" - * contains the result of that verification. If "status" is not SECSuccess, - * "failureReason" is a copy of the error code that was set at the time; - * presumably it tells why the signature verification failed. - */ -struct ocspSignatureStr { - SECAlgorithmID signatureAlgorithm; - SECItem signature; /* a BIT STRING */ - SECItem **derCerts; /* a SEQUENCE OF Certificate */ - CERTCertificate *cert; /* local; not part of encoding */ - PRBool wasChecked; /* local; not part of encoding */ - SECStatus status; /* local; not part of encoding */ - int failureReason; /* local; not part of encoding */ -}; - -/* - * An OCSPRequest contains a SEQUENCE OF these, one for each certificate - * whose status is being checked. - * - * Note that in the OCSP specification this is just called "Request", - * but since that seemed confusing (vs. an OCSPRequest) and to be more - * consistent with the parallel type "SingleResponse", I called it a - * "SingleRequest". - * - * XXX figure out how to get rid of that arena -- there must be a way - */ -struct ocspSingleRequestStr { - PRArenaPool *arena; /* just a copy of the response arena, - * needed here for extension handling - * routines, on creation only */ - CERTOCSPCertID *reqCert; - CERTCertExtension **singleRequestExtensions; -}; - -/* - * A CertID is the means of identifying a certificate, used both in requests - * and in responses. - * - * When in a SingleRequest it specifies the certificate to be checked. - * When in a SingleResponse it is the cert whose status is being given. - */ -struct CERTOCSPCertIDStr { - SECAlgorithmID hashAlgorithm; - SECItem issuerNameHash; /* an OCTET STRING */ - SECItem issuerKeyHash; /* an OCTET STRING */ - SECItem serialNumber; /* an INTEGER */ - SECItem issuerSHA1NameHash; /* keep other hashes around when */ - SECItem issuerMD5NameHash; /* we have them */ - SECItem issuerMD2NameHash; - SECItem issuerSHA1KeyHash; /* keep other hashes around when */ - SECItem issuerMD5KeyHash; /* we have them */ - SECItem issuerMD2KeyHash; - PRArenaPool *poolp; -}; - -/* - * This describes the value of the responseStatus field in an OCSPResponse. - * The corresponding ASN.1 definition is: - * - * OCSPResponseStatus ::= ENUMERATED { - * successful (0), --Response has valid confirmations - * malformedRequest (1), --Illegal confirmation request - * internalError (2), --Internal error in issuer - * tryLater (3), --Try again later - * --(4) is not used - * sigRequired (5), --Must sign the request - * unauthorized (6), --Request unauthorized - * } - */ -typedef enum { - ocspResponse_successful = 0, - ocspResponse_malformedRequest = 1, - ocspResponse_internalError = 2, - ocspResponse_tryLater = 3, - ocspResponse_unused = 4, - ocspResponse_sigRequired = 5, - ocspResponse_unauthorized = 6, - ocspResponse_other /* unknown/unrecognized value */ -} ocspResponseStatus; - -/* - * An OCSPResponse is what is sent (encoded) by an OCSP responder. - * - * The field "responseStatus" is the ASN.1 encoded value; the field - * "statusValue" is simply that same value translated into our local - * type ocspResponseStatus. - */ -struct CERTOCSPResponseStr { - PRArenaPool *arena; /* local; not part of encoding */ - SECItem responseStatus; /* an ENUMERATED, see above */ - ocspResponseStatus statusValue; /* local; not part of encoding */ - ocspResponseBytes *responseBytes; /* only when status is successful */ -}; - -/* - * A ResponseBytes (despite appearances) is what contains the meat - * of a successful response -- but still in encoded form. The type - * given as "responseType" tells you how to decode the string. - * - * We look at the OID and translate it into our local OID representation - * "responseTypeTag", and use that value to tell us how to decode the - * actual response itself. For now the only kind of OCSP response we - * know about is a BasicOCSPResponse. However, the intention in the - * OCSP specification is to allow for other response types, so we are - * building in that flexibility from the start and thus put a pointer - * to that data structure inside of a union. Whenever OCSP adds more - * response types, just add them to the union. - */ -struct ocspResponseBytesStr { - SECItem responseType; /* an OBJECT IDENTIFIER */ - SECOidTag responseTypeTag; /* local; not part of encoding */ - SECItem response; /* an OCTET STRING */ - union { - ocspBasicOCSPResponse *basic; /* when type is id-pkix-ocsp-basic */ - } decodedResponse; /* local; not part of encoding */ -}; - -/* - * A BasicOCSPResponse -- when the responseType in a ResponseBytes is - * id-pkix-ocsp-basic, the "response" OCTET STRING above is the DER - * encoding of one of these. - * - * Note that in the OCSP specification, the signature fields are not - * part of a separate sub-structure. But since they are the same fields - * as we define for the signature in a request, it made sense to share - * the C data structure here and in some shared code to operate on them. - */ -struct ocspBasicOCSPResponseStr { - ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */ - ocspSignature responseSignature; -}; - -/* - * A ResponseData is the part of a BasicOCSPResponse that is signed - * (after it is DER encoded). It contains the real details of the response - * (a per-certificate status). - */ -struct ocspResponseDataStr { - SECItem version; /* an INTEGER */ - SECItem derResponderID; - ocspResponderID *responderID; /* local; not part of encoding */ - SECItem producedAt; /* a GeneralizedTime */ - CERTOCSPSingleResponse **responses; - CERTCertExtension **responseExtensions; -}; - -/* - * A ResponderID identifies the responder -- or more correctly, the - * signer of the response. The ASN.1 definition of a ResponderID is: - * - * ResponderID ::= CHOICE { - * byName [1] EXPLICIT Name, - * byKey [2] EXPLICIT KeyHash } - * - * Because it is CHOICE, the type of identification used and the - * identification itself are actually encoded together. To represent - * this same information internally, we explicitly define a type and - * save it, along with the value, into a data structure. - */ - -typedef enum { - ocspResponderID_byName, - ocspResponderID_byKey, - ocspResponderID_other /* unknown kind of responderID */ -} ocspResponderIDType; - -struct ocspResponderIDStr { - ocspResponderIDType responderIDType;/* local; not part of encoding */ - union { - CERTName name; /* when ocspResponderID_byName */ - SECItem keyHash; /* when ocspResponderID_byKey */ - SECItem other; /* when ocspResponderID_other */ - } responderIDValue; -}; - -/* - * The ResponseData in a BasicOCSPResponse contains a SEQUENCE OF - * SingleResponse -- one for each certificate whose status is being supplied. - * - * XXX figure out how to get rid of that arena -- there must be a way - */ -struct CERTOCSPSingleResponseStr { - PRArenaPool *arena; /* just a copy of the response arena, - * needed here for extension handling - * routines, on creation only */ - CERTOCSPCertID *certID; - SECItem derCertStatus; - ocspCertStatus *certStatus; /* local; not part of encoding */ - SECItem thisUpdate; /* a GeneralizedTime */ - SECItem *nextUpdate; /* a GeneralizedTime */ - CERTCertExtension **singleExtensions; -}; - -/* - * A CertStatus is the actual per-certificate status. Its ASN.1 definition: - * - * CertStatus ::= CHOICE { - * good [0] IMPLICIT NULL, - * revoked [1] IMPLICIT RevokedInfo, - * unknown [2] IMPLICIT UnknownInfo } - * - * (where for now UnknownInfo is defined to be NULL but in the - * future may be replaced with an enumeration). - * - * Because it is CHOICE, the status value and its associated information - * (if any) are actually encoded together. To represent this same - * information internally, we explicitly define a type and save it, - * along with the value, into a data structure. - */ - -typedef enum { - ocspCertStatus_good, /* cert is not revoked */ - ocspCertStatus_revoked, /* cert is revoked */ - ocspCertStatus_unknown, /* cert was unknown to the responder */ - ocspCertStatus_other /* status was not an expected value */ -} ocspCertStatusType; - -/* - * This is the actual per-certificate status. - * - * The "goodInfo" and "unknownInfo" items are only place-holders for a NULL. - * (Though someday OCSP may replace UnknownInfo with an enumeration that - * gives more detailed information.) - */ -struct ocspCertStatusStr { - ocspCertStatusType certStatusType; /* local; not part of encoding */ - union { - SECItem *goodInfo; /* when ocspCertStatus_good */ - ocspRevokedInfo *revokedInfo; /* when ocspCertStatus_revoked */ - SECItem *unknownInfo; /* when ocspCertStatus_unknown */ - SECItem *otherInfo; /* when ocspCertStatus_other */ - } certStatusInfo; -}; - -/* - * A RevokedInfo gives information about a revoked certificate -- when it - * was revoked and why. - */ -struct ocspRevokedInfoStr { - SECItem revocationTime; /* a GeneralizedTime */ - SECItem *revocationReason; /* a CRLReason; ignored for now */ -}; - -/* - * ServiceLocator can be included as one of the singleRequestExtensions. - * When added, it specifies the (name of the) issuer of the cert being - * checked, and optionally the value of the AuthorityInfoAccess extension - * if the cert has one. - */ -struct ocspServiceLocatorStr { - CERTName *issuer; - SECItem locator; /* DER encoded authInfoAccess extension from cert */ -}; - -#endif /* _OCSPTI_H_ */ diff --git a/security/nss/lib/certhigh/xcrldist.c b/security/nss/lib/certhigh/xcrldist.c deleted file mode 100644 index 6f8a014f0..000000000 --- a/security/nss/lib/certhigh/xcrldist.c +++ /dev/null @@ -1,222 +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 x.509 v3 CRL Distribution Point extension. - */ -#include "genname.h" -#include "certt.h" -#include "secerr.h" - -extern void PrepareBitStringForEncoding (SECItem *bitMap, SECItem *value); - -static const SEC_ASN1Template FullNameTemplate[] = { - {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 0, - offsetof (CRLDistributionPoint,derFullName), CERT_GeneralNamesTemplate} -}; - -static const SEC_ASN1Template RelativeNameTemplate[] = { - {SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_CONSTRUCTED | 1, - offsetof (CRLDistributionPoint,distPoint.relativeName), CERT_RDNTemplate} -}; - -static const SEC_ASN1Template CRLDistributionPointTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CRLDistributionPoint) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT | 0, - offsetof(CRLDistributionPoint,derDistPoint), SEC_AnyTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CRLDistributionPoint,bitsmap), SEC_BitStringTemplate}, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_CONSTRUCTED | 2, - offsetof(CRLDistributionPoint, derCrlIssuer), CERT_GeneralNamesTemplate}, - { 0 } -}; - -const SEC_ASN1Template CERTCRLDistributionPointsTemplate[] = { - {SEC_ASN1_SEQUENCE_OF, 0, CRLDistributionPointTemplate} -}; - -SECStatus -CERT_EncodeCRLDistributionPoints (PRArenaPool *arena, CERTCrlDistributionPoints *value, - SECItem *derValue) -{ - CRLDistributionPoint **pointList, *point; - PRArenaPool *ourPool = NULL; - SECStatus rv = SECSuccess; - - PORT_Assert (derValue); - PORT_Assert (value && value->distPoints); - - do { - ourPool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); - if (ourPool == NULL) { - rv = SECFailure; - break; - } - - pointList = value->distPoints; - while (*pointList) { - point = *pointList; - point->derFullName = NULL; - point->derDistPoint.data = NULL; - - if (point->distPointType == generalName) { - point->derFullName = cert_EncodeGeneralNames - (ourPool, point->distPoint.fullName); - - if (point->derFullName) { - rv = (SEC_ASN1EncodeItem (ourPool, &point->derDistPoint, - point, FullNameTemplate) == NULL) ? SECFailure : SECSuccess; - } else { - rv = SECFailure; - } - } - else if (point->distPointType == relativeDistinguishedName) { - if (SEC_ASN1EncodeItem - (ourPool, &point->derDistPoint, - point, RelativeNameTemplate) == NULL) - rv = SECFailure; - } - /* distributionPointName is omitted */ - else if (point->distPointType != 0) { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - rv = SECFailure; - } - if (rv != SECSuccess) - break; - - if (point->reasons.data) - PrepareBitStringForEncoding (&point->bitsmap, &point->reasons); - - if (point->crlIssuer) { - point->derCrlIssuer = cert_EncodeGeneralNames - (ourPool, point->crlIssuer); - if (!point->crlIssuer) - break; - } - - ++pointList; - } - if (rv != SECSuccess) - break; - if (SEC_ASN1EncodeItem - (arena, derValue, value, CERTCRLDistributionPointsTemplate) == NULL) { - rv = SECFailure; - break; - } - } while (0); - PORT_FreeArena (ourPool, PR_FALSE); - return (rv); -} - -CERTCrlDistributionPoints * -CERT_DecodeCRLDistributionPoints (PRArenaPool *arena, SECItem *encodedValue) -{ - CERTCrlDistributionPoints *value = NULL; - CRLDistributionPoint **pointList, *point; - SECStatus rv; - - PORT_Assert (arena); - do { - value = (CERTCrlDistributionPoints*)PORT_ArenaZAlloc (arena, sizeof (*value)); - if (value == NULL) { - rv = SECFailure; - break; - } - - rv = SEC_QuickDERDecodeItem - (arena, &value->distPoints, CERTCRLDistributionPointsTemplate, - encodedValue); - if (rv != SECSuccess) - break; - - pointList = value->distPoints; - while (*pointList) { - point = *pointList; - - /* get the data if the distributionPointName is not omitted */ - if (point->derDistPoint.data != NULL) { - point->distPointType = (DistributionPointTypes) - ((point->derDistPoint.data[0] & 0x1f) +1); - if (point->distPointType == generalName) { - SECItem innerDER; - - innerDER.data = NULL; - rv = SEC_QuickDERDecodeItem - (arena, point, FullNameTemplate, &(point->derDistPoint)); - if (rv != SECSuccess) - break; - point->distPoint.fullName = cert_DecodeGeneralNames - (arena, point->derFullName); - - if (!point->distPoint.fullName) - break; - } - else if ( relativeDistinguishedName) { - rv = SEC_QuickDERDecodeItem - (arena, point, RelativeNameTemplate, &(point->derDistPoint)); - if (rv != SECSuccess) - break; - } - else { - PORT_SetError (SEC_ERROR_EXTENSION_VALUE_INVALID); - break; - } - } - - /* Get the reason code if it's not omitted in the encoding */ - if (point->bitsmap.data != NULL) { - point->reasons.data = (unsigned char*) PORT_ArenaAlloc - (arena, (point->bitsmap.len + 7) >> 3); - if (!point->reasons.data) { - rv = SECFailure; - break; - } - PORT_Memcpy (point->reasons.data, point->bitsmap.data, - point->reasons.len = ((point->bitsmap.len + 7) >> 3)); - } - - /* Get the crl issuer name if it's not omitted in the encoding */ - if (point->derCrlIssuer != NULL) { - point->crlIssuer = cert_DecodeGeneralNames - (arena, point->derCrlIssuer); - - if (!point->crlIssuer) - break; - } - ++pointList; - } - } while (0); - return (rv == SECSuccess ? value : NULL); -} diff --git a/security/nss/lib/cryptohi/Makefile b/security/nss/lib/cryptohi/Makefile deleted file mode 100644 index ced902117..000000000 --- a/security/nss/lib/cryptohi/Makefile +++ /dev/null @@ -1,77 +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/cryptohi/config.mk b/security/nss/lib/cryptohi/config.mk deleted file mode 100644 index 0a00dc61e..000000000 --- a/security/nss/lib/cryptohi/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/cryptohi/cryptohi.h b/security/nss/lib/cryptohi/cryptohi.h deleted file mode 100644 index 28359cb65..000000000 --- a/security/nss/lib/cryptohi/cryptohi.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - * crypto.h - public data structures and prototypes for the crypto library - * - * 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. - * - * $Id$ - */ - -#ifndef _CRYPTOHI_H_ -#define _CRYPTOHI_H_ - -#include "blapi.h" - -#include "seccomon.h" -#include "secoidt.h" -#include "secdert.h" -#include "cryptoht.h" -#include "keyt.h" -#include "certt.h" - - -SEC_BEGIN_PROTOS - - -/****************************************/ -/* -** DER encode/decode DSA signatures -*/ - -/* ANSI X9.57 defines DSA signatures as DER encoded data. Our DSA code (and - * most of the rest of the world) just generates 40 bytes of raw data. These - * functions convert between formats. - */ -extern SECStatus DSAU_EncodeDerSig(SECItem *dest, SECItem *src); -extern SECItem *DSAU_DecodeDerSig(SECItem *item); - - - -/****************************************/ -/* -** Signature creation operations -*/ - -/* -** Create a new signature context used for signing a data stream. -** "alg" the signature algorithm to use (e.g. SEC_OID_RSA_WITH_MD5) -** "privKey" the private key to use -*/ -extern SGNContext *SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *privKey); - -/* -** Destroy a signature-context object -** "key" the object -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void SGN_DestroyContext(SGNContext *cx, PRBool freeit); - -/* -** Reset the signing context "cx" to its initial state, preparing it for -** another stream of data. -*/ -extern SECStatus SGN_Begin(SGNContext *cx); - -/* -** Update the signing context with more data to sign. -** "cx" the context -** "input" the input data to sign -** "inputLen" the length of the input data -*/ -extern SECStatus SGN_Update(SGNContext *cx, unsigned char *input, - unsigned int inputLen); - -/* -** Finish the signature process. Use either k0 or k1 to sign the data -** stream that was input using SGN_Update. The resulting signature is -** formatted using PKCS#1 and then encrypted using RSA private or public -** encryption. -** "cx" the context -** "result" the final signature data (memory is allocated) -*/ -extern SECStatus SGN_End(SGNContext *cx, SECItem *result); - -/* -** Sign a single block of data using private key encryption and given -** signature/hash algorithm. -** "result" the final signature data (memory is allocated) -** "buf" the input data to sign -** "len" the amount of data to sign -** "pk" the private key to encrypt with -** "algid" the signature/hash algorithm to sign with -** (must be compatible with the key type). -*/ -extern SECStatus SEC_SignData(SECItem *result, unsigned char *buf, int len, - SECKEYPrivateKey *pk, SECOidTag algid); - -/* -** Sign a pre-digested block of data using private key encryption, encoding -** The given signature/hash algorithm. -** "result" the final signature data (memory is allocated) -** "digest" the digest to sign -** "pk" the private key to encrypt with -** "algtag" The algorithm tag to encode (need for RSA only) -*/ -extern SECStatus SGN_Digest(SECKEYPrivateKey *privKey, - SECOidTag algtag, SECItem *result, SECItem *digest); - -/* -** DER sign a single block of data using private key encryption and the -** MD5 hashing algorithm. This routine first computes a digital signature -** using SEC_SignData, then wraps it with an CERTSignedData and then der -** encodes the result. -** "arena" is the memory arena to use to allocate data from -** "result" the final der encoded data (memory is allocated) -** "buf" the input data to sign -** "len" the amount of data to sign -** "pk" the private key to encrypt with -*/ -extern SECStatus SEC_DerSignData(PRArenaPool *arena, SECItem *result, - unsigned char *buf, int len, - SECKEYPrivateKey *pk, SECOidTag algid); - -/* -** Destroy a signed-data object. -** "sd" the object -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void SEC_DestroySignedData(CERTSignedData *sd, PRBool freeit); - -/****************************************/ -/* -** Signature verification operations -*/ - -/* -** Create a signature verification context. -** "key" the public key to verify with -** "sig" the encrypted signature data if sig is NULL then -** VFY_EndWithSignature must be called with the correct signature at -** the end of the processing. -** "algid" specifies the signing algorithm to use. This must match -** the key type. -** "wincx" void pointer to the window context -*/ -extern VFYContext *VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, - SECOidTag algid, void *wincx); - -/* -** Destroy a verification-context object. -** "cx" the context to destroy -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void VFY_DestroyContext(VFYContext *cx, PRBool freeit); - -extern SECStatus VFY_Begin(VFYContext *cx); - -/* -** Update a verification context with more input data. The input data -** is fed to a secure hash function (depending on what was in the -** encrypted signature data). -** "cx" the context -** "input" the input data -** "inputLen" the amount of input data -*/ -extern SECStatus VFY_Update(VFYContext *cx, unsigned char *input, - unsigned int inputLen); - -/* -** Finish the verification process. The return value is a status which -** indicates success or failure. On success, the SECSuccess value is -** returned. Otherwise, SECFailure is returned and the error code found -** using PORT_GetError() indicates what failure occurred. -** "cx" the context -*/ -extern SECStatus VFY_End(VFYContext *cx); - -/* -** Finish the verification process. The return value is a status which -** indicates success or failure. On success, the SECSuccess value is -** returned. Otherwise, SECFailure is returned and the error code found -** using PORT_GetError() indicates what failure occurred. If signature is -** supplied the verification uses this signature to verify, otherwise the -** signature passed in VFY_CreateContext() is used. -** VFY_EndWithSignature(cx,NULL); is identical to VFY_End(cx);. -** "cx" the context -** "sig" the encrypted signature data -*/ -extern SECStatus VFY_EndWithSignature(VFYContext *cx, SECItem *sig); - - -/* -** Verify the signature on a block of data for which we already have -** the digest. The signature data is an RSA private key encrypted -** block of data formatted according to PKCS#1. -** "dig" the digest -** "key" the public key to check the signature with -** "sig" the encrypted signature data -** "algid" specifies the signing algorithm to use. This must match -** the key type. -**/ -extern SECStatus VFY_VerifyDigest(SECItem *dig, SECKEYPublicKey *key, - SECItem *sig, SECOidTag algid, void *wincx); - -/* -** Verify the signature on a block of data. The signature data is an RSA -** private key encrypted block of data formatted according to PKCS#1. -** "buf" the input data -** "len" the length of the input data -** "key" the public key to check the signature with -** "sig" the encrypted signature data -** "algid" specifies the signing algorithm to use. This must match -** the key type. -*/ -extern SECStatus VFY_VerifyData(unsigned char *buf, int len, - SECKEYPublicKey *key, SECItem *sig, - SECOidTag algid, void *wincx); - - -SEC_END_PROTOS - -#endif /* _CRYPTOHI_H_ */ diff --git a/security/nss/lib/cryptohi/cryptoht.h b/security/nss/lib/cryptohi/cryptoht.h deleted file mode 100644 index 3116db279..000000000 --- a/security/nss/lib/cryptohi/cryptoht.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * cryptoht.h - public data structures for the crypto library - * - * 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. - * - * $Id$ - */ - -#ifndef _CRYPTOHT_H_ -#define _CRYPTOHT_H_ - -typedef struct SGNContextStr SGNContext; -typedef struct VFYContextStr VFYContext; - - -#endif /* _CRYPTOHT_H_ */ diff --git a/security/nss/lib/cryptohi/dsautil.c b/security/nss/lib/cryptohi/dsautil.c deleted file mode 100644 index c592ec7df..000000000 --- a/security/nss/lib/cryptohi/dsautil.c +++ /dev/null @@ -1,232 +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 "secasn1.h" -#include "secitem.h" -#include "prerr.h" - -#ifndef DSA_SUBPRIME_LEN -#define DSA_SUBPRIME_LEN 20 /* bytes */ -#endif - -typedef struct { - SECItem r; - SECItem s; -} DSA_ASN1Signature; - -const SEC_ASN1Template DSA_SignatureTemplate[] = -{ - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(DSA_ASN1Signature) }, - { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature,r) }, - { SEC_ASN1_INTEGER, offsetof(DSA_ASN1Signature,s) }, - { 0, } -}; - -/* Input is variable length multi-byte integer, MSB first (big endian). -** Most signficant bit of first byte is NOT treated as a sign bit. -** May be one or more leading bytes of zeros. -** Output is variable length multi-byte integer, MSB first (big endian). -** Most significant bit of first byte will be zero (positive sign bit) -** No more than one leading zero byte. -** Caller supplies dest buffer, and assures that it is long enough, -** e.g. at least one byte longer that src's buffer. -*/ -void -DSAU_ConvertUnsignedToSigned(SECItem *dest, SECItem *src) -{ - unsigned char *pSrc = src->data; - unsigned char *pDst = dest->data; - unsigned int cntSrc = src->len; - unsigned char c; - - /* skip any leading zeros. */ - while (cntSrc && !(c = *pSrc)) { - pSrc++; - cntSrc--; - } - if (!cntSrc) { - *pDst = 0; - dest->len = 1; - return; - } - - if (c & 0x80) - *pDst++ = 0; - - PORT_Memcpy(pDst, pSrc, cntSrc); - dest->len = (pDst - dest->data) + cntSrc; -} - -/* -** src is a buffer holding a signed variable length integer. -** dest is a buffer which will be filled with an unsigned integer, -** MSB first (big endian) with leading zeros, so that the last byte -** of src will be the LSB of the integer. The result will be exactly -** the length specified by the caller in dest->len. -** src can be shorter than dest. src can be longer than dst, but only -** if the extra leading bytes are zeros. -*/ -SECStatus -DSAU_ConvertSignedToFixedUnsigned(SECItem *dest, SECItem *src) -{ - unsigned char *pSrc = src->data; - unsigned char *pDst = dest->data; - unsigned int cntSrc = src->len; - unsigned int cntDst = dest->len; - int zCount = cntDst - cntSrc; - - if (zCount > 0) { - PORT_Memset(pDst, 0, zCount); - PORT_Memcpy(pDst + zCount, pSrc, cntSrc); - return SECSuccess; - } - if (zCount <= 0) { - /* Source is longer than destination. Check for leading zeros. */ - while (zCount++ < 0) { - if (*pSrc++ != 0) - goto loser; - } - } - PORT_Memcpy(pDst, pSrc, cntDst); - return SECSuccess; - -loser: - PORT_SetError( PR_INVALID_ARGUMENT_ERROR ); - return SECFailure; -} - -/* src is a "raw" DSA signature, 20 bytes of r followed by 20 bytes of s. -** dest is the signature DER encoded. ? -*/ -SECStatus -DSAU_EncodeDerSig(SECItem *dest, SECItem *src) -{ - SECItem * item; - SECItem srcItem; - DSA_ASN1Signature sig; - unsigned char signedR[DSA_SUBPRIME_LEN + 1]; - unsigned char signedS[DSA_SUBPRIME_LEN + 1]; - - PORT_Memset(&sig, 0, sizeof(sig)); - - PORT_Assert(src->len == 2 * DSA_SUBPRIME_LEN); - if (src->len != 2 * DSA_SUBPRIME_LEN) { - PORT_SetError( PR_INVALID_ARGUMENT_ERROR ); - return SECFailure; - } - - /* Must convert r and s from "unsigned" integers to "signed" integers. - ** If the high order bit of the first byte (MSB) is 1, then must - ** prepend with leading zero. - ** Must remove all but one leading zero byte from numbers. - */ - sig.r.type = siUnsignedInteger; - sig.r.data = signedR; - sig.r.len = sizeof signedR; - sig.s.type = siUnsignedInteger; - sig.s.data = signedS; - sig.s.len = sizeof signedR; - - srcItem.data = src->data; - srcItem.len = DSA_SUBPRIME_LEN; - - DSAU_ConvertUnsignedToSigned(&sig.r, &srcItem); - srcItem.data += DSA_SUBPRIME_LEN; - DSAU_ConvertUnsignedToSigned(&sig.s, &srcItem); - - item = SEC_ASN1EncodeItem(NULL, dest, &sig, DSA_SignatureTemplate); - if (item == NULL) - return SECFailure; - - /* XXX leak item? */ - return SECSuccess; -} - -/* src is a DER-encoded DSA signature. -** Returns a newly-allocated SECItem structure, pointing at a newly allocated -** buffer containing the "raw" DSA signature, which is 20 bytes of r, -** followed by 20 bytes of s. -*/ -SECItem * -DSAU_DecodeDerSig(SECItem *item) -{ - SECItem * result = NULL; - SECStatus status; - DSA_ASN1Signature sig; - SECItem dst; - - PORT_Memset(&sig, 0, sizeof(sig)); - - result = PORT_ZNew(SECItem); - if (result == NULL) - goto loser; - - result->len = 2 * DSA_SUBPRIME_LEN; - result->data = (unsigned char*)PORT_Alloc(2 * DSA_SUBPRIME_LEN); - if (result->data == NULL) - goto loser; - - sig.r.type = siUnsignedInteger; - sig.s.type = siUnsignedInteger; - status = SEC_ASN1DecodeItem(NULL, &sig, DSA_SignatureTemplate, item); - if (status != SECSuccess) - goto loser; - - /* Convert sig.r and sig.s from variable length signed integers to - ** fixed length unsigned integers. - */ - dst.data = result->data; - dst.len = DSA_SUBPRIME_LEN; - status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.r); - if (status != SECSuccess) - goto loser; - - dst.data += DSA_SUBPRIME_LEN; - status = DSAU_ConvertSignedToFixedUnsigned(&dst, &sig.s); - if (status != SECSuccess) - goto loser; - -done: - if (sig.r.data != NULL) - PORT_Free(sig.r.data); - if (sig.s.data != NULL) - PORT_Free(sig.s.data); - - return result; - -loser: - if (result != NULL) { - SECITEM_FreeItem(result, PR_TRUE); - result = NULL; - } - goto done; -} diff --git a/security/nss/lib/cryptohi/key.h b/security/nss/lib/cryptohi/key.h deleted file mode 100644 index 678beafd8..000000000 --- a/security/nss/lib/cryptohi/key.h +++ /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. - * - * key.h - public data structures and prototypes for the private key library - * - * $Id$ - */ - -#ifndef _KEY_H_ -#define _KEY_H_ - -#include "keyhi.h" - -#endif /* _KEY_H_ */ diff --git a/security/nss/lib/cryptohi/keyhi.h b/security/nss/lib/cryptohi/keyhi.h deleted file mode 100644 index 844a44877..000000000 --- a/security/nss/lib/cryptohi/keyhi.h +++ /dev/null @@ -1,273 +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): - * Dr Stephen Henson <stephen.henson@gemplus.com> - * - * 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. - * - * key.h - public data structures and prototypes for the private key library - * - * $Id$ - */ - -#ifndef _KEYHI_H_ -#define _KEYHI_H_ - -#include "plarena.h" - -#include "seccomon.h" -#include "secoidt.h" -#include "secdert.h" -#include "keythi.h" -#include "certt.h" -/*#include "secpkcs5.h" */ - -SEC_BEGIN_PROTOS - - -/* -** Destroy a subject-public-key-info object. -*/ -extern void SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki); - -/* -** Copy subject-public-key-info "src" to "dst". "dst" is filled in -** appropriately (memory is allocated for each of the sub objects). -*/ -extern SECStatus SECKEY_CopySubjectPublicKeyInfo(PRArenaPool *arena, - CERTSubjectPublicKeyInfo *dst, - CERTSubjectPublicKeyInfo *src); - -/* -** Update the PQG parameters for a cert's public key. -** Only done for DSA and Fortezza certs -*/ -extern SECStatus -SECKEY_UpdateCertPQG(CERTCertificate * subjectCert); - - -/* Compare the KEA parameters of two public keys. - * Only used by fortezza. */ - -extern SECStatus -SECKEY_KEAParamCompare(CERTCertificate *cert1,CERTCertificate *cert2); - -/* -** Return the strength of the public key -*/ -extern unsigned SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk); - - -/* -** Make a copy of the private key "privKey" -*/ -extern SECKEYPrivateKey *SECKEY_CopyPrivateKey(SECKEYPrivateKey *privKey); - -/* -** Make a copy of the public key "pubKey" -*/ -extern SECKEYPublicKey *SECKEY_CopyPublicKey(SECKEYPublicKey *pubKey); - -/* -** Convert a private key "privateKey" into a public key -*/ -extern SECKEYPublicKey *SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privateKey); - -/* - * create a new RSA key pair. The private Key is returned... - */ -SECKEYPrivateKey *SECKEY_CreateRSAPrivateKey(int keySizeInBits, - SECKEYPublicKey **pubk, void *cx); - -/* - * create a new DH key pair. The private Key is returned... - */ -SECKEYPrivateKey *SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, - SECKEYPublicKey **pubk, void *cx); -/* -** Create a subject-public-key-info based on a public key. -*/ -extern CERTSubjectPublicKeyInfo * -SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *k); - -/* -** Decode a DER encoded public key into an SECKEYPublicKey structure. -*/ -extern SECKEYPublicKey *SECKEY_DecodeDERPublicKey(SECItem *pubkder); - -/* -** Convert a base64 ascii encoded DER public key to our internal format. -*/ -extern SECKEYPublicKey *SECKEY_ConvertAndDecodePublicKey(char *pubkstr); - -/* -** Convert a base64 ascii encoded DER public key and challenge to spki, -** and verify the signature and challenge data are correct -*/ -extern CERTSubjectPublicKeyInfo * -SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge, - void *cx); - -/* -** Encode a CERTSubjectPublicKeyInfo structure. into a -** DER encoded subject public key info. -*/ -SECItem * -SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk); - -/* -** Decode a DER encoded subject public key info into a -** CERTSubjectPublicKeyInfo structure. -*/ -extern CERTSubjectPublicKeyInfo * -SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider); - -/* -** Convert a base64 ascii encoded DER subject public key info to our -** internal format. -*/ -extern CERTSubjectPublicKeyInfo * -SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(char *spkistr); - -/* - * extract the public key from a subject Public Key info structure. - * (used by JSS). - */ -extern SECKEYPublicKey * -SECKEY_ExtractPublicKey(CERTSubjectPublicKeyInfo *); - -/* -** Destroy a private key object. -** "key" the object -*/ -extern void SECKEY_DestroyPrivateKey(SECKEYPrivateKey *key); - - -/* -** Destroy a public key object. -** "key" the object -*/ -extern void SECKEY_DestroyPublicKey(SECKEYPublicKey *key); - -/* Destroy and zero out a private key info structure. for now this - * function zero's out memory allocated in an arena for the key - * since PORT_FreeArena does not currently do this. - * - * NOTE -- If a private key info is allocated in an arena, one should - * not call this function with freeit = PR_FALSE. The function should - * destroy the arena. - */ -extern void -SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk, PRBool freeit); - -/* Destroy and zero out an encrypted private key info. - * - * NOTE -- If a encrypted private key info is allocated in an arena, one should - * not call this function with freeit = PR_FALSE. The function should - * destroy the arena. - */ -extern void -SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki, - PRBool freeit); - -/* Copy private key info structure. - * poolp is the arena into which the contents of from is to be copied. - * NULL is a valid entry. - * to is the destination private key info - * from is the source private key info - * if either from or to is NULL or an error occurs, SECFailure is - * returned. otherwise, SECSuccess is returned. - */ -extern SECStatus -SECKEY_CopyPrivateKeyInfo(PRArenaPool *poolp, - SECKEYPrivateKeyInfo *to, - SECKEYPrivateKeyInfo *from); - -/* Copy encrypted private key info structure. - * poolp is the arena into which the contents of from is to be copied. - * NULL is a valid entry. - * to is the destination encrypted private key info - * from is the source encrypted private key info - * if either from or to is NULL or an error occurs, SECFailure is - * returned. otherwise, SECSuccess is returned. - */ -extern SECStatus -SECKEY_CopyEncryptedPrivateKeyInfo(PRArenaPool *poolp, - SECKEYEncryptedPrivateKeyInfo *to, - SECKEYEncryptedPrivateKeyInfo *from); -/* - * Accessor functions for key type of public and private keys. - */ -KeyType SECKEY_GetPrivateKeyType(SECKEYPrivateKey *privKey); -KeyType SECKEY_GetPublicKeyType(SECKEYPublicKey *pubKey); - -/* - * Creates a PublicKey from its DER encoding. - * Currently only supports RSA and DSA keys. - */ -SECKEYPublicKey* -SECKEY_ImportDERPublicKey(SECItem *derKey, CK_KEY_TYPE type); - -SECKEYPrivateKeyList* -SECKEY_NewPrivateKeyList(void); - -void -SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys); - -void -SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node); - -SECStatus -SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list, - SECKEYPrivateKey *key); - -#define PRIVKEY_LIST_HEAD(l) ((SECKEYPrivateKeyListNode*)PR_LIST_HEAD(&l->list)) -#define PRIVKEY_LIST_NEXT(n) ((SECKEYPrivateKeyListNode *)n->links.next) -#define PRIVKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list)) - -SECKEYPublicKeyList* -SECKEY_NewPublicKeyList(void); - -void -SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys); - -void -SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node); - -SECStatus -SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list, - SECKEYPublicKey *key); - -#define PUBKEY_LIST_HEAD(l) ((SECKEYPublicKeyListNode*)PR_LIST_HEAD(&l->list)) -#define PUBKEY_LIST_NEXT(n) ((SECKEYPublicKeyListNode *)n->links.next) -#define PUBKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list)) - -SEC_END_PROTOS - -#endif /* _KEYHI_H_ */ diff --git a/security/nss/lib/cryptohi/keyt.h b/security/nss/lib/cryptohi/keyt.h deleted file mode 100644 index 1b104b96a..000000000 --- a/security/nss/lib/cryptohi/keyt.h +++ /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. - * - * keyt.h - public data structures for the private key library - * - * $Id$ - */ - -#ifndef _KEYT_H_ -#define _KEYT_H_ - -#include "keythi.h" - -#endif /* _KEYT_H_ */ diff --git a/security/nss/lib/cryptohi/keythi.h b/security/nss/lib/cryptohi/keythi.h deleted file mode 100644 index 7b864b868..000000000 --- a/security/nss/lib/cryptohi/keythi.h +++ /dev/null @@ -1,223 +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 _KEYTHI_H_ -#define _KEYTHI_H_ 1 - -#include "plarena.h" -#include "pkcs11t.h" -#include "secmodt.h" -#include "prclist.h" - -typedef enum { - nullKey = 0, - rsaKey = 1, - dsaKey = 2, - fortezzaKey = 3, - dhKey = 4, - keaKey = 5 -} KeyType; - -/* -** Template Definitions -**/ - -SEC_BEGIN_PROTOS -extern const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[]; -extern const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[]; -extern const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[]; -extern const SEC_ASN1Template SECKEY_DHParamKeyTemplate[]; -extern const SEC_ASN1Template SECKEY_PQGParamsTemplate[]; -extern const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[]; - -/* Windows DLL accessor functions */ -extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_DSAPublicKeyTemplate; -extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_RSAPublicKeyTemplate; -SEC_END_PROTOS - - -/* -** RSA Public Key structures -** member names from PKCS#1, section 7.1 -*/ - -struct SECKEYRSAPublicKeyStr { - PRArenaPool * arena; - SECItem modulus; - SECItem publicExponent; -}; -typedef struct SECKEYRSAPublicKeyStr SECKEYRSAPublicKey; - - -/* -** DSA Public Key and related structures -*/ - -struct SECKEYPQGParamsStr { - PRArenaPool *arena; - SECItem prime; /* p */ - SECItem subPrime; /* q */ - SECItem base; /* g */ - /* XXX chrisk: this needs to be expanded to hold j and validationParms (RFC2459 7.3.2) */ -}; -typedef struct SECKEYPQGParamsStr SECKEYPQGParams; - -struct SECKEYDSAPublicKeyStr { - SECKEYPQGParams params; - SECItem publicValue; -}; -typedef struct SECKEYDSAPublicKeyStr SECKEYDSAPublicKey; - - -/* -** Diffie-Hellman Public Key structure -** Structure member names suggested by PKCS#3. -*/ -struct SECKEYDHParamsStr { - PRArenaPool * arena; - SECItem prime; /* p */ - SECItem base; /* g */ -}; -typedef struct SECKEYDHParamsStr SECKEYDHParams; - -struct SECKEYDHPublicKeyStr { - PRArenaPool * arena; - SECItem prime; - SECItem base; - SECItem publicValue; -}; -typedef struct SECKEYDHPublicKeyStr SECKEYDHPublicKey; - - -/* -** FORTEZZA Public Key structures -*/ -struct SECKEYFortezzaPublicKeyStr { - int KEAversion; - int DSSversion; - unsigned char KMID[8]; - SECItem clearance; - SECItem KEApriviledge; - SECItem DSSpriviledge; - SECItem KEAKey; - SECItem DSSKey; - SECKEYPQGParams params; - SECKEYPQGParams keaParams; -}; -typedef struct SECKEYFortezzaPublicKeyStr SECKEYFortezzaPublicKey; - -struct SECKEYDiffPQGParamsStr { - SECKEYPQGParams DiffKEAParams; - SECKEYPQGParams DiffDSAParams; -}; -typedef struct SECKEYDiffPQGParamsStr SECKEYDiffPQGParams; - -struct SECKEYPQGDualParamsStr { - SECKEYPQGParams CommParams; - SECKEYDiffPQGParams DiffParams; -}; -typedef struct SECKEYPQGDualParamsStr SECKEYPQGDualParams; - -struct SECKEYKEAParamsStr { - PLArenaPool *arena; - SECItem hash; -}; -typedef struct SECKEYKEAParamsStr SECKEYKEAParams; - -struct SECKEYKEAPublicKeyStr { - SECKEYKEAParams params; - SECItem publicValue; -}; -typedef struct SECKEYKEAPublicKeyStr SECKEYKEAPublicKey; - -/* -** A Generic public key object. -*/ -struct SECKEYPublicKeyStr { - PLArenaPool *arena; - KeyType keyType; - PK11SlotInfo *pkcs11Slot; - CK_OBJECT_HANDLE pkcs11ID; - union { - SECKEYRSAPublicKey rsa; - SECKEYDSAPublicKey dsa; - SECKEYDHPublicKey dh; - SECKEYKEAPublicKey kea; - SECKEYFortezzaPublicKey fortezza; - } u; -}; -typedef struct SECKEYPublicKeyStr SECKEYPublicKey; - -/* -** A generic key structure -*/ -struct SECKEYPrivateKeyStr { - PLArenaPool *arena; - KeyType keyType; - PK11SlotInfo *pkcs11Slot; /* pkcs11 slot this key lives in */ - CK_OBJECT_HANDLE pkcs11ID; /* ID of pkcs11 object */ - PRBool pkcs11IsTemp; /* temp pkcs11 object, delete it when done */ - void *wincx; /* context for errors and pw prompts */ -}; -typedef struct SECKEYPrivateKeyStr SECKEYPrivateKey; - -/* Despite the name, this struct isn't used by any pkcs5 code. -** It's used by pkcs7 and pkcs12 code. -*/ -typedef struct { - SECItem *pwitem; - PK11SymKey *key; - PK11SlotInfo *slot; - void *wincx; -} SEC_PKCS5KeyAndPassword; - -typedef struct { - PRCList links; - SECKEYPrivateKey *key; -} SECKEYPrivateKeyListNode; - -typedef struct { - PRCList list; - PRArenaPool *arena; -} SECKEYPrivateKeyList; - -typedef struct { - PRCList links; - SECKEYPublicKey *key; -} SECKEYPublicKeyListNode; - -typedef struct { - PRCList list; - PRArenaPool *arena; -} SECKEYPublicKeyList; -#endif /* _KEYTHI_H_ */ - diff --git a/security/nss/lib/cryptohi/manifest.mn b/security/nss/lib/cryptohi/manifest.mn deleted file mode 100644 index 69c62b72f..000000000 --- a/security/nss/lib/cryptohi/manifest.mn +++ /dev/null @@ -1,61 +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 = ../../.. - -MODULE = softoken - -REQUIRES = dbm - -# LIBRARY_NAME = cryptohi - -PRIVATE_EXPORTS = \ - cryptohi.h \ - cryptoht.h \ - hasht.h \ - key.h \ - keyhi.h \ - keyt.h \ - keythi.h \ - sechash.h \ - $(NULL) - -NO_LIBSRCS = \ - sechash.c \ - seckey.c \ - secsign.c \ - secvfy.c \ - dsautil.c \ - $(NULL) - -CSRCS = $(NULL) - diff --git a/security/nss/lib/cryptohi/sechash.c b/security/nss/lib/cryptohi/sechash.c deleted file mode 100644 index 36ee1efd2..000000000 --- a/security/nss/lib/cryptohi/sechash.c +++ /dev/null @@ -1,281 +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 "sechash.h" -#include "secoidt.h" -#include "blapi.h" -#include "pk11func.h" /* for the PK11_ calls below. */ - -static void * -null_hash_new_context(void) -{ - return NULL; -} - -static void * -null_hash_clone_context(void *v) -{ - PORT_Assert(v == NULL); - return NULL; -} - -static void -null_hash_begin(void *v) -{ -} - -static void -null_hash_update(void *v, const unsigned char *input, unsigned int length) -{ -} - -static void -null_hash_end(void *v, unsigned char *output, unsigned int *outLen, - unsigned int maxOut) -{ - *outLen = 0; -} - -static void -null_hash_destroy_context(void *v, PRBool b) -{ - PORT_Assert(v == NULL); -} - - -static void * -md2_NewContext(void) { - return (void *) PK11_CreateDigestContext(SEC_OID_MD2); -} - -static void * -md5_NewContext(void) { - return (void *) PK11_CreateDigestContext(SEC_OID_MD5); -} - -static void * -sha1_NewContext(void) { - return (void *) PK11_CreateDigestContext(SEC_OID_SHA1); -} - -const SECHashObject SECHashObjects[] = { - { 0, - (void * (*)(void)) null_hash_new_context, - (void * (*)(void *)) null_hash_clone_context, - (void (*)(void *, PRBool)) null_hash_destroy_context, - (void (*)(void *)) null_hash_begin, - (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update, - (void (*)(void *, unsigned char *, unsigned int *, - unsigned int)) null_hash_end - }, - { MD2_LENGTH, - (void * (*)(void)) md2_NewContext, - (void * (*)(void *)) PK11_CloneContext, - (void (*)(void *, PRBool)) PK11_DestroyContext, - (void (*)(void *)) PK11_DigestBegin, - (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp, - (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) - PK11_DigestFinal - }, - { MD5_LENGTH, - (void * (*)(void)) md5_NewContext, - (void * (*)(void *)) PK11_CloneContext, - (void (*)(void *, PRBool)) PK11_DestroyContext, - (void (*)(void *)) PK11_DigestBegin, - (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp, - (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) - PK11_DigestFinal - }, - { SHA1_LENGTH, - (void * (*)(void)) sha1_NewContext, - (void * (*)(void *)) PK11_CloneContext, - (void (*)(void *, PRBool)) PK11_DestroyContext, - (void (*)(void *)) PK11_DigestBegin, - (void (*)(void *, const unsigned char *, unsigned int)) PK11_DigestOp, - (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) - PK11_DigestFinal - }, -}; - -const SECHashObject * -HASH_GetHashObject(HASH_HashType type) -{ - return &SECHashObjects[type]; -} - - -unsigned int -HASH_ResultLen(HASH_HashType type) -{ - if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) { - return(0); - } - - return(SECHashObjects[type].length); -} - -unsigned int -HASH_ResultLenContext(HASHContext *context) -{ - return(context->hashobj->length); -} - - - -SECStatus -HASH_HashBuf(HASH_HashType type, - unsigned char *dest, - unsigned char *src, - uint32 src_len) -{ - HASHContext *cx; - unsigned int part; - - if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) { - return(SECFailure); - } - - cx = HASH_Create(type); - if ( cx == NULL ) { - return(SECFailure); - } - HASH_Begin(cx); - HASH_Update(cx, src, src_len); - HASH_End(cx, dest, &part, HASH_ResultLenContext(cx)); - HASH_Destroy(cx); - - return(SECSuccess); -} - -HASHContext * -HASH_Create(HASH_HashType type) -{ - void *hash_context = NULL; - HASHContext *ret = NULL; - - if ( ( type < HASH_AlgNULL ) || ( type >= HASH_AlgTOTAL ) ) { - return(NULL); - } - - hash_context = (* SECHashObjects[type].create)(); - if ( hash_context == NULL ) { - goto loser; - } - - ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext)); - if ( ret == NULL ) { - goto loser; - } - - ret->hash_context = hash_context; - ret->hashobj = &SECHashObjects[type]; - - return(ret); - -loser: - if ( hash_context != NULL ) { - (* SECHashObjects[type].destroy)(hash_context, PR_TRUE); - } - - return(NULL); -} - - -HASHContext * -HASH_Clone(HASHContext *context) -{ - void *hash_context = NULL; - HASHContext *ret = NULL; - - hash_context = (* context->hashobj->clone)(context->hash_context); - if ( hash_context == NULL ) { - goto loser; - } - - ret = (HASHContext *)PORT_Alloc(sizeof(HASHContext)); - if ( ret == NULL ) { - goto loser; - } - - ret->hash_context = hash_context; - ret->hashobj = context->hashobj; - - return(ret); - -loser: - if ( hash_context != NULL ) { - (* context->hashobj->destroy)(hash_context, PR_TRUE); - } - - return(NULL); - -} - -void -HASH_Destroy(HASHContext *context) -{ - (* context->hashobj->destroy)(context->hash_context, PR_TRUE); - PORT_Free(context); - return; -} - - -void -HASH_Begin(HASHContext *context) -{ - (* context->hashobj->begin)(context->hash_context); - return; -} - - -void -HASH_Update(HASHContext *context, - const unsigned char *src, - unsigned int len) -{ - (* context->hashobj->update)(context->hash_context, src, len); - return; -} - -void -HASH_End(HASHContext *context, - unsigned char *result, - unsigned int *result_len, - unsigned int max_result_len) -{ - (* context->hashobj->end)(context->hash_context, result, result_len, - max_result_len); - return; -} - - - diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c deleted file mode 100644 index 7f0b4025a..000000000 --- a/security/nss/lib/cryptohi/seckey.c +++ /dev/null @@ -1,1966 +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): - * Dr Stephen Henson <stephen.henson@gemplus.com> - * - * 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 "cryptohi.h" -#include "keyhi.h" -#include "secrng.h" -#include "secoid.h" -#include "secitem.h" -#include "secder.h" -#include "base64.h" -#include "secasn1.h" -#include "cert.h" -#include "pk11func.h" -#include "secerr.h" -#include "secdig.h" -#include "prtime.h" - -const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTSubjectPublicKeyInfo) }, - { SEC_ASN1_INLINE, - offsetof(CERTSubjectPublicKeyInfo,algorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(CERTSubjectPublicKeyInfo,subjectPublicKey), }, - { 0, } -}; - -const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[] = -{ - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPublicKeyAndChallenge) }, - { SEC_ASN1_ANY, offsetof(CERTPublicKeyAndChallenge,spki) }, - { SEC_ASN1_IA5_STRING, offsetof(CERTPublicKeyAndChallenge,challenge) }, - { 0 } -}; - -const SEC_ASN1Template SECKEY_RSAPublicKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.rsa.modulus), }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.rsa.publicExponent), }, - { 0, } -}; - -const SEC_ASN1Template SECKEY_DSAPublicKeyTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dsa.publicValue), }, - { 0, } -}; - -const SEC_ASN1Template SECKEY_PQGParamsTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) }, - { 0, } -}; - -const SEC_ASN1Template SECKEY_DHPublicKeyTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dh.publicValue), }, - { 0, } -}; - -const SEC_ASN1Template SECKEY_DHParamKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPublicKey) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dh.prime), }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.dh.base), }, - /* XXX chrisk: this needs to be expanded for decoding of j and validationParms (RFC2459 7.3.2) */ - { SEC_ASN1_SKIP_REST }, - { 0, } -}; - -const SEC_ASN1Template SECKEY_FortezzaParameterTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) }, - { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPQGParams,prime), }, - { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPQGParams,subPrime), }, - { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPQGParams,base), }, - { 0 }, -}; - -const SEC_ASN1Template SECKEY_FortezzaDiffParameterTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYDiffPQGParams) }, - { SEC_ASN1_INLINE, offsetof(SECKEYDiffPQGParams,DiffKEAParams), - SECKEY_FortezzaParameterTemplate}, - { SEC_ASN1_INLINE, offsetof(SECKEYDiffPQGParams,DiffDSAParams), - SECKEY_FortezzaParameterTemplate}, - { 0 }, -}; - -const SEC_ASN1Template SECKEY_FortezzaPreParamTemplate[] = { - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(SECKEYPQGDualParams,CommParams), - SECKEY_FortezzaParameterTemplate}, - { 0, } -}; - -const SEC_ASN1Template SECKEY_FortezzaAltPreParamTemplate[] = { - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(SECKEYPQGDualParams,DiffParams), - SECKEY_FortezzaDiffParameterTemplate}, - { 0, } -}; - -const SEC_ASN1Template SECKEY_KEAPublicKeyTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(SECKEYPublicKey,u.kea.publicValue), }, - { 0, } -}; - -const SEC_ASN1Template SECKEY_KEAParamsTemplate[] = { - { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPublicKey,u.kea.params.hash), }, - { 0, } -}; - -SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_DSAPublicKeyTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_RSAPublicKeyTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SubjectPublicKeyInfoTemplate) - -/* - * See bugzilla bug 125359 - * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, - * all of the templates above that en/decode into integers must be converted - * from ASN.1's signed integer type. This is done by marking either the - * source or destination (encoding or decoding, respectively) type as - * siUnsignedInteger. - */ -static void -prepare_rsa_pub_key_for_asn1(SECKEYPublicKey *pubk) -{ - pubk->u.rsa.modulus.type = siUnsignedInteger; - pubk->u.rsa.publicExponent.type = siUnsignedInteger; -} - -static void -prepare_dsa_pub_key_for_asn1(SECKEYPublicKey *pubk) -{ - pubk->u.dsa.publicValue.type = siUnsignedInteger; -} - -static void -prepare_pqg_params_for_asn1(SECKEYPQGParams *params) -{ - params->prime.type = siUnsignedInteger; - params->subPrime.type = siUnsignedInteger; - params->base.type = siUnsignedInteger; -} - -static void -prepare_dh_pub_key_for_asn1(SECKEYPublicKey *pubk) -{ - pubk->u.dh.prime.type = siUnsignedInteger; - pubk->u.dh.base.type = siUnsignedInteger; - pubk->u.dh.publicValue.type = siUnsignedInteger; -} - -static void -prepare_kea_pub_key_for_asn1(SECKEYPublicKey *pubk) -{ - pubk->u.kea.publicValue.type = siUnsignedInteger; -} - -/* Create an RSA key pair is any slot able to do so. -** The created keys are "session" (temporary), not "token" (permanent), -** and they are "sensitive", which makes them costly to move to another token. -*/ -SECKEYPrivateKey * -SECKEY_CreateRSAPrivateKey(int keySizeInBits,SECKEYPublicKey **pubk, void *cx) -{ - SECKEYPrivateKey *privk; - PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN,cx); - PK11RSAGenParams param; - - param.keySizeInBits = keySizeInBits; - param.pe = 65537L; - - privk = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN,¶m,pubk, - PR_FALSE, PR_TRUE, cx); - PK11_FreeSlot(slot); - return(privk); -} - -/* Create a DH key pair in any slot able to do so, -** This is a "session" (temporary), not "token" (permanent) key. -** Because of the high probability that this key will need to be moved to -** another token, and the high cost of moving "sensitive" keys, we attempt -** to create this key pair without the "sensitive" attribute, but revert to -** creating a "sensitive" key if necessary. -*/ -SECKEYPrivateKey * -SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *cx) -{ - SECKEYPrivateKey *privk; - PK11SlotInfo *slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,cx); - - privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param, - pubk, PR_FALSE, PR_FALSE, cx); - if (!privk) - privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param, - pubk, PR_FALSE, PR_TRUE, cx); - - PK11_FreeSlot(slot); - return(privk); -} - -void -SECKEY_DestroyPrivateKey(SECKEYPrivateKey *privk) -{ - if (privk) { - if (privk->pkcs11Slot) { - if (privk->pkcs11IsTemp) { - PK11_DestroyObject(privk->pkcs11Slot,privk->pkcs11ID); - } - PK11_FreeSlot(privk->pkcs11Slot); - - } - if (privk->arena) { - PORT_FreeArena(privk->arena, PR_TRUE); - } - } -} - -void -SECKEY_DestroyPublicKey(SECKEYPublicKey *pubk) -{ - if (pubk) { - if (pubk->pkcs11Slot) { - if (!PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { - PK11_DestroyObject(pubk->pkcs11Slot,pubk->pkcs11ID); - } - PK11_FreeSlot(pubk->pkcs11Slot); - } - if (pubk->arena) { - PORT_FreeArena(pubk->arena, PR_FALSE); - } - } -} - -SECStatus -SECKEY_CopySubjectPublicKeyInfo(PRArenaPool *arena, - CERTSubjectPublicKeyInfo *to, - CERTSubjectPublicKeyInfo *from) -{ - SECStatus rv; - - rv = SECOID_CopyAlgorithmID(arena, &to->algorithm, &from->algorithm); - if (rv == SECSuccess) - rv = SECITEM_CopyItem(arena, &to->subjectPublicKey, &from->subjectPublicKey); - - return rv; -} - -SECStatus -SECKEY_KEASetParams(SECKEYKEAParams * params, SECKEYPublicKey * pubKey) { - - if (pubKey->keyType == fortezzaKey) { - /* the key is a fortezza V1 public key */ - - /* obtain hash of pubkey->u.fortezza.params.prime.data + - pubkey->u.fortezza.params.subPrime.data + - pubkey->u.fortezza.params.base.data */ - - /* store hash in params->hash */ - - } else if (pubKey->keyType == keaKey) { - - /* the key is a new fortezza KEA public key. */ - SECITEM_CopyItem(pubKey->arena, ¶ms->hash, - &pubKey->u.kea.params.hash ); - - } else { - - /* the key has no KEA parameters */ - return SECFailure; - } - return SECSuccess; -} - - -SECStatus -SECKEY_KEAParamCompare(CERTCertificate *cert1,CERTCertificate *cert2) -{ - - SECStatus rv; - - SECKEYPublicKey *pubKey1 = 0; - SECKEYPublicKey *pubKey2 = 0; - - SECKEYKEAParams params1; - SECKEYKEAParams params2; - - - rv = SECFailure; - - /* get cert1's public key */ - pubKey1 = CERT_ExtractPublicKey(cert1); - if ( !pubKey1 ) { - return(SECFailure); - } - - - /* get cert2's public key */ - pubKey2 = CERT_ExtractPublicKey(cert2); - if ( !pubKey2 ) { - return(SECFailure); - } - - /* handle the case when both public keys are new - * fortezza KEA public keys. */ - - if ((pubKey1->keyType == keaKey) && - (pubKey2->keyType == keaKey) ) { - - rv = (SECStatus)SECITEM_CompareItem(&pubKey1->u.kea.params.hash, - &pubKey2->u.kea.params.hash); - goto done; - } - - /* handle the case when both public keys are old fortezza - * public keys. */ - - if ((pubKey1->keyType == fortezzaKey) && - (pubKey2->keyType == fortezzaKey) ) { - - rv = (SECStatus)SECITEM_CompareItem(&pubKey1->u.fortezza.keaParams.prime, - &pubKey2->u.fortezza.keaParams.prime); - - if (rv == SECEqual) { - rv = (SECStatus)SECITEM_CompareItem(&pubKey1->u.fortezza.keaParams.subPrime, - &pubKey2->u.fortezza.keaParams.subPrime); - } - - if (rv == SECEqual) { - rv = (SECStatus)SECITEM_CompareItem(&pubKey1->u.fortezza.keaParams.base, - &pubKey2->u.fortezza.keaParams.base); - } - - goto done; - } - - - /* handle the case when the public keys are a mixture of - * old and new. */ - - rv = SECKEY_KEASetParams(¶ms1, pubKey1); - if (rv != SECSuccess) return rv; - - rv = SECKEY_KEASetParams(¶ms2, pubKey2); - if (rv != SECSuccess) return rv; - - rv = (SECStatus)SECITEM_CompareItem(¶ms1.hash, ¶ms2.hash); - -done: - SECKEY_DestroyPublicKey(pubKey1); - SECKEY_DestroyPublicKey(pubKey2); - - return rv; /* returns SECEqual if parameters are equal */ - -} - - -/* Procedure to update the pqg parameters for a cert's public key. - * pqg parameters only need to be updated for DSA and fortezza certificates. - * The procedure uses calls to itself recursively to update a certificate - * issuer's pqg parameters. Some important rules are: - * - Do nothing if the cert already has PQG parameters. - * - If the cert does not have PQG parameters, obtain them from the issuer. - * - A valid cert chain cannot have a DSA or Fortezza cert without - * pqg parameters that has a parent that is not a DSA or Fortezza cert. - * - pqg paramters are stored in two different formats: the standard - * DER encoded format and the fortezza-only wrapped format. The params - * should be copied from issuer to subject cert without modifying the - * formats. The public key extraction code will deal with the different - * formats at the time of extraction. */ - -SECStatus -seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count) -{ - SECStatus rv, rvCompare; - SECOidData *oid=NULL; - int tag; - CERTSubjectPublicKeyInfo * subjectSpki=NULL; - CERTSubjectPublicKeyInfo * issuerSpki=NULL; - CERTCertificate *issuerCert = NULL; - - rv = SECSuccess; - - /* increment cert chain length counter*/ - count++; - - /* check if cert chain length exceeds the maximum length*/ - if (count > CERT_MAX_CERT_CHAIN) { - return SECFailure; - } - - oid = SECOID_FindOID(&subjectCert->subjectPublicKeyInfo.algorithm.algorithm); - if (oid != NULL) { - tag = oid->offset; - - /* Check if cert has a DSA or Fortezza public key. If not, return - * success since no PQG params need to be updated. */ - - if ( (tag != SEC_OID_MISSI_KEA_DSS_OLD) && - (tag != SEC_OID_MISSI_DSS_OLD) && - (tag != SEC_OID_MISSI_KEA_DSS) && - (tag != SEC_OID_MISSI_DSS) && - (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) && - (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) && - (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) && - (tag != SEC_OID_SDN702_DSA_SIGNATURE) ) { - - return SECSuccess; - } - } else { - return SECFailure; /* return failure if oid is NULL */ - } - - /* if cert has PQG parameters, return success */ - - subjectSpki=&subjectCert->subjectPublicKeyInfo; - - if (subjectSpki->algorithm.parameters.len != 0) { - return SECSuccess; - } - - /* check if the cert is self-signed */ - rvCompare = (SECStatus)SECITEM_CompareItem(&subjectCert->derSubject, - &subjectCert->derIssuer); - if (rvCompare == SECEqual) { - /* fail since cert is self-signed and has no pqg params. */ - return SECFailure; - } - - /* get issuer cert */ - issuerCert = CERT_FindCertIssuer(subjectCert, PR_Now(), certUsageAnyCA); - if ( ! issuerCert ) { - return SECFailure; - } - - /* if parent is not DSA or fortezza, return failure since - we don't allow this case. */ - - oid = SECOID_FindOID(&issuerCert->subjectPublicKeyInfo.algorithm.algorithm); - if (oid != NULL) { - tag = oid->offset; - - /* Check if issuer cert has a DSA or Fortezza public key. If not, - * return failure. */ - - if ( (tag != SEC_OID_MISSI_KEA_DSS_OLD) && - (tag != SEC_OID_MISSI_DSS_OLD) && - (tag != SEC_OID_MISSI_KEA_DSS) && - (tag != SEC_OID_MISSI_DSS) && - (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) && - (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) && - (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) && - (tag != SEC_OID_SDN702_DSA_SIGNATURE) ) { - - return SECFailure; - } - } else { - return SECFailure; /* return failure if oid is NULL */ - } - - - /* at this point the subject cert has no pqg parameters and the - * issuer cert has a DSA or fortezza public key. Update the issuer's - * pqg parameters with a recursive call to this same function. */ - - rv = seckey_UpdateCertPQGChain(issuerCert, count); - if (rv != SECSuccess) return rv; - - /* ensure issuer has pqg parameters */ - - issuerSpki=&issuerCert->subjectPublicKeyInfo; - if (issuerSpki->algorithm.parameters.len == 0) { - rv = SECFailure; - } - - /* if update was successful and pqg params present, then copy the - * parameters to the subject cert's key. */ - - if (rv == SECSuccess) { - rv = SECITEM_CopyItem(subjectCert->arena, - &subjectSpki->algorithm.parameters, - &issuerSpki->algorithm.parameters); - } - - return rv; - -} - - -SECStatus -SECKEY_UpdateCertPQG(CERTCertificate * subjectCert) -{ - return(seckey_UpdateCertPQGChain(subjectCert,0)); -} - - -/* Decode the PQG parameters. The params could be stored in two - * possible formats, the old fortezza-only wrapped format or - * the standard DER encoded format. Store the decoded parameters in an - * old fortezza cert data structure */ - -SECStatus -SECKEY_FortezzaDecodePQGtoOld(PRArenaPool *arena, SECKEYPublicKey *pubk, - SECItem *params) { - SECStatus rv; - SECKEYPQGDualParams dual_params; - - if (params == NULL) return SECFailure; - - if (params->data == NULL) return SECFailure; - - /* Check if params use the standard format. - * The value 0xa1 will appear in the first byte of the parameter data - * if the PQG parameters are not using the standard format. This - * code should be changed to use a better method to detect non-standard - * parameters. */ - - if ((params->data[0] != 0xa1) && - (params->data[0] != 0xa0)) { - - /* PQG params are in the standard format */ - - /* Store DSA PQG parameters */ - prepare_pqg_params_for_asn1(&pubk->u.fortezza.params); - rv = SEC_ASN1DecodeItem(arena, &pubk->u.fortezza.params, - SECKEY_PQGParamsTemplate, - params); - - if (rv == SECSuccess) { - - /* Copy the DSA PQG parameters to the KEA PQG parameters. */ - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime, - &pubk->u.fortezza.params.prime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime, - &pubk->u.fortezza.params.subPrime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base, - &pubk->u.fortezza.params.base); - if (rv != SECSuccess) return rv; - } - - } else { - - dual_params.CommParams.prime.len = 0; - dual_params.CommParams.subPrime.len = 0; - dual_params.CommParams.base.len = 0; - dual_params.DiffParams.DiffDSAParams.prime.len = 0; - dual_params.DiffParams.DiffDSAParams.subPrime.len = 0; - dual_params.DiffParams.DiffDSAParams.base.len = 0; - - /* else the old fortezza-only wrapped format is used. */ - - if (params->data[0] == 0xa1) { - rv = SEC_ASN1DecodeItem(arena, &dual_params, - SECKEY_FortezzaPreParamTemplate, params); - } else { - rv = SEC_ASN1DecodeItem(arena, &dual_params, - SECKEY_FortezzaAltPreParamTemplate, params); - } - - if (rv < 0) return rv; - - if ( (dual_params.CommParams.prime.len > 0) && - (dual_params.CommParams.subPrime.len > 0) && - (dual_params.CommParams.base.len > 0) ) { - /* copy in common params */ - - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.prime, - &dual_params.CommParams.prime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.subPrime, - &dual_params.CommParams.subPrime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.base, - &dual_params.CommParams.base); - - /* Copy the DSA PQG parameters to the KEA PQG parameters. */ - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime, - &pubk->u.fortezza.params.prime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime, - &pubk->u.fortezza.params.subPrime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base, - &pubk->u.fortezza.params.base); - if (rv != SECSuccess) return rv; - - } else { - - /* else copy in different params */ - - /* copy DSA PQG parameters */ - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.prime, - &dual_params.DiffParams.DiffDSAParams.prime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.subPrime, - &dual_params.DiffParams.DiffDSAParams.subPrime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.params.base, - &dual_params.DiffParams.DiffDSAParams.base); - - /* copy KEA PQG parameters */ - - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.prime, - &dual_params.DiffParams.DiffKEAParams.prime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.subPrime, - &dual_params.DiffParams.DiffKEAParams.subPrime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.keaParams.base, - &dual_params.DiffParams.DiffKEAParams.base); - } - - } - return rv; -} - - -/* Decode the DSA PQG parameters. The params could be stored in two - * possible formats, the old fortezza-only wrapped format or - * the normal standard format. Store the decoded parameters in - * a V3 certificate data structure. */ - -SECStatus -SECKEY_DSADecodePQG(PRArenaPool *arena, SECKEYPublicKey *pubk, SECItem *params) { - SECStatus rv; - SECKEYPQGDualParams dual_params; - - if (params == NULL) return SECFailure; - - if (params->data == NULL) return SECFailure; - - /* Check if params use the standard format. - * The value 0xa1 will appear in the first byte of the parameter data - * if the PQG parameters are not using the standard format. This - * code should be changed to use a better method to detect non-standard - * parameters. */ - - if ((params->data[0] != 0xa1) && - (params->data[0] != 0xa0)) { - - /* PQG params are in the standard format */ - prepare_pqg_params_for_asn1(&pubk->u.dsa.params); - rv = SEC_ASN1DecodeItem(arena, &pubk->u.dsa.params, - SECKEY_PQGParamsTemplate, - params); - } else { - - dual_params.CommParams.prime.len = 0; - dual_params.CommParams.subPrime.len = 0; - dual_params.CommParams.base.len = 0; - dual_params.DiffParams.DiffDSAParams.prime.len = 0; - dual_params.DiffParams.DiffDSAParams.subPrime.len = 0; - dual_params.DiffParams.DiffDSAParams.base.len = 0; - - /* else the old fortezza-only wrapped format is used. */ - if (params->data[0] == 0xa1) { - rv = SEC_ASN1DecodeItem(arena, &dual_params, - SECKEY_FortezzaPreParamTemplate, params); - } else { - rv = SEC_ASN1DecodeItem(arena, &dual_params, - SECKEY_FortezzaAltPreParamTemplate, params); - } - - if (rv < 0) return rv; - - if ( (dual_params.CommParams.prime.len > 0) && - (dual_params.CommParams.subPrime.len > 0) && - (dual_params.CommParams.base.len > 0) ) { - /* copy in common params */ - - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime, - &dual_params.CommParams.prime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime, - &dual_params.CommParams.subPrime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base, - &dual_params.CommParams.base); - - } else { - - /* else copy in different params */ - - /* copy DSA PQG parameters */ - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime, - &dual_params.DiffParams.DiffDSAParams.prime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime, - &dual_params.DiffParams.DiffDSAParams.subPrime); - if (rv != SECSuccess) return rv; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base, - &dual_params.DiffParams.DiffDSAParams.base); - - } - } - return rv; -} - - - -/* Decodes the DER encoded fortezza public key and stores the results in a - * structure of type SECKEYPublicKey. */ - -SECStatus -SECKEY_FortezzaDecodeCertKey(PRArenaPool *arena, SECKEYPublicKey *pubk, - SECItem *rawkey, SECItem *params) { - - unsigned char *rawptr = rawkey->data; - unsigned char *end = rawkey->data + rawkey->len; - unsigned char *clearptr; - - /* first march down and decode the raw key data */ - - /* version */ - pubk->u.fortezza.KEAversion = *rawptr++; - if (*rawptr++ != 0x01) { - return SECFailure; - } - - /* KMID */ - PORT_Memcpy(pubk->u.fortezza.KMID,rawptr, - sizeof(pubk->u.fortezza.KMID)); - rawptr += sizeof(pubk->u.fortezza.KMID); - - /* clearance (the string up to the first byte with the hi-bit on */ - clearptr = rawptr; - while ((rawptr < end) && (*rawptr++ & 0x80)); - - if (rawptr >= end) { return SECFailure; } - pubk->u.fortezza.clearance.len = rawptr - clearptr; - pubk->u.fortezza.clearance.data = - (unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.clearance.len); - if (pubk->u.fortezza.clearance.data == NULL) { - return SECFailure; - } - PORT_Memcpy(pubk->u.fortezza.clearance.data,clearptr, - pubk->u.fortezza.clearance.len); - - /* KEAPrivilege (the string up to the first byte with the hi-bit on */ - clearptr = rawptr; - while ((rawptr < end) && (*rawptr++ & 0x80)); - if (rawptr >= end) { return SECFailure; } - pubk->u.fortezza.KEApriviledge.len = rawptr - clearptr; - pubk->u.fortezza.KEApriviledge.data = - (unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.KEApriviledge.len); - if (pubk->u.fortezza.KEApriviledge.data == NULL) { - return SECFailure; - } - PORT_Memcpy(pubk->u.fortezza.KEApriviledge.data,clearptr, - pubk->u.fortezza.KEApriviledge.len); - - - /* now copy the key. The next to bytes are the key length, and the - * key follows */ - pubk->u.fortezza.KEAKey.len = (*rawptr << 8) | rawptr[1]; - - rawptr += 2; - if (rawptr+pubk->u.fortezza.KEAKey.len > end) { return SECFailure; } - pubk->u.fortezza.KEAKey.data = - (unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.KEAKey.len); - if (pubk->u.fortezza.KEAKey.data == NULL) { - return SECFailure; - } - PORT_Memcpy(pubk->u.fortezza.KEAKey.data,rawptr, - pubk->u.fortezza.KEAKey.len); - rawptr += pubk->u.fortezza.KEAKey.len; - - /* shared key */ - if (rawptr >= end) { - pubk->u.fortezza.DSSKey.len = pubk->u.fortezza.KEAKey.len; - /* this depends on the fact that we are going to get freed with an - * ArenaFree call. We cannot free DSSKey and KEAKey separately */ - pubk->u.fortezza.DSSKey.data= - pubk->u.fortezza.KEAKey.data; - pubk->u.fortezza.DSSpriviledge.len = - pubk->u.fortezza.KEApriviledge.len; - pubk->u.fortezza.DSSpriviledge.data = - pubk->u.fortezza.DSSpriviledge.data; - goto done; - } - - - /* DSS Version is next */ - pubk->u.fortezza.DSSversion = *rawptr++; - - if (*rawptr++ != 2) { - return SECFailure; - } - - /* DSSPrivilege (the string up to the first byte with the hi-bit on */ - clearptr = rawptr; - while ((rawptr < end) && (*rawptr++ & 0x80)); - if (rawptr >= end) { return SECFailure; } - pubk->u.fortezza.DSSpriviledge.len = rawptr - clearptr; - pubk->u.fortezza.DSSpriviledge.data = - (unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.DSSpriviledge.len); - if (pubk->u.fortezza.DSSpriviledge.data == NULL) { - return SECFailure; - } - PORT_Memcpy(pubk->u.fortezza.DSSpriviledge.data,clearptr, - pubk->u.fortezza.DSSpriviledge.len); - - /* finally copy the DSS key. The next to bytes are the key length, - * and the key follows */ - pubk->u.fortezza.DSSKey.len = (*rawptr << 8) | rawptr[1]; - - rawptr += 2; - if (rawptr+pubk->u.fortezza.DSSKey.len > end){ return SECFailure; } - pubk->u.fortezza.DSSKey.data = - (unsigned char*)PORT_ArenaZAlloc(arena,pubk->u.fortezza.DSSKey.len); - if (pubk->u.fortezza.DSSKey.data == NULL) { - return SECFailure; - } - PORT_Memcpy(pubk->u.fortezza.DSSKey.data,rawptr, - pubk->u.fortezza.DSSKey.len); - - /* ok, now we decode the parameters */ -done: - - return SECKEY_FortezzaDecodePQGtoOld(arena, pubk, params); -} - - -/* Function used to determine what kind of cert we are dealing with. */ -KeyType -CERT_GetCertKeyType (CERTSubjectPublicKeyInfo *spki) { - int tag; - KeyType keyType; - - tag = SECOID_GetAlgorithmTag(&spki->algorithm); - switch (tag) { - case SEC_OID_X500_RSA_ENCRYPTION: - case SEC_OID_PKCS1_RSA_ENCRYPTION: - keyType = rsaKey; - break; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - keyType = dsaKey; - break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_DSS_OLD: - case SEC_OID_MISSI_DSS: - keyType = fortezzaKey; - break; - case SEC_OID_MISSI_KEA: - case SEC_OID_MISSI_ALT_KEA: - keyType = keaKey; - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: - keyType = dhKey; - break; - default: - keyType = nullKey; - } - return keyType; -} - -static SECKEYPublicKey * -seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) -{ - SECKEYPublicKey *pubk; - SECItem os; - SECStatus rv; - PRArenaPool *arena; - SECOidTag tag; - - arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) - return NULL; - - pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); - if (pubk == NULL) { - PORT_FreeArena (arena, PR_FALSE); - return NULL; - } - - pubk->arena = arena; - pubk->pkcs11Slot = 0; - pubk->pkcs11ID = CK_INVALID_HANDLE; - - - /* Convert bit string length from bits to bytes */ - os = spki->subjectPublicKey; - DER_ConvertBitString (&os); - - tag = SECOID_GetAlgorithmTag(&spki->algorithm); - switch ( tag ) { - case SEC_OID_X500_RSA_ENCRYPTION: - case SEC_OID_PKCS1_RSA_ENCRYPTION: - pubk->keyType = rsaKey; - prepare_rsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &os); - if (rv == SECSuccess) - return pubk; - break; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - case SEC_OID_SDN702_DSA_SIGNATURE: - pubk->keyType = dsaKey; - prepare_dsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &os); - if (rv != SECSuccess) break; - - rv = SECKEY_DSADecodePQG(arena, pubk, - &spki->algorithm.parameters); - - if (rv == SECSuccess) return pubk; - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: - pubk->keyType = dhKey; - prepare_dh_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &os); - if (rv != SECSuccess) break; - - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_DHParamKeyTemplate, - &spki->algorithm.parameters); - - if (rv == SECSuccess) return pubk; - break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_DSS_OLD: - case SEC_OID_MISSI_DSS: - pubk->keyType = fortezzaKey; - rv = SECKEY_FortezzaDecodeCertKey(arena, pubk, &os, - &spki->algorithm.parameters); - if (rv == SECSuccess) - return pubk; - break; - - case SEC_OID_MISSI_KEA: - pubk->keyType = keaKey; - - prepare_kea_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, - SECKEY_KEAPublicKeyTemplate, &os); - if (rv != SECSuccess) break; - - - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_KEAParamsTemplate, - &spki->algorithm.parameters); - - if (rv == SECSuccess) - return pubk; - - break; - - case SEC_OID_MISSI_ALT_KEA: - pubk->keyType = keaKey; - - rv = SECITEM_CopyItem(arena,&pubk->u.kea.publicValue,&os); - if (rv != SECSuccess) break; - - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_KEAParamsTemplate, - &spki->algorithm.parameters); - - if (rv == SECSuccess) - return pubk; - - break; - - - default: - rv = SECFailure; - break; - } - - SECKEY_DestroyPublicKey (pubk); - return NULL; -} - - -/* required for JSS */ -SECKEYPublicKey * -SECKEY_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) -{ - return seckey_ExtractPublicKey(spki); -} - -SECKEYPublicKey * -CERT_ExtractPublicKey(CERTCertificate *cert) -{ - SECStatus rv; - - rv = SECKEY_UpdateCertPQG(cert); - if (rv != SECSuccess) return NULL; - - return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo); -} - -/* - * Get the public key for the fortezza KMID. NOTE this requires the - * PQG paramters to be set. We probably should have a fortezza call that - * just extracts the kmid for us directly so this function can work - * without having the whole cert chain - */ -SECKEYPublicKey * -CERT_KMIDPublicKey(CERTCertificate *cert) -{ - return seckey_ExtractPublicKey(&cert->subjectPublicKeyInfo); -} - -/* returns key strength in bytes (not bits) */ -unsigned -SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk) -{ - unsigned char b0; - - /* interpret modulus length as key strength... in - * fortezza that's the public key length */ - - switch (pubk->keyType) { - case rsaKey: - b0 = pubk->u.rsa.modulus.data[0]; - return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; - case dsaKey: - b0 = pubk->u.dsa.publicValue.data[0]; - return b0 ? pubk->u.dsa.publicValue.len : - pubk->u.dsa.publicValue.len - 1; - case dhKey: - b0 = pubk->u.dh.publicValue.data[0]; - return b0 ? pubk->u.dh.publicValue.len : - pubk->u.dh.publicValue.len - 1; - case fortezzaKey: - return PR_MAX(pubk->u.fortezza.KEAKey.len, pubk->u.fortezza.DSSKey.len); - default: - break; - } - return 0; -} - -SECKEYPrivateKey * -SECKEY_CopyPrivateKey(SECKEYPrivateKey *privk) -{ - SECKEYPrivateKey *copyk; - PRArenaPool *arena; - - if (privk == NULL) { - return NULL; - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - copyk = (SECKEYPrivateKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPrivateKey)); - if (copyk) { - copyk->arena = arena; - copyk->keyType = privk->keyType; - - /* copy the PKCS #11 parameters */ - copyk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot); - /* if the key we're referencing was a temparary key we have just - * created, that we want to go away when we're through, we need - * to make a copy of it */ - if (privk->pkcs11IsTemp) { - copyk->pkcs11ID = - PK11_CopyKey(privk->pkcs11Slot,privk->pkcs11ID); - if (copyk->pkcs11ID == CK_INVALID_HANDLE) goto fail; - } else { - copyk->pkcs11ID = privk->pkcs11ID; - } - copyk->pkcs11IsTemp = privk->pkcs11IsTemp; - copyk->wincx = privk->wincx; - return copyk; - } else { - PORT_SetError (SEC_ERROR_NO_MEMORY); - } - -fail: - PORT_FreeArena (arena, PR_FALSE); - return NULL; -} - -SECKEYPublicKey * -SECKEY_CopyPublicKey(SECKEYPublicKey *pubk) -{ - SECKEYPublicKey *copyk; - PRArenaPool *arena; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - copyk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey)); - if (copyk != NULL) { - SECStatus rv = SECSuccess; - - copyk->arena = arena; - copyk->keyType = pubk->keyType; - if (pubk->pkcs11Slot && - PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { - copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot); - copyk->pkcs11ID = pubk->pkcs11ID; - } else { - copyk->pkcs11Slot = NULL; /* go get own reference */ - copyk->pkcs11ID = CK_INVALID_HANDLE; - } - switch (pubk->keyType) { - case rsaKey: - rv = SECITEM_CopyItem(arena, ©k->u.rsa.modulus, - &pubk->u.rsa.modulus); - if (rv == SECSuccess) { - rv = SECITEM_CopyItem (arena, ©k->u.rsa.publicExponent, - &pubk->u.rsa.publicExponent); - if (rv == SECSuccess) - return copyk; - } - break; - case dsaKey: - rv = SECITEM_CopyItem(arena, ©k->u.dsa.publicValue, - &pubk->u.dsa.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.prime, - &pubk->u.dsa.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.subPrime, - &pubk->u.dsa.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.base, - &pubk->u.dsa.params.base); - break; - case keaKey: - rv = SECITEM_CopyItem(arena, ©k->u.kea.publicValue, - &pubk->u.kea.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.kea.params.hash, - &pubk->u.kea.params.hash); - break; - case fortezzaKey: - copyk->u.fortezza.KEAversion = pubk->u.fortezza.KEAversion; - copyk->u.fortezza.DSSversion = pubk->u.fortezza.DSSversion; - PORT_Memcpy(copyk->u.fortezza.KMID, pubk->u.fortezza.KMID, - sizeof(pubk->u.fortezza.KMID)); - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.clearance, - &pubk->u.fortezza.clearance); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEApriviledge, - &pubk->u.fortezza.KEApriviledge); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSpriviledge, - &pubk->u.fortezza.DSSpriviledge); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEAKey, - &pubk->u.fortezza.KEAKey); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSKey, - &pubk->u.fortezza.DSSKey); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.prime, - &pubk->u.fortezza.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.subPrime, - &pubk->u.fortezza.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.base, - &pubk->u.fortezza.params.base); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.prime, - &pubk->u.fortezza.keaParams.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.subPrime, - &pubk->u.fortezza.keaParams.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.base, - &pubk->u.fortezza.keaParams.base); - break; - case dhKey: - rv = SECITEM_CopyItem(arena,©k->u.dh.prime,&pubk->u.dh.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena,©k->u.dh.base,&pubk->u.dh.base); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dh.publicValue, - &pubk->u.dh.publicValue); - break; - case nullKey: - return copyk; - default: - rv = SECFailure; - break; - } - if (rv == SECSuccess) - return copyk; - - SECKEY_DestroyPublicKey (copyk); - } else { - PORT_SetError (SEC_ERROR_NO_MEMORY); - } - - PORT_FreeArena (arena, PR_FALSE); - return NULL; -} - - -SECKEYPublicKey * -SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk) -{ - SECKEYPublicKey *pubk; - PRArenaPool *arena; - CERTCertificate *cert; - SECStatus rv; - - /* - * First try to look up the cert. - */ - cert = PK11_GetCertFromPrivateKey(privk); - if (cert) { - pubk = CERT_ExtractPublicKey(cert); - CERT_DestroyCertificate(cert); - return pubk; - } - - /* couldn't find the cert, build pub key by hand */ - arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - pubk = (SECKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof (SECKEYPublicKey)); - if (pubk == NULL) { - PORT_FreeArena(arena,PR_FALSE); - return NULL; - } - pubk->keyType = privk->keyType; - pubk->pkcs11Slot = NULL; - pubk->pkcs11ID = CK_INVALID_HANDLE; - pubk->arena = arena; - - /* - * fortezza is at the head of this switch, since we don't want to - * allocate an arena... CERT_ExtractPublicKey will to that for us. - */ - switch(privk->keyType) { - case fortezzaKey: - case nullKey: - case dhKey: - case dsaKey: - /* Nothing to query, if the cert isn't there, we're done -- no way - * to get the public key */ - break; - case rsaKey: - rv = PK11_ReadAttribute(privk->pkcs11Slot,privk->pkcs11ID, - CKA_MODULUS,arena,&pubk->u.rsa.modulus); - if (rv != SECSuccess) break; - rv = PK11_ReadAttribute(privk->pkcs11Slot,privk->pkcs11ID, - CKA_PUBLIC_EXPONENT,arena,&pubk->u.rsa.publicExponent); - if (rv != SECSuccess) break; - return pubk; - break; - default: - break; - } - - PORT_FreeArena (arena, PR_FALSE); - return NULL; -} - -CERTSubjectPublicKeyInfo * -SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk) -{ - CERTSubjectPublicKeyInfo *spki; - PRArenaPool *arena; - SECItem params = { siBuffer, NULL, 0 }; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; - } - - spki = (CERTSubjectPublicKeyInfo *) PORT_ArenaZAlloc(arena, sizeof (*spki)); - if (spki != NULL) { - SECStatus rv; - SECItem *rv_item; - - spki->arena = arena; - switch(pubk->keyType) { - case rsaKey: - rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, - SEC_OID_PKCS1_RSA_ENCRYPTION, 0); - if (rv == SECSuccess) { - /* - * DER encode the public key into the subjectPublicKeyInfo. - */ - prepare_rsa_pub_key_for_asn1(pubk); - rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey, - pubk, SECKEY_RSAPublicKeyTemplate); - if (rv_item != NULL) { - /* - * The stored value is supposed to be a BIT_STRING, - * so convert the length. - */ - spki->subjectPublicKey.len <<= 3; - /* - * We got a good one; return it. - */ - return spki; - } - } - break; - case dsaKey: - /* DER encode the params. */ - prepare_pqg_params_for_asn1(&pubk->u.dsa.params); - rv_item = SEC_ASN1EncodeItem(arena, ¶ms, &pubk->u.dsa.params, - SECKEY_PQGParamsTemplate); - if (rv_item != NULL) { - rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, - SEC_OID_ANSIX9_DSA_SIGNATURE, - ¶ms); - if (rv == SECSuccess) { - /* - * DER encode the public key into the subjectPublicKeyInfo. - */ - prepare_dsa_pub_key_for_asn1(pubk); - rv_item = SEC_ASN1EncodeItem(arena, &spki->subjectPublicKey, - pubk, - SECKEY_DSAPublicKeyTemplate); - if (rv_item != NULL) { - /* - * The stored value is supposed to be a BIT_STRING, - * so convert the length. - */ - spki->subjectPublicKey.len <<= 3; - /* - * We got a good one; return it. - */ - return spki; - } - } - } - SECITEM_FreeItem(¶ms, PR_FALSE); - break; - case keaKey: - case dhKey: /* later... */ - - break; - case fortezzaKey: -#ifdef notdef - /* encode the DSS parameters (PQG) */ - rv = FortezzaBuildParams(¶ms,pubk); - if (rv != SECSuccess) break; - - /* set the algorithm */ - rv = SECOID_SetAlgorithmID(arena, &spki->algorithm, - SEC_OID_MISSI_KEA_DSS, ¶ms); - PORT_Free(params.data); - if (rv == SECSuccess) { - /* - * Encode the public key into the subjectPublicKeyInfo. - * Fortezza key material is not standard DER - */ - rv = FortezzaEncodeCertKey(arena,&spki->subjectPublicKey,pubk); - if (rv == SECSuccess) { - /* - * The stored value is supposed to be a BIT_STRING, - * so convert the length. - */ - spki->subjectPublicKey.len <<= 3; - - /* - * We got a good one; return it. - */ - return spki; - } - } -#endif - break; - default: - break; - } - } else { - PORT_SetError(SEC_ERROR_NO_MEMORY); - } - - PORT_FreeArena(arena, PR_FALSE); - return NULL; -} - -void -SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki) -{ - if (spki && spki->arena) { - PORT_FreeArena(spki->arena, PR_FALSE); - } -} - -/* - * this only works for RSA keys... need to do something - * similiar to CERT_ExtractPublicKey for other key times. - */ -SECKEYPublicKey * -SECKEY_DecodeDERPublicKey(SECItem *pubkder) -{ - PRArenaPool *arena; - SECKEYPublicKey *pubk; - SECStatus rv; - - arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey)); - if (pubk != NULL) { - pubk->arena = arena; - pubk->pkcs11Slot = NULL; - pubk->pkcs11ID = 0; - prepare_rsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, - pubkder); - if (rv == SECSuccess) - return pubk; - SECKEY_DestroyPublicKey (pubk); - } else { - PORT_SetError (SEC_ERROR_NO_MEMORY); - } - - PORT_FreeArena (arena, PR_FALSE); - return NULL; -} - -/* - * Decode a base64 ascii encoded DER encoded public key. - */ -SECKEYPublicKey * -SECKEY_ConvertAndDecodePublicKey(char *pubkstr) -{ - SECKEYPublicKey *pubk; - SECStatus rv; - SECItem der; - - rv = ATOB_ConvertAsciiToItem (&der, pubkstr); - if (rv != SECSuccess) - return NULL; - - pubk = SECKEY_DecodeDERPublicKey (&der); - - PORT_Free (der.data); - return pubk; -} - -SECItem * -SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk) -{ - CERTSubjectPublicKeyInfo *spki=NULL; - SECItem *spkiDER=NULL; - - /* get the subjectpublickeyinfo */ - spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); - if( spki == NULL ) { - goto finish; - } - - /* DER-encode the subjectpublickeyinfo */ - spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki, - CERT_SubjectPublicKeyInfoTemplate); -finish: - if (spki!=NULL) { - SECKEY_DestroySubjectPublicKeyInfo(spki); - } - return spkiDER; -} - - -CERTSubjectPublicKeyInfo * -SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider) -{ - PRArenaPool *arena; - CERTSubjectPublicKeyInfo *spki; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return NULL; - } - - spki = (CERTSubjectPublicKeyInfo *) - PORT_ArenaZAlloc(arena, sizeof (CERTSubjectPublicKeyInfo)); - if (spki != NULL) { - spki->arena = arena; - rv = SEC_QuickDERDecodeItem(arena,spki, - CERT_SubjectPublicKeyInfoTemplate,spkider); - if (rv == SECSuccess) - return spki; - SECKEY_DestroySubjectPublicKeyInfo(spki); - } else { - PORT_SetError(SEC_ERROR_NO_MEMORY); - } - - PORT_FreeArena(arena, PR_FALSE); - return NULL; -} - -/* - * Decode a base64 ascii encoded DER encoded subject public key info. - */ -CERTSubjectPublicKeyInfo * -SECKEY_ConvertAndDecodeSubjectPublicKeyInfo(char *spkistr) -{ - CERTSubjectPublicKeyInfo *spki; - SECStatus rv; - SECItem der; - - rv = ATOB_ConvertAsciiToItem(&der, spkistr); - if (rv != SECSuccess) - return NULL; - - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der); - - PORT_Free(der.data); - return spki; -} - -/* - * Decode a base64 ascii encoded DER encoded public key and challenge - * Verify digital signature and make sure challenge matches - */ -CERTSubjectPublicKeyInfo * -SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge, - void *wincx) -{ - CERTSubjectPublicKeyInfo *spki = NULL; - CERTPublicKeyAndChallenge pkac; - SECStatus rv; - SECItem signedItem; - PRArenaPool *arena = NULL; - CERTSignedData sd; - SECItem sig; - SECKEYPublicKey *pubKey = NULL; - unsigned int len; - - signedItem.data = NULL; - - /* convert the base64 encoded data to binary */ - rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr); - if (rv != SECSuccess) { - goto loser; - } - - /* create an arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto loser; - } - - /* decode the outer wrapping of signed data */ - PORT_Memset(&sd, 0, sizeof(CERTSignedData)); - rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem ); - if ( rv ) { - goto loser; - } - - /* decode the public key and challenge wrapper */ - PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge)); - rv = SEC_QuickDERDecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate, - &sd.data); - if ( rv ) { - goto loser; - } - - /* decode the subject public key info */ - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki); - if ( spki == NULL ) { - goto loser; - } - - /* get the public key */ - pubKey = seckey_ExtractPublicKey(spki); - if ( pubKey == NULL ) { - goto loser; - } - - /* check the signature */ - sig = sd.signature; - DER_ConvertBitString(&sig); - rv = VFY_VerifyData(sd.data.data, sd.data.len, pubKey, &sig, - SECOID_GetAlgorithmTag(&(sd.signatureAlgorithm)), wincx); - if ( rv != SECSuccess ) { - goto loser; - } - - /* check the challenge */ - if ( challenge ) { - len = PORT_Strlen(challenge); - /* length is right */ - if ( len != pkac.challenge.len ) { - goto loser; - } - /* actual data is right */ - if ( PORT_Memcmp(challenge, pkac.challenge.data, len) != 0 ) { - goto loser; - } - } - goto done; - -loser: - /* make sure that we return null if we got an error */ - if ( spki ) { - SECKEY_DestroySubjectPublicKeyInfo(spki); - } - spki = NULL; - -done: - if ( signedItem.data ) { - PORT_Free(signedItem.data); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - if ( pubKey ) { - SECKEY_DestroyPublicKey(pubKey); - } - - return spki; -} - -void -SECKEY_DestroyPrivateKeyInfo(SECKEYPrivateKeyInfo *pvk, - PRBool freeit) -{ - PRArenaPool *poolp; - - if(pvk != NULL) { - if(pvk->arena) { - poolp = pvk->arena; - /* zero structure since PORT_FreeArena does not support - * this yet. - */ - PORT_Memset(pvk->privateKey.data, 0, pvk->privateKey.len); - PORT_Memset((char *)pvk, 0, sizeof(*pvk)); - if(freeit == PR_TRUE) { - PORT_FreeArena(poolp, PR_TRUE); - } else { - pvk->arena = poolp; - } - } else { - SECITEM_ZfreeItem(&pvk->version, PR_FALSE); - SECITEM_ZfreeItem(&pvk->privateKey, PR_FALSE); - SECOID_DestroyAlgorithmID(&pvk->algorithm, PR_FALSE); - PORT_Memset((char *)pvk, 0, sizeof(pvk)); - if(freeit == PR_TRUE) { - PORT_Free(pvk); - } - } - } -} - -void -SECKEY_DestroyEncryptedPrivateKeyInfo(SECKEYEncryptedPrivateKeyInfo *epki, - PRBool freeit) -{ - PRArenaPool *poolp; - - if(epki != NULL) { - if(epki->arena) { - poolp = epki->arena; - /* zero structure since PORT_FreeArena does not support - * this yet. - */ - PORT_Memset(epki->encryptedData.data, 0, epki->encryptedData.len); - PORT_Memset((char *)epki, 0, sizeof(*epki)); - if(freeit == PR_TRUE) { - PORT_FreeArena(poolp, PR_TRUE); - } else { - epki->arena = poolp; - } - } else { - SECITEM_ZfreeItem(&epki->encryptedData, PR_FALSE); - SECOID_DestroyAlgorithmID(&epki->algorithm, PR_FALSE); - PORT_Memset((char *)epki, 0, sizeof(epki)); - if(freeit == PR_TRUE) { - PORT_Free(epki); - } - } - } -} - -SECStatus -SECKEY_CopyPrivateKeyInfo(PRArenaPool *poolp, - SECKEYPrivateKeyInfo *to, - SECKEYPrivateKeyInfo *from) -{ - SECStatus rv = SECFailure; - - if((to == NULL) || (from == NULL)) { - return SECFailure; - } - - rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm); - if(rv != SECSuccess) { - return SECFailure; - } - rv = SECITEM_CopyItem(poolp, &to->privateKey, &from->privateKey); - if(rv != SECSuccess) { - return SECFailure; - } - rv = SECITEM_CopyItem(poolp, &to->version, &from->version); - - return rv; -} - -SECStatus -SECKEY_CopyEncryptedPrivateKeyInfo(PRArenaPool *poolp, - SECKEYEncryptedPrivateKeyInfo *to, - SECKEYEncryptedPrivateKeyInfo *from) -{ - SECStatus rv = SECFailure; - - if((to == NULL) || (from == NULL)) { - return SECFailure; - } - - rv = SECOID_CopyAlgorithmID(poolp, &to->algorithm, &from->algorithm); - if(rv != SECSuccess) { - return SECFailure; - } - rv = SECITEM_CopyItem(poolp, &to->encryptedData, &from->encryptedData); - - return rv; -} - -KeyType -SECKEY_GetPrivateKeyType(SECKEYPrivateKey *privKey) -{ - return privKey->keyType; -} - -KeyType -SECKEY_GetPublicKeyType(SECKEYPublicKey *pubKey) -{ - return pubKey->keyType; -} - -SECKEYPublicKey* -SECKEY_ImportDERPublicKey(SECItem *derKey, CK_KEY_TYPE type) -{ - SECKEYPublicKey *pubk = NULL; - SECStatus rv = SECFailure; - - pubk = PORT_ZNew(SECKEYPublicKey); - if(pubk == NULL) { - goto finish; - } - pubk->arena = NULL; - pubk->pkcs11Slot = NULL; - pubk->pkcs11ID = CK_INVALID_HANDLE; - - switch( type ) { - case CKK_RSA: - prepare_rsa_pub_key_for_asn1(pubk); - rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_RSAPublicKeyTemplate,derKey); - pubk->keyType = rsaKey; - break; - case CKK_DSA: - prepare_dsa_pub_key_for_asn1(pubk); - rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_DSAPublicKeyTemplate,derKey); - pubk->keyType = dsaKey; - break; - case CKK_DH: - prepare_dh_pub_key_for_asn1(pubk); - rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_DHPublicKeyTemplate, derKey); - pubk->keyType = dhKey; - break; - default: - rv = SECFailure; - break; - } - -finish: - if( rv != SECSuccess && pubk != NULL) { - PORT_Free(pubk); - pubk = NULL; - } - return pubk; -} - -SECKEYPrivateKeyList* -SECKEY_NewPrivateKeyList(void) -{ - PRArenaPool *arena = NULL; - SECKEYPrivateKeyList *ret = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - ret = (SECKEYPrivateKeyList *)PORT_ArenaZAlloc(arena, - sizeof(SECKEYPrivateKeyList)); - 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 -SECKEY_DestroyPrivateKeyList(SECKEYPrivateKeyList *keys) -{ - while( !PR_CLIST_IS_EMPTY(&keys->list) ) { - SECKEY_RemovePrivateKeyListNode( - (SECKEYPrivateKeyListNode*)(PR_LIST_HEAD(&keys->list)) ); - } - - PORT_FreeArena(keys->arena, PR_FALSE); - - return; -} - - -void -SECKEY_RemovePrivateKeyListNode(SECKEYPrivateKeyListNode *node) -{ - PR_ASSERT(node->key); - SECKEY_DestroyPrivateKey(node->key); - node->key = NULL; - PR_REMOVE_LINK(&node->links); - return; - -} - -SECStatus -SECKEY_AddPrivateKeyToListTail( SECKEYPrivateKeyList *list, - SECKEYPrivateKey *key) -{ - SECKEYPrivateKeyListNode *node; - - node = (SECKEYPrivateKeyListNode *)PORT_ArenaZAlloc(list->arena, - sizeof(SECKEYPrivateKeyListNode)); - if ( node == NULL ) { - goto loser; - } - - PR_INSERT_BEFORE(&node->links, &list->list); - node->key = key; - return(SECSuccess); - -loser: - return(SECFailure); -} - - -SECKEYPublicKeyList* -SECKEY_NewPublicKeyList(void) -{ - PRArenaPool *arena = NULL; - SECKEYPublicKeyList *ret = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - ret = (SECKEYPublicKeyList *)PORT_ArenaZAlloc(arena, - sizeof(SECKEYPublicKeyList)); - 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 -SECKEY_DestroyPublicKeyList(SECKEYPublicKeyList *keys) -{ - while( !PR_CLIST_IS_EMPTY(&keys->list) ) { - SECKEY_RemovePublicKeyListNode( - (SECKEYPublicKeyListNode*)(PR_LIST_HEAD(&keys->list)) ); - } - - PORT_FreeArena(keys->arena, PR_FALSE); - - return; -} - - -void -SECKEY_RemovePublicKeyListNode(SECKEYPublicKeyListNode *node) -{ - PR_ASSERT(node->key); - SECKEY_DestroyPublicKey(node->key); - node->key = NULL; - PR_REMOVE_LINK(&node->links); - return; - -} - -SECStatus -SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list, - SECKEYPublicKey *key) -{ - SECKEYPublicKeyListNode *node; - - node = (SECKEYPublicKeyListNode *)PORT_ArenaZAlloc(list->arena, - sizeof(SECKEYPublicKeyListNode)); - if ( node == NULL ) { - goto loser; - } - - PR_INSERT_BEFORE(&node->links, &list->list); - node->key = key; - return(SECSuccess); - -loser: - return(SECFailure); -} diff --git a/security/nss/lib/cryptohi/secsign.c b/security/nss/lib/cryptohi/secsign.c deleted file mode 100644 index 98131c6eb..000000000 --- a/security/nss/lib/cryptohi/secsign.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Signature stuff. - * - * 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. - * - * $Id$ - */ - -#include <stdio.h> -#include "cryptohi.h" -#include "sechash.h" -#include "secder.h" -#include "keyhi.h" -#include "secoid.h" -#include "secdig.h" -#include "pk11func.h" -#include "secerr.h" - -struct SGNContextStr { - SECOidTag signalg; - SECOidTag hashalg; - void *hashcx; - const SECHashObject *hashobj; - SECKEYPrivateKey *key; -}; - -SGNContext * -SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) -{ - SGNContext *cx; - SECOidTag hashalg, signalg; - KeyType keyType; - - /* OK, map a PKCS #7 hash and encrypt algorithm into - * a standard hashing algorithm. Why did we pass in the whole - * PKCS #7 algTag if we were just going to change here you might - * ask. Well the answer is for some cards we may have to do the - * hashing on card. It may not support CKM_RSA_PKCS sign algorithm, - * it may just support CKM_RSA_PKCS_WITH_SHA1 and/or CKM_RSA_PKCS_WITH_MD5. - */ - switch (alg) { - /* We probably shouldn't be generating MD2 signatures either */ - case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: - hashalg = SEC_OID_MD2; - signalg = SEC_OID_PKCS1_RSA_ENCRYPTION; - keyType = rsaKey; - break; - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - hashalg = SEC_OID_MD5; - signalg = SEC_OID_PKCS1_RSA_ENCRYPTION; - keyType = rsaKey; - break; - case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: - case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: - hashalg = SEC_OID_SHA1; - signalg = SEC_OID_PKCS1_RSA_ENCRYPTION; - keyType = rsaKey; - break; - /* what about normal DSA? */ - case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - hashalg = SEC_OID_SHA1; - signalg = SEC_OID_ANSIX9_DSA_SIGNATURE; - keyType = dsaKey; - break; - case SEC_OID_MISSI_DSS: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_DSS_OLD: - hashalg = SEC_OID_SHA1; - signalg = SEC_OID_MISSI_DSS; /* XXX Is there a better algid? */ - keyType = fortezzaKey; - break; - /* we don't implement MD4 hashes. - * we *CERTAINLY* don't want to sign one! */ - case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return 0; - } - - /* verify our key type */ - if (key->keyType != keyType && - !((key->keyType == dsaKey) && (keyType == fortezzaKey)) && - !((key->keyType == fortezzaKey) && (keyType == dsaKey)) ) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return 0; - } - - cx = (SGNContext*) PORT_ZAlloc(sizeof(SGNContext)); - if (cx) { - cx->hashalg = hashalg; - cx->signalg = signalg; - cx->key = key; - } - return cx; -} - -void -SGN_DestroyContext(SGNContext *cx, PRBool freeit) -{ - if (cx) { - if (cx->hashcx != NULL) { - (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); - cx->hashcx = NULL; - } - if (freeit) { - PORT_ZFree(cx, sizeof(SGNContext)); - } - } -} - -SECStatus -SGN_Begin(SGNContext *cx) -{ - if (cx->hashcx != NULL) { - (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); - cx->hashcx = NULL; - } - - switch (cx->hashalg) { - case SEC_OID_MD2: - cx->hashobj = &SECHashObjects[HASH_AlgMD2]; - break; - case SEC_OID_MD5: - cx->hashobj = &SECHashObjects[HASH_AlgMD5]; - break; - case SEC_OID_SHA1: - cx->hashobj = &SECHashObjects[HASH_AlgSHA1]; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return SECFailure; - } - - cx->hashcx = (*cx->hashobj->create)(); - if (cx->hashcx == NULL) - return SECFailure; - - (*cx->hashobj->begin)(cx->hashcx); - return SECSuccess; -} - -SECStatus -SGN_Update(SGNContext *cx, unsigned char *input, unsigned inputLen) -{ - if (cx->hashcx == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - (*cx->hashobj->update)(cx->hashcx, input, inputLen); - return SECSuccess; -} - -SECStatus -SGN_End(SGNContext *cx, SECItem *result) -{ - unsigned char digest[32]; - unsigned part1, signatureLen; - SECStatus rv; - SECItem digder, sigitem; - PRArenaPool *arena = 0; - SECKEYPrivateKey *privKey = cx->key; - SGNDigestInfo *di = 0; - - - result->data = 0; - digder.data = 0; - - /* Finish up digest function */ - if (cx->hashcx == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - (*cx->hashobj->end)(cx->hashcx, digest, &part1, sizeof(digest)); - - - if (privKey->keyType == rsaKey) { - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( !arena ) { - rv = SECFailure; - goto loser; - } - - /* Construct digest info */ - di = SGN_CreateDigestInfo(cx->hashalg, digest, part1); - if (!di) { - rv = SECFailure; - goto loser; - } - - /* Der encode the digest as a DigestInfo */ - rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di); - if (rv != SECSuccess) { - goto loser; - } - } else { - digder.data = digest; - digder.len = part1; - } - - /* - ** Encrypt signature after constructing appropriate PKCS#1 signature - ** block - */ - signatureLen = PK11_SignatureLen(privKey); - sigitem.len = signatureLen; - sigitem.data = (unsigned char*) PORT_Alloc(signatureLen); - - if (sigitem.data == NULL) { - rv = SECFailure; - goto loser; - } - - rv = PK11_Sign(privKey, &sigitem, &digder); - if (rv != SECSuccess) { - PORT_Free(sigitem.data); - sigitem.data = NULL; - } - - if (cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) { - rv = DSAU_EncodeDerSig(result, &sigitem); - PORT_Free(sigitem.data); - if (rv != SECSuccess) - goto loser; - } else { - result->len = sigitem.len; - result->data = sigitem.data; - } - - loser: - SGN_DestroyDigestInfo(di); - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return rv; -} - -/************************************************************************/ - -/* -** Sign a block of data returning in result a bunch of bytes that are the -** signature. Returns zero on success, an error code on failure. -*/ -SECStatus -SEC_SignData(SECItem *res, unsigned char *buf, int len, - SECKEYPrivateKey *pk, SECOidTag algid) -{ - SECStatus rv; - SGNContext *sgn; - - - sgn = SGN_NewContext(algid, pk); - - if (sgn == NULL) - return SECFailure; - - rv = SGN_Begin(sgn); - if (rv != SECSuccess) - goto loser; - - rv = SGN_Update(sgn, buf, len); - if (rv != SECSuccess) - goto loser; - - rv = SGN_End(sgn, res); - - loser: - SGN_DestroyContext(sgn, PR_TRUE); - return rv; -} - -/* -** Sign the input file's contents returning in result a bunch of bytes -** that are the signature. Returns zero on success, an error code on -** failure. -*/ -SECStatus -SEC_SignFile(SECItem *result, FILE *input, - SECKEYPrivateKey *pk, SECOidTag algid) -{ - unsigned char buf[1024]; - SECStatus rv; - int nb; - SGNContext *sgn; - - sgn = SGN_NewContext(algid, pk); - if (sgn == NULL) - return SECFailure; - rv = SGN_Begin(sgn); - if (rv != SECSuccess) - goto loser; - - /* - ** Now feed the contents of the input file into the digest - ** algorithm, one chunk at a time, until we have exhausted the - ** input - */ - for (;;) { - if (feof(input)) break; - nb = fread(buf, 1, sizeof(buf), input); - if (nb == 0) { - if (ferror(input)) { - PORT_SetError(SEC_ERROR_IO); - rv = SECFailure; - goto loser; - } - break; - } - rv = SGN_Update(sgn, buf, nb); - if (rv != SECSuccess) - goto loser; - } - - /* Sign the digest */ - rv = SGN_End(sgn, result); - /* FALL THROUGH */ - - loser: - SGN_DestroyContext(sgn, PR_TRUE); - return rv; -} - -/************************************************************************/ - -DERTemplate CERTSignedDataTemplate[] = -{ - { DER_SEQUENCE, - 0, NULL, sizeof(CERTSignedData) }, - { DER_ANY, - offsetof(CERTSignedData,data), }, - { DER_INLINE, - offsetof(CERTSignedData,signatureAlgorithm), - SECAlgorithmIDTemplate, }, - { DER_BIT_STRING, - offsetof(CERTSignedData,signature), }, - { 0, } -}; - -const SEC_ASN1Template CERT_SignedDataTemplate[] = -{ - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTSignedData) }, - { SEC_ASN1_ANY, - offsetof(CERTSignedData,data), }, - { SEC_ASN1_INLINE, - offsetof(CERTSignedData,signatureAlgorithm), - SECOID_AlgorithmIDTemplate, }, - { SEC_ASN1_BIT_STRING, - offsetof(CERTSignedData,signature), }, - { 0, } -}; - -SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedDataTemplate) - - -SECStatus -SEC_DerSignData(PRArenaPool *arena, SECItem *result, - unsigned char *buf, int len, SECKEYPrivateKey *pk, SECOidTag algID) -{ - SECItem it; - CERTSignedData sd; - SECStatus rv; - - it.data = 0; - - /* XXX We should probably have some asserts here to make sure the key type - * and algID match - */ - - if (algID == SEC_OID_UNKNOWN) { - switch(pk->keyType) { - case rsaKey: - algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; - break; - case dsaKey: - algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; - break; - default: - return SECFailure; - break; - } - } - - /* Sign input buffer */ - rv = SEC_SignData(&it, buf, len, pk, algID); - if (rv) goto loser; - - /* Fill out SignedData object */ - PORT_Memset(&sd, 0, sizeof(sd)); - sd.data.data = buf; - sd.data.len = len; - sd.signature.data = it.data; - sd.signature.len = it.len << 3; /* convert to bit string */ - rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0); - if (rv) goto loser; - - /* DER encode the signed data object */ - rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd); - /* FALL THROUGH */ - - loser: - PORT_Free(it.data); - return rv; -} - -SECStatus -SGN_Digest(SECKEYPrivateKey *privKey, - SECOidTag algtag, SECItem *result, SECItem *digest) -{ - unsigned modulusLen; - SECStatus rv; - SECItem digder; - PRArenaPool *arena = 0; - SGNDigestInfo *di = 0; - - - result->data = 0; - - if (privKey->keyType == rsaKey) { - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( !arena ) { - rv = SECFailure; - goto loser; - } - - /* Construct digest info */ - di = SGN_CreateDigestInfo(algtag, digest->data, digest->len); - if (!di) { - rv = SECFailure; - goto loser; - } - - /* Der encode the digest as a DigestInfo */ - rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di); - if (rv != SECSuccess) { - goto loser; - } - } else { - digder.data = digest->data; - digder.len = digest->len; - } - - /* - ** Encrypt signature after constructing appropriate PKCS#1 signature - ** block - */ - modulusLen = PK11_SignatureLen(privKey); - result->len = modulusLen; - result->data = (unsigned char*) PORT_Alloc(modulusLen); - - if (result->data == NULL) { - rv = SECFailure; - goto loser; - } - - rv = PK11_Sign(privKey, result, &digder); - if (rv != SECSuccess) { - PORT_Free(result->data); - result->data = NULL; - } - - loser: - SGN_DestroyDigestInfo(di); - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return rv; -} diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c deleted file mode 100644 index bf63dd070..000000000 --- a/security/nss/lib/cryptohi/secvfy.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Verification stuff. - * - * 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. - * - * $Id$ - */ - -#include <stdio.h> -#include "cryptohi.h" -#include "sechash.h" -#include "keyhi.h" -#include "secasn1.h" -#include "secoid.h" -#include "pk11func.h" -#include "secdig.h" -#include "secerr.h" - -/* -** Decrypt signature block using public key (in place) -** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION -*/ -static SECStatus -DecryptSigBlock(int *tagp, unsigned char *digest, SECKEYPublicKey *key, - SECItem *sig, char *wincx) -{ - SGNDigestInfo *di = NULL; - unsigned char *dsig = NULL; - unsigned char *buf = NULL; - SECStatus rv; - SECOidTag tag; - SECItem it; - - if (key == NULL) goto loser; - - it.len = SECKEY_PublicKeyStrength(key); - if (!it.len) goto loser; - it.data = buf = (unsigned char *)PORT_Alloc(it.len); - if (!buf) goto loser; - - /* Decrypt signature block */ - dsig = (unsigned char*) PORT_Alloc(sig->len); - if (dsig == NULL) goto loser; - - /* decrypt the block */ - rv = PK11_VerifyRecover(key, sig, &it, wincx); - if (rv != SECSuccess) goto loser; - - di = SGN_DecodeDigestInfo(&it); - if (di == NULL) goto sigloser; - - /* - ** Finally we have the digest info; now we can extract the algorithm - ** ID and the signature block - */ - tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm); - /* XXX Check that tag is an appropriate algorithm? */ - if (di->digest.len > 32) { - PORT_SetError(SEC_ERROR_OUTPUT_LEN); - goto loser; - } - PORT_Memcpy(digest, di->digest.data, di->digest.len); - *tagp = tag; - goto done; - - sigloser: - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - - loser: - rv = SECFailure; - - done: - if (di != NULL) SGN_DestroyDigestInfo(di); - if (dsig != NULL) PORT_Free(dsig); - if (buf != NULL) PORT_Free(buf); - - return rv; -} - -typedef enum { VFY_RSA, VFY_DSA} VerifyType; - -struct VFYContextStr { - SECOidTag alg; - VerifyType type; - SECKEYPublicKey *key; - /* digest holds the full dsa signature... 40 bytes */ - unsigned char digest[DSA_SIGNATURE_LEN]; - void * wincx; - void *hashcx; - const SECHashObject *hashobj; - SECOidTag sigAlg; - PRBool hasSignature; -}; - -/* - * decode the DSA signature from it's DER wrapping. - */ -static SECStatus -decodeDSASignature(SECOidTag algid, SECItem *sig, unsigned char *digest) { - SECItem *dsasig = NULL; - SECStatus rv=SECSuccess; - - /* if this is a DER encoded signature, decode it first */ - if ((algid == SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) || - (algid == SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) || - (algid == SEC_OID_ANSIX9_DSA_SIGNATURE)) { - dsasig = DSAU_DecodeDerSig(sig); - if ((dsasig == NULL) || (dsasig->len != DSA_SIGNATURE_LEN)) { - rv = SECFailure; - goto loser; - } - PORT_Memcpy(digest, dsasig->data, dsasig->len); - } else { - if (sig->len != DSA_SIGNATURE_LEN) { - rv = SECFailure; - goto loser; - } - PORT_Memcpy(digest, sig->data, sig->len); - } - -loser: - if (dsasig != NULL) - SECITEM_FreeItem(dsasig, PR_TRUE); - return rv; - -} -/* - * Pulls the hash algorithm, signing algorithm, and key type out of a - * composite algorithm. - * - * alg: the composite algorithm to dissect. - * hashalg: address of a SECOidTag which will be set with the hash algorithm. - * signalg: address of a SECOidTag which will be set with the signing alg. - * keyType: address of a KeyType which will be set with the key type. - * Returns: SECSuccess if the algorithm was acceptable, SECFailure if the - * algorithm was not found or was not a signing algorithm. - */ -static SECStatus -decodeSigAlg(SECOidTag alg, SECOidTag *hashalg) -{ - PR_ASSERT(hashalg!=NULL); - - switch (alg) { - /* We probably shouldn't be generating MD2 signatures either */ - case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: - *hashalg = SEC_OID_MD2; - return SECSuccess; - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - *hashalg = SEC_OID_MD5; - return SECSuccess; - case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: - case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE: - *hashalg = SEC_OID_SHA1; - return SECSuccess; - /* what about normal DSA? */ - case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - *hashalg = SEC_OID_SHA1; - return SECSuccess; - case SEC_OID_MISSI_DSS: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_DSS_OLD: - *hashalg = SEC_OID_SHA1; - return SECSuccess; - /* we don't implement MD4 hashes */ - case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: - default: - break; - } - return SECFailure; -} - -VFYContext * -VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, - void *wincx) -{ - VFYContext *cx; - SECStatus rv; - - cx = (VFYContext*) PORT_ZAlloc(sizeof(VFYContext)); - if (cx) { - cx->wincx = wincx; - cx->hasSignature = (sig != NULL); - cx->sigAlg = algid; - rv = SECSuccess; - switch (key->keyType) { - case rsaKey: - cx->type = VFY_RSA; - cx->key = SECKEY_CopyPublicKey(key); /* extra safety precautions */ - if (sig) { - int hashid; - rv = DecryptSigBlock(&hashid, &cx->digest[0], - key, sig, (char*)wincx); - cx->alg = hashid; - } else { - rv = decodeSigAlg(algid,&cx->alg); - } - break; - case fortezzaKey: - case dsaKey: - cx->type = VFY_DSA; - cx->alg = SEC_OID_SHA1; - cx->key = SECKEY_CopyPublicKey(key); - if (sig) { - rv = decodeDSASignature(algid,sig,&cx->digest[0]); - } - break; - default: - rv = SECFailure; - break; - } - if (rv) goto loser; - switch (cx->alg) { - case SEC_OID_MD2: - case SEC_OID_MD5: - case SEC_OID_SHA1: - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - goto loser; - } - } - return cx; - - loser: - VFY_DestroyContext(cx, PR_TRUE); - return 0; -} - -void -VFY_DestroyContext(VFYContext *cx, PRBool freeit) -{ - if (cx) { - if (cx->hashcx != NULL) { - (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); - cx->hashcx = NULL; - } - if (cx->key) { - SECKEY_DestroyPublicKey(cx->key); - } - if (freeit) { - PORT_ZFree(cx, sizeof(VFYContext)); - } - } -} - -SECStatus -VFY_Begin(VFYContext *cx) -{ - if (cx->hashcx != NULL) { - (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE); - cx->hashcx = NULL; - } - - switch (cx->alg) { - case SEC_OID_MD2: - cx->hashobj = &SECHashObjects[HASH_AlgMD2]; - break; - case SEC_OID_MD5: - cx->hashobj = &SECHashObjects[HASH_AlgMD5]; - break; - case SEC_OID_SHA1: - cx->hashobj = &SECHashObjects[HASH_AlgSHA1]; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return SECFailure; - } - - cx->hashcx = (*cx->hashobj->create)(); - if (cx->hashcx == NULL) - return SECFailure; - - (*cx->hashobj->begin)(cx->hashcx); - return SECSuccess; -} - -SECStatus -VFY_Update(VFYContext *cx, unsigned char *input, unsigned inputLen) -{ - if (cx->hashcx == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - (*cx->hashobj->update)(cx->hashcx, input, inputLen); - return SECSuccess; -} - -SECStatus -VFY_EndWithSignature(VFYContext *cx, SECItem *sig) -{ - unsigned char final[32]; - unsigned part; - SECItem hash,dsasig; - SECStatus rv; - - if ((cx->hasSignature == PR_FALSE) && (sig == NULL)) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - - if (cx->hashcx == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - (*cx->hashobj->end)(cx->hashcx, final, &part, sizeof(final)); - switch (cx->type) { - case VFY_DSA: - if (sig) { - rv = decodeDSASignature(cx->sigAlg,sig,&cx->digest[0]); - if (rv != SECSuccess) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - return SECFailure; - } - } - dsasig.data = cx->digest; - dsasig.len = DSA_SIGNATURE_LEN; /* magic size of dsa signature */ - hash.data = final; - hash.len = part; - if (PK11_Verify(cx->key,&dsasig,&hash,cx->wincx) != SECSuccess) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - return SECFailure; - } - break; - case VFY_RSA: - if (sig) { - int hashid; - rv = DecryptSigBlock(&hashid, &cx->digest[0], - cx->key, sig, (char*)cx->wincx); - if ((rv != SECSuccess) || (hashid != cx->alg)) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - return SECFailure; - } - } - if (PORT_Memcmp(final, cx->digest, part)) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - return SECFailure; - } - break; - default: - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - return SECFailure; /* shouldn't happen */ - } - return SECSuccess; -} - -SECStatus -VFY_End(VFYContext *cx) -{ - return VFY_EndWithSignature(cx,NULL); -} - -/************************************************************************/ -/* - * Verify that a previously-computed digest matches a signature. - * XXX This should take a parameter that specifies the digest algorithm, - * and we should compare that the algorithm found in the DigestInfo - * matches it! - */ -SECStatus -VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, - SECOidTag algid, void *wincx) -{ - SECStatus rv; - VFYContext *cx; - SECItem dsasig; - - rv = SECFailure; - - cx = VFY_CreateContext(key, sig, algid, wincx); - if (cx != NULL) { - switch (key->keyType) { - case rsaKey: - if (PORT_Memcmp(digest->data, cx->digest, digest->len)) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - } else { - rv = SECSuccess; - } - break; - case fortezzaKey: - case dsaKey: - dsasig.data = &cx->digest[0]; - dsasig.len = DSA_SIGNATURE_LEN; /* magic size of dsa signature */ - if (PK11_Verify(cx->key, &dsasig, digest, cx->wincx) != SECSuccess) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - } else { - rv = SECSuccess; - } - break; - default: - break; - } - VFY_DestroyContext(cx, PR_TRUE); - } - return rv; -} - -SECStatus -VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, - SECItem *sig, SECOidTag algid, void *wincx) -{ - SECStatus rv; - VFYContext *cx; - - cx = VFY_CreateContext(key, sig, algid, wincx); - if (cx == NULL) - return SECFailure; - - rv = VFY_Begin(cx); - if (rv == SECSuccess) { - rv = VFY_Update(cx, buf, len); - if (rv == SECSuccess) - rv = VFY_End(cx); - } - - VFY_DestroyContext(cx, PR_TRUE); - return rv; -} - -SECStatus -SEC_VerifyFile(FILE *input, SECKEYPublicKey *key, SECItem *sig, - SECOidTag algid, void *wincx) -{ - unsigned char buf[1024]; - SECStatus rv; - int nb; - VFYContext *cx; - - cx = VFY_CreateContext(key, sig, algid, wincx); - if (cx == NULL) - rv = SECFailure; - - rv = VFY_Begin(cx); - if (rv == SECSuccess) { - /* - * Now feed the contents of the input file into the digest algorithm, - * one chunk at a time, until we have exhausted the input. - */ - for (;;) { - if (feof(input)) - break; - nb = fread(buf, 1, sizeof(buf), input); - if (nb == 0) { - if (ferror(input)) { - PORT_SetError(SEC_ERROR_IO); - VFY_DestroyContext(cx, PR_TRUE); - return SECFailure; - } - break; - } - rv = VFY_Update(cx, buf, nb); - if (rv != SECSuccess) - goto loser; - } - } - - /* Verify the digest */ - rv = VFY_End(cx); - /* FALL THROUGH */ - - loser: - VFY_DestroyContext(cx, PR_TRUE); - return rv; -} diff --git a/security/nss/lib/dev/Makefile b/security/nss/lib/dev/Makefile index aa883e01a..4dcea50f9 100644 --- a/security/nss/lib/dev/Makefile +++ b/security/nss/lib/dev/Makefile @@ -52,9 +52,5 @@ endif #export:: private_export -export:: copy_files private_export - -# XXX hack to share module debug file for now -copy_files:: - $(INSTALL) -m 444 ../pk11wrap/debug_module.c ./ +export:: private_export diff --git a/security/nss/lib/pk11wrap/debug_module.c b/security/nss/lib/dev/debug_module.c index 34de3bf65..34de3bf65 100644 --- a/security/nss/lib/pk11wrap/debug_module.c +++ b/security/nss/lib/dev/debug_module.c diff --git a/security/nss/lib/manifest.mn b/security/nss/lib/manifest.mn index 49d8725b1..0cf1bf678 100644 --- a/security/nss/lib/manifest.mn +++ b/security/nss/lib/manifest.mn @@ -38,14 +38,11 @@ BASE_DIRS = \ base \ $(NULL) -# softoken seems to depend on just about everything in old NSS +# softoken continues to depend on util SOFTOKEN_DIRS = \ util \ freebl \ - cryptohi \ - pk11wrap \ softoken \ - certdb \ $(NULL) # core stan libraries diff --git a/security/nss/lib/pk11wrap/Makefile b/security/nss/lib/pk11wrap/Makefile deleted file mode 100644 index a84456e7d..000000000 --- a/security/nss/lib/pk11wrap/Makefile +++ /dev/null @@ -1,88 +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 - -# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile -# pk11slot.c in 64-bit mode for unknown reasons. A workaround is -# to compile it with optimizations turned on. (Bugzilla bug #63815) -ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3) -ifeq ($(USE_64),1) -ifndef BUILD_OPT -$(OBJDIR)/pk11slot.o: pk11slot.c - @$(MAKE_OBJDIR) - $(CC) -o $@ -c -O2 $(CFLAGS) $< -endif -endif -endif diff --git a/security/nss/lib/pk11wrap/config.mk b/security/nss/lib/pk11wrap/config.mk deleted file mode 100644 index 0a00dc61e..000000000 --- a/security/nss/lib/pk11wrap/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/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c deleted file mode 100644 index 3f704436d..000000000 --- a/security/nss/lib/pk11wrap/dev3hack.c +++ /dev/null @@ -1,294 +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. - */ - -#ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; -#endif /* DEBUG */ - -#ifndef NSS_3_4_CODE -#define NSS_3_4_CODE -#endif /* NSS_3_4_CODE */ - -#ifndef PKIT_H -#include "pkit.h" -#endif /* PKIT_H */ - -#ifndef DEVM_H -#include "devm.h" -#endif /* DEVM_H */ - -#include "pki3hack.h" -#include "dev3hack.h" -#include "pkim.h" - -#ifndef BASE_H -#include "base.h" -#endif /* BASE_H */ - -#include "pk11func.h" -#include "secmodti.h" - -NSS_IMPLEMENT nssSession * -nssSession_ImportNSS3Session(NSSArena *arenaOpt, - CK_SESSION_HANDLE session, - PZLock *lock, PRBool rw) -{ - nssSession *rvSession; - rvSession = nss_ZNEW(arenaOpt, nssSession); - rvSession->handle = session; - rvSession->lock = lock; - rvSession->isRW = rw; - return rvSession; -} - -NSS_IMPLEMENT nssSession * -nssSlot_CreateSession -( - NSSSlot *slot, - NSSArena *arenaOpt, - PRBool readWrite -) -{ - nssSession *rvSession; - rvSession = nss_ZNEW(arenaOpt, nssSession); - if (!rvSession) { - return (nssSession *)NULL; - } - if (readWrite) { - rvSession->handle = PK11_GetRWSession(slot->pk11slot); - if (rvSession->handle == CK_INVALID_HANDLE) { - nss_ZFreeIf(rvSession); - return NULL; - } - rvSession->isRW = PR_TRUE; - rvSession->slot = slot; - return rvSession; - } else { - return NULL; - } -} - -NSS_IMPLEMENT PRStatus -nssSession_Destroy -( - nssSession *s -) -{ - CK_RV ckrv = CKR_OK; - if (s) { - if (s->isRW) { - PK11_RestoreROSession(s->slot->pk11slot, s->handle); - } - nss_ZFreeIf(s); - } - return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE; -} - -static NSSSlot * -nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) -{ - NSSSlot *rvSlot; - NSSArena *arena; - arena = nssArena_Create(); - if (!arena) { - return NULL; - } - rvSlot = nss_ZNEW(arena, NSSSlot); - if (!rvSlot) { - nssArena_Destroy(arena); - return NULL; - } - rvSlot->base.refCount = 1; - rvSlot->base.lock = PZ_NewLock(nssILockOther); - rvSlot->base.arena = arena; - rvSlot->pk11slot = nss3slot; - rvSlot->epv = nss3slot->functionList; - rvSlot->slotID = nss3slot->slotID; - /* Grab the slot name from the PKCS#11 fixed-length buffer */ - rvSlot->base.name = nssUTF8_Duplicate(nss3slot->slot_name,td->arena); - return rvSlot; -} - -NSS_IMPLEMENT NSSToken * -nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) -{ - NSSToken *rvToken; - NSSArena *arena; - arena = nssArena_Create(); - if (!arena) { - return NULL; - } - rvToken = nss_ZNEW(arena, NSSToken); - if (!rvToken) { - nssArena_Destroy(arena); - return NULL; - } - rvToken->base.refCount = 1; - rvToken->base.lock = PZ_NewLock(nssILockOther); - rvToken->base.arena = arena; - rvToken->pk11slot = nss3slot; - rvToken->epv = nss3slot->functionList; - rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena, - nss3slot->session, - nss3slot->sessionLock, - nss3slot->defRWSession); - /* The above test was used in 3.4, for this cache have it always on */ - if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) { - rvToken->cache = nssTokenObjectCache_Create(rvToken, - PR_TRUE, PR_TRUE, PR_TRUE); - if (!rvToken->cache) { - nssArena_Destroy(arena); - return (NSSToken *)NULL; - } - } - rvToken->trustDomain = td; - /* Grab the token name from the PKCS#11 fixed-length buffer */ - rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena); - rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot); - rvToken->slot->token = rvToken; - rvToken->defaultSession->slot = rvToken->slot; - return rvToken; -} - -NSS_IMPLEMENT void -nssToken_UpdateName(NSSToken *token) -{ - if (!token) { - return; - } - token->base.name = nssUTF8_Duplicate(token->pk11slot->token_name,token->base.arena); -} - -NSS_IMPLEMENT PRBool -nssSlot_IsPermanent -( - NSSSlot *slot -) -{ - return slot->pk11slot->isPerm; -} - -NSS_IMPLEMENT PRBool -nssSlot_IsFriendly -( - NSSSlot *slot -) -{ - return PK11_IsFriendly(slot->pk11slot); -} - -NSS_IMPLEMENT PRStatus -nssToken_Refresh(NSSToken *token) -{ - PK11SlotInfo *nss3slot; - - if (!token) { - return PR_SUCCESS; - } - nss3slot = token->pk11slot; - token->defaultSession = nssSession_ImportNSS3Session(token->slot->base.arena, - nss3slot->session, - nss3slot->sessionLock, - nss3slot->defRWSession); - return PR_SUCCESS; -} - -NSS_IMPLEMENT PRStatus -nssSlot_Refresh -( - NSSSlot *slot -) -{ - PK11SlotInfo *nss3slot = slot->pk11slot; - PRBool doit = PR_FALSE; - if (slot->token->base.name[0] == 0) { - doit = PR_TRUE; - } - if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) { - return PR_FAILURE; - } - if (doit) { - nssTrustDomain_UpdateCachedTokenCerts(slot->token->trustDomain, - slot->token); - } - return nssToken_Refresh(slot->token); -} - -NSS_IMPLEMENT PRStatus -nssToken_GetTrustOrder -( - NSSToken *tok -) -{ - PK11SlotInfo *slot; - SECMODModule *module; - slot = tok->pk11slot; - module = PK11_GetModule(slot); - return module->trustOrder; -} - -NSS_IMPLEMENT PRBool -nssSlot_IsLoggedIn -( - NSSSlot *slot -) -{ - if (!slot->pk11slot->needLogin) { - return PR_TRUE; - } - return PK11_IsLoggedIn(slot->pk11slot, NULL); -} - - -NSSTrustDomain * -nssToken_GetTrustDomain(NSSToken *token) -{ - return token->trustDomain; -} - -NSS_EXTERN PRStatus -nssTrustDomain_RemoveTokenCertsFromCache -( - NSSTrustDomain *td, - NSSToken *token -); - -NSS_IMPLEMENT PRStatus -nssToken_NotifyCertsNotVisible -( - NSSToken *tok -) -{ - return nssTrustDomain_RemoveTokenCertsFromCache(tok->trustDomain, tok); -} - diff --git a/security/nss/lib/pk11wrap/dev3hack.h b/security/nss/lib/pk11wrap/dev3hack.h deleted file mode 100644 index d2e3ab4e1..000000000 --- a/security/nss/lib/pk11wrap/dev3hack.h +++ /dev/null @@ -1,63 +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 DEVNSS3HACK_H -#define DEVNSS3HACK_H - -#ifdef DEBUG -static const char DEVNSS3HACK_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; -#endif /* DEBUG */ - -#include "cert.h" - -PR_BEGIN_EXTERN_C - -NSS_EXTERN NSSToken * -nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot); - -NSS_EXTERN void -nssToken_UpdateName(NSSToken *); - -NSS_EXTERN PRStatus -nssToken_Refresh(NSSToken *); - -NSSTrustDomain * -nssToken_GetTrustDomain(NSSToken *token); - -void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst); - -NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl); - -PR_END_EXTERN_C - -#endif /* DEVNSS3HACK_H */ diff --git a/security/nss/lib/pk11wrap/manifest.mn b/security/nss/lib/pk11wrap/manifest.mn deleted file mode 100644 index 7a6e5c734..000000000 --- a/security/nss/lib/pk11wrap/manifest.mn +++ /dev/null @@ -1,78 +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 = \ - secmod.h \ - secmodt.h \ - secpkcs5.h \ - pk11func.h \ - pk11sdr.h \ - pk11pqg.h \ - $(NULL) - -PRIVATE_EXPORTS = \ - pk11init.h \ - dev3hack.h \ - $(NULL) - -MODULE = softoken - -CSRCS = $(NULL) - -NO_CSRCS = \ - dev3hack.c \ - pk11cert.c \ - pk11err.c \ - pk11load.c \ - pk11pars.c \ - pk11slot.c \ - pk11list.c \ - pk11skey.c \ - pk11kea.c \ - pk11util.c \ - pk11sdr.c \ - pk11pqg.c \ - pk11pk12.c \ - pk11pbe.c \ - $(NULL) - -REQUIRES = security dbm - -#LIBRARY_NAME = pk11wrap - -# only add module debugging in opt builds if DEBUG_PKCS11 is set -ifdef DEBUG_PKCS11 - DEFINES += -DDEBUG_MODULE -endif - diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c deleted file mode 100644 index e768dc9b4..000000000 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ /dev/null @@ -1,4078 +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. - */ -/* - * This file implements the Symkey wrapper and the PKCS context - * Interfaces. - */ -#include "seccomon.h" -#include "secmod.h" -#include "nssilock.h" -#include "secmodi.h" -#include "pkcs11.h" -#include "pk11func.h" -#include "cert.h" -#include "secitem.h" -#include "key.h" -#include "hasht.h" -#include "secoid.h" -#include "pkcs7t.h" -#include "cmsreclist.h" - -#include "certdb.h" -#include "secerr.h" -#include "sslerr.h" - -#ifndef NSS_3_4_CODE -#define NSS_3_4_CODE -#endif /* NSS_3_4_CODE */ -#include "pki3hack.h" -#include "dev3hack.h" - -#include "devm.h" -#include "nsspki.h" -#include "pki.h" -#include "pkim.h" -#include "pkitm.h" -#include "pkistore.h" /* to remove temp cert */ -#include "devt.h" - -#define PK11_SEARCH_CHUNKSIZE 10 - -CK_OBJECT_HANDLE -pk11_FindPubKeyByAnyCert(CERTCertificate *cert, PK11SlotInfo **slot, void *wincx); - -struct nss3_cert_cbstr { - SECStatus(* callback)(CERTCertificate*, void *); - nssList *cached; - void *arg; -}; - -/* Translate from NSSCertificate to CERTCertificate, then pass the latter - * to a callback. - */ -static PRStatus convert_cert(NSSCertificate *c, void *arg) -{ - CERTCertificate *nss3cert; - SECStatus secrv; - struct nss3_cert_cbstr *nss3cb = (struct nss3_cert_cbstr *)arg; - nss3cert = STAN_GetCERTCertificate(c); - if (!nss3cert) return PR_FAILURE; - secrv = (*nss3cb->callback)(nss3cert, nss3cb->arg); - return (secrv) ? PR_FAILURE : PR_SUCCESS; -} - -void -PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst) -{ - sl->nssToken = nsst; -} - -NSSToken * -PK11Slot_GetNSSToken(PK11SlotInfo *sl) -{ - return sl->nssToken; -} - -/* - * build a cert nickname based on the token name and the label of the - * certificate If the label in NULL, build a label based on the ID. - */ -static int toHex(int x) { return (x < 10) ? (x+'0') : (x+'a'-10); } -#define MAX_CERT_ID 4 -#define DEFAULT_STRING "Cert ID " -static char * -pk11_buildNickname(PK11SlotInfo *slot,CK_ATTRIBUTE *cert_label, - CK_ATTRIBUTE *key_label, CK_ATTRIBUTE *cert_id) -{ - int prefixLen = PORT_Strlen(slot->token_name); - int suffixLen = 0; - char *suffix = NULL; - char buildNew[sizeof(DEFAULT_STRING)+MAX_CERT_ID*2]; - char *next,*nickname; - - if (cert_label && (cert_label->ulValueLen)) { - suffixLen = cert_label->ulValueLen; - suffix = (char*)cert_label->pValue; - } else if (key_label && (key_label->ulValueLen)) { - suffixLen = key_label->ulValueLen; - suffix = (char*)key_label->pValue; - } else if (cert_id && cert_id->ulValueLen > 0) { - int i,first = cert_id->ulValueLen - MAX_CERT_ID; - int offset = sizeof(DEFAULT_STRING); - char *idValue = (char *)cert_id->pValue; - - PORT_Memcpy(buildNew,DEFAULT_STRING,sizeof(DEFAULT_STRING)-1); - next = buildNew + offset; - if (first < 0) first = 0; - for (i=first; i < (int) cert_id->ulValueLen; i++) { - *next++ = toHex((idValue[i] >> 4) & 0xf); - *next++ = toHex(idValue[i] & 0xf); - } - *next++ = 0; - suffix = buildNew; - suffixLen = PORT_Strlen(buildNew); - } else { - PORT_SetError( SEC_ERROR_LIBRARY_FAILURE ); - return NULL; - } - - /* if is internal key slot, add code to skip the prefix!! */ - next = nickname = (char *)PORT_Alloc(prefixLen+1+suffixLen+1); - if (nickname == NULL) return NULL; - - PORT_Memcpy(next,slot->token_name,prefixLen); - next += prefixLen; - *next++ = ':'; - PORT_Memcpy(next,suffix,suffixLen); - next += suffixLen; - *next++ = 0; - return nickname; -} - -/* - * return the object handle that matches the template - */ -CK_OBJECT_HANDLE -pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize) -{ - CK_OBJECT_HANDLE object; - CK_RV crv; - CK_ULONG objectCount; - - /* - * issue the find - */ - PK11_EnterSlotMonitor(slot); - crv=PK11_GETTAB(slot)->C_FindObjectsInit(slot->session, theTemplate, tsize); - if (crv != CKR_OK) { - PK11_ExitSlotMonitor(slot); - PORT_SetError( PK11_MapError(crv) ); - return CK_INVALID_HANDLE; - } - - crv=PK11_GETTAB(slot)->C_FindObjects(slot->session,&object,1,&objectCount); - PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); - PK11_ExitSlotMonitor(slot); - if ((crv != CKR_OK) || (objectCount < 1)) { - /* shouldn't use SSL_ERROR... here */ - PORT_SetError( crv != CKR_OK ? PK11_MapError(crv) : - SSL_ERROR_NO_CERTIFICATE); - return CK_INVALID_HANDLE; - } - - /* blow up if the PKCS #11 module returns us and invalid object handle */ - PORT_Assert(object != CK_INVALID_HANDLE); - return object; -} - -/* - * return all the object handles that matches the template - */ -CK_OBJECT_HANDLE * -pk11_FindObjectsByTemplate(PK11SlotInfo *slot, - CK_ATTRIBUTE *findTemplate,int findCount,int *object_count) { - CK_OBJECT_HANDLE *objID = NULL; - CK_ULONG returned_count = 0; - CK_RV crv; - - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session, findTemplate, - findCount); - if (crv != CKR_OK) { - PK11_ExitSlotMonitor(slot); - PORT_SetError( PK11_MapError(crv) ); - *object_count = -1; - return NULL; - } - - - /* - * collect all the Matching Objects - */ - do { - CK_OBJECT_HANDLE *oldObjID = objID; - - if (objID == NULL) { - objID = (CK_OBJECT_HANDLE *) PORT_Alloc(sizeof(CK_OBJECT_HANDLE)* - (*object_count+ PK11_SEARCH_CHUNKSIZE)); - } else { - objID = (CK_OBJECT_HANDLE *) PORT_Realloc(objID, - sizeof(CK_OBJECT_HANDLE)*(*object_count+PK11_SEARCH_CHUNKSIZE)); - } - - if (objID == NULL) { - if (oldObjID) PORT_Free(oldObjID); - break; - } - crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, - &objID[*object_count],PK11_SEARCH_CHUNKSIZE,&returned_count); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - PORT_Free(objID); - objID = NULL; - break; - } - *object_count += returned_count; - } while (returned_count == PK11_SEARCH_CHUNKSIZE); - - PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); - PK11_ExitSlotMonitor(slot); - - if (objID && (*object_count == 0)) { - PORT_Free(objID); - return NULL; - } - if (objID == NULL) *object_count = -1; - return objID; -} -/* - * given a PKCS #11 object, match it's peer based on the KeyID. searchID - * is typically a privateKey or a certificate while the peer is the opposite - */ -CK_OBJECT_HANDLE -PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID, - CK_OBJECT_CLASS matchclass) -{ - CK_ATTRIBUTE theTemplate[] = { - { CKA_ID, NULL, 0 }, - { CKA_CLASS, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - CK_ATTRIBUTE *keyclass = &theTemplate[1]; - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - /* if you change the array, change the variable below as well */ - CK_OBJECT_HANDLE peerID; - CK_OBJECT_HANDLE parent; - PRArenaPool *arena; - CK_RV crv; - - /* now we need to create space for the public key */ - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) return CK_INVALID_HANDLE; - - crv = PK11_GetAttributes(arena,slot,searchID,theTemplate,tsize); - if (crv != CKR_OK) { - PORT_FreeArena(arena,PR_FALSE); - PORT_SetError( PK11_MapError(crv) ); - return CK_INVALID_HANDLE; - } - - if ((theTemplate[0].ulValueLen == 0) || (theTemplate[0].ulValueLen == -1)) { - PORT_FreeArena(arena,PR_FALSE); - PORT_SetError(SEC_ERROR_BAD_KEY); - return CK_INVALID_HANDLE; - } - - - - /* - * issue the find - */ - parent = *(CK_OBJECT_CLASS *)(keyclass->pValue); - *(CK_OBJECT_CLASS *)(keyclass->pValue) = matchclass; - - peerID = pk11_FindObjectByTemplate(slot,theTemplate,tsize); - PORT_FreeArena(arena,PR_FALSE); - - return peerID; -} - -PRBool -PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert, - CK_OBJECT_HANDLE certID) -{ - CK_OBJECT_CLASS theClass; - - if (slot == NULL) return PR_FALSE; - if (cert == NULL) return PR_FALSE; - - theClass = CKO_PRIVATE_KEY; - if (!PK11_IsLoggedIn(slot,NULL) && PK11_NeedLogin(slot)) { - theClass = CKO_PUBLIC_KEY; - } - if (PK11_MatchItem(slot, certID , theClass) != CK_INVALID_HANDLE) { - return PR_TRUE; - } - - if (theClass == CKO_PUBLIC_KEY) { - SECKEYPublicKey *pubKey= CERT_ExtractPublicKey(cert); - CK_ATTRIBUTE theTemplate; - - if (pubKey == NULL) { - return PR_FALSE; - } - - PK11_SETATTRS(&theTemplate,0,NULL,0); - switch (pubKey->keyType) { - case rsaKey: - PK11_SETATTRS(&theTemplate,CKA_MODULUS, pubKey->u.rsa.modulus.data, - pubKey->u.rsa.modulus.len); - break; - case dsaKey: - PK11_SETATTRS(&theTemplate,CKA_VALUE, pubKey->u.dsa.publicValue.data, - pubKey->u.dsa.publicValue.len); - break; - case dhKey: - PK11_SETATTRS(&theTemplate,CKA_VALUE, pubKey->u.dh.publicValue.data, - pubKey->u.dh.publicValue.len); - break; - case keaKey: - case fortezzaKey: - case nullKey: - /* fall through and return false */ - break; - } - - if (theTemplate.ulValueLen == 0) { - SECKEY_DestroyPublicKey(pubKey); - return PR_FALSE; - } - pk11_SignedToUnsigned(&theTemplate); - if (pk11_FindObjectByTemplate(slot,&theTemplate,1) != CK_INVALID_HANDLE) { - SECKEY_DestroyPublicKey(pubKey); - return PR_TRUE; - } - SECKEY_DestroyPublicKey(pubKey); - } - return PR_FALSE; -} - -/* - * Check out if a cert has ID of zero. This is a magic ID that tells - * NSS that this cert may be an automagically trusted cert. - * The Cert has to be self signed as well. That check is done elsewhere. - * - */ -PRBool -pk11_isID0(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID) -{ - CK_ATTRIBUTE keyID = {CKA_ID, NULL, 0}; - PRBool isZero = PR_FALSE; - int i; - CK_RV crv; - - - crv = PK11_GetAttributes(NULL,slot,certID,&keyID,1); - if (crv != CKR_OK) { - return isZero; - } - - if (keyID.ulValueLen != 0) { - char *value = (char *)keyID.pValue; - isZero = PR_TRUE; /* ID exists, may be zero */ - for (i=0; i < (int) keyID.ulValueLen; i++) { - if (value[i] != 0) { - isZero = PR_FALSE; /* nope */ - break; - } - } - } - PORT_Free(keyID.pValue); - return isZero; - -} - -/* - * Create an NSSCertificate from a slot/certID pair, return it as a - * CERTCertificate. - */ -static CERTCertificate -*pk11_fastCert(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, - CK_ATTRIBUTE *privateLabel, char **nickptr) -{ - NSSCertificate *c; - nssCryptokiObject *co; - nssPKIObject *pkio; - NSSToken *token; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - - /* Get the cryptoki object from the handle */ - token = PK11Slot_GetNSSToken(slot); - co = nssCryptokiObject_Create(token, token->defaultSession, certID); - if (!co) { - return NULL; - } - - /* Create a PKI object from the cryptoki instance */ - pkio = nssPKIObject_Create(NULL, co, td, NULL); - if (!pkio) { - nssCryptokiObject_Destroy(co); - return NULL; - } - - /* Create a certificate */ - c = nssCertificate_Create(pkio); - if (!c) { - nssPKIObject_Destroy(pkio); - return NULL; - } - - /* Build the old-fashioned nickname */ - if ((nickptr) && (co->label)) { - CK_ATTRIBUTE label, id; - label.type = CKA_LABEL; - label.pValue = co->label; - label.ulValueLen = PORT_Strlen(co->label); - id.type = CKA_ID; - id.pValue = c->id.data; - id.ulValueLen = c->id.size; - *nickptr = pk11_buildNickname(slot, &label, privateLabel, &id); - } - return STAN_GetCERTCertificate(c); -} - -CK_TRUST -pk11_GetTrustField(PK11SlotInfo *slot, PRArenaPool *arena, - CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type) -{ - CK_TRUST rv = 0; - SECItem item; - - item.data = NULL; - item.len = 0; - - if( SECSuccess == PK11_ReadAttribute(slot, id, type, arena, &item) ) { - PORT_Assert(item.len == sizeof(CK_TRUST)); - PORT_Memcpy(&rv, item.data, sizeof(CK_TRUST)); - /* Damn, is there an endian problem here? */ - return rv; - } - - return 0; -} - -PRBool -pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust *trust) -{ - PRArenaPool *arena; - - CK_ATTRIBUTE tobjTemplate[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_CERT_SHA1_HASH, NULL, 0 }, - }; - - CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST; - CK_OBJECT_HANDLE tobjID; - unsigned char sha1_hash[SHA1_LENGTH]; - - CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth; - - PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len); - - PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc)); - PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash, - SHA1_LENGTH); - - tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate, - sizeof(tobjTemplate)/sizeof(tobjTemplate[0])); - if( CK_INVALID_HANDLE == tobjID ) { - return PR_FALSE; - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if( NULL == arena ) return PR_FALSE; - - /* Unfortunately, it seems that PK11_GetAttributes doesn't deal - * well with nonexistant attributes. I guess we have to check - * the trust info fields one at a time. - */ - - /* We could verify CKA_CERT_HASH here */ - - /* We could verify CKA_EXPIRES here */ - - - /* "Purpose" trust information */ - serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH); - clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH); - codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING); - emailProtection = pk11_GetTrustField(slot, arena, tobjID, - CKA_TRUST_EMAIL_PROTECTION); - /* Here's where the fun logic happens. We have to map back from the - * key usage, extended key usage, purpose, and possibly other trust values - * into the old trust-flags bits. */ - - /* First implementation: keep it simple for testing. We can study what other - * mappings would be appropriate and add them later.. fgmr 20000724 */ - - if ( serverAuth == CKT_NETSCAPE_TRUSTED ) { - trust->sslFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED; - } - - if ( serverAuth == CKT_NETSCAPE_TRUSTED_DELEGATOR ) { - trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | - CERTDB_NS_TRUSTED_CA; - } - if ( clientAuth == CKT_NETSCAPE_TRUSTED_DELEGATOR ) { - trust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA ; - } - - if ( emailProtection == CKT_NETSCAPE_TRUSTED ) { - trust->emailFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED; - } - - if ( emailProtection == CKT_NETSCAPE_TRUSTED_DELEGATOR ) { - trust->emailFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA; - } - - if( codeSigning == CKT_NETSCAPE_TRUSTED ) { - trust->objectSigningFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED; - } - - if( codeSigning == CKT_NETSCAPE_TRUSTED_DELEGATOR ) { - trust->objectSigningFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA; - } - - /* There's certainly a lot more logic that can go here.. */ - - PORT_FreeArena(arena, PR_FALSE); - - return PR_TRUE; -} - -/* - * Build an CERTCertificate structure from a PKCS#11 object ID.... certID - * Must be a CertObject. This code does not explicitly checks that. - */ -CERTCertificate * -PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID, - CK_ATTRIBUTE *privateLabel) -{ - char * nickname = NULL; - CERTCertificate *cert = NULL; - CERTCertTrust *trust; - PRBool isFortezzaRootCA = PR_FALSE; - PRBool swapNickname = PR_FALSE; - - cert = pk11_fastCert(slot,certID,privateLabel, &nickname); - if (cert == NULL) goto loser; - - if (nickname) { - if (cert->nickname != NULL) { - cert->dbnickname = cert->nickname; - } - cert->nickname = PORT_ArenaStrdup(cert->arena,nickname); - PORT_Free(nickname); - nickname = NULL; - swapNickname = PR_TRUE; - } - - /* remember where this cert came from.... If we have just looked - * it up from the database and it already has a slot, don't add a new - * one. */ - if (cert->slot == NULL) { - cert->slot = PK11_ReferenceSlot(slot); - cert->pkcs11ID = certID; - cert->ownSlot = PR_TRUE; - cert->series = slot->series; - } - - trust = (CERTCertTrust*)PORT_ArenaAlloc(cert->arena, sizeof(CERTCertTrust)); - if (trust == NULL) goto loser; - PORT_Memset(trust,0, sizeof(CERTCertTrust)); - cert->trust = trust; - - - - if(! pk11_HandleTrustObject(slot, cert, trust) ) { - unsigned int type; - - /* build some cert trust flags */ - if (CERT_IsCACert(cert, &type)) { - unsigned int trustflags = CERTDB_VALID_CA; - - /* Allow PKCS #11 modules to give us trusted CA's. We only accept - * valid CA's which are self-signed here. They must have an object - * ID of '0'. */ - if (pk11_isID0(slot,certID) && - SECITEM_CompareItem(&cert->derSubject,&cert->derIssuer) - == SECEqual) { - trustflags |= CERTDB_TRUSTED_CA; - /* is the slot a fortezza card? allow the user or - * admin to turn on objectSigning, but don't turn - * full trust on explicitly */ - if (PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) { - trust->objectSigningFlags |= CERTDB_VALID_CA; - isFortezzaRootCA = PR_TRUE; - } - } - if ((type & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) { - trust->sslFlags |= trustflags; - } - if ((type & NS_CERT_TYPE_EMAIL_CA) == NS_CERT_TYPE_EMAIL_CA) { - trust->emailFlags |= trustflags; - } - if ((type & NS_CERT_TYPE_OBJECT_SIGNING_CA) - == NS_CERT_TYPE_OBJECT_SIGNING_CA) { - trust->objectSigningFlags |= trustflags; - } - } - } - - if (PK11_IsUserCert(slot,cert,certID)) { - trust->sslFlags |= CERTDB_USER; - trust->emailFlags |= CERTDB_USER; - /* trust->objectSigningFlags |= CERTDB_USER; */ - } - - return cert; - -loser: - if (nickname) PORT_Free(nickname); - if (cert) CERT_DestroyCertificate(cert); - return NULL; -} - - -/* - * Build get a certificate from a private key - */ -CERTCertificate * -PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey) -{ - PK11SlotInfo *slot = privKey->pkcs11Slot; - CK_OBJECT_HANDLE handle = privKey->pkcs11ID; - CK_OBJECT_HANDLE certID = - PK11_MatchItem(slot,handle,CKO_CERTIFICATE); - CERTCertificate *cert; - - if (certID == CK_INVALID_HANDLE) { - PORT_SetError(SSL_ERROR_NO_CERTIFICATE); - return NULL; - } - cert = PK11_MakeCertFromHandle(slot,certID,NULL); - return (cert); - -} - -/* - * destroy a private key if there are no matching certs. - * this function also frees the privKey structure. - */ -SECStatus -PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force) -{ - CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey); - - /* found a cert matching the private key?. */ - if (!force && cert != NULL) { - /* yes, don't delete the key */ - CERT_DestroyCertificate(cert); - SECKEY_DestroyPrivateKey(privKey); - return SECWouldBlock; - } - /* now, then it's safe for the key to go away */ - PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID); - SECKEY_DestroyPrivateKey(privKey); - return SECSuccess; -} - -/* - * destroy a private key if there are no matching certs. - * this function also frees the privKey structure. - */ -SECStatus -PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey) -{ - /* now, then it's safe for the key to go away */ - if (pubKey->pkcs11Slot == NULL) { - return SECFailure; - } - PK11_DestroyTokenObject(pubKey->pkcs11Slot,pubKey->pkcs11ID); - SECKEY_DestroyPublicKey(pubKey); - return SECSuccess; -} - - -/* - * delete a cert and it's private key (if no other certs are pointing to the - * private key. - */ -SECStatus -PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx) -{ - SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(cert,wincx); - CK_OBJECT_HANDLE pubKey; - PK11SlotInfo *slot = NULL; - - pubKey = pk11_FindPubKeyByAnyCert(cert, &slot, wincx); - if (privKey) { -#ifdef NSS_CLASSIC - PK11_DestroyTokenObject(cert->slot,cert->pkcs11ID); -#else - /* For 3.4, utilize the generic cert delete function */ - SEC_DeletePermCertificate(cert); -#endif - PK11_DeleteTokenPrivateKey(privKey, PR_FALSE); - } - if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) { - PK11_DestroyTokenObject(slot,pubKey); - PK11_FreeSlot(slot); - } - return SECSuccess; -} - -/* - * count the number of objects that match the template. - */ -int -PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate, - int templateCount) -{ - CK_OBJECT_HANDLE objID[PK11_SEARCH_CHUNKSIZE]; - int object_count = 0; - CK_ULONG returned_count = 0; - CK_RV crv; - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session, - findTemplate, templateCount); - if (crv != CKR_OK) { - PK11_ExitSlotMonitor(slot); - PORT_SetError( PK11_MapError(crv) ); - return 0; - } - - /* - * collect all the Matching Objects - */ - do { - crv = PK11_GETTAB(slot)->C_FindObjects(slot->session, - objID,PK11_SEARCH_CHUNKSIZE,&returned_count); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - break; - } - object_count += returned_count; - } while (returned_count == PK11_SEARCH_CHUNKSIZE); - - PK11_GETTAB(slot)->C_FindObjectsFinal(slot->session); - PK11_ExitSlotMonitor(slot); - return object_count; -} - -/* - * cert callback structure - */ -typedef struct pk11DoCertCallbackStr { - SECStatus(* callback)(PK11SlotInfo *slot, CERTCertificate*, void *); - SECStatus(* noslotcallback)(CERTCertificate*, void *); - SECStatus(* itemcallback)(CERTCertificate*, SECItem *, void *); - void *callbackArg; -} pk11DoCertCallback; - -/* - * callback to map object handles to certificate structures. - */ -static SECStatus -pk11_DoCerts(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, void *arg) -{ - CERTCertificate *cert; - pk11DoCertCallback *certcb = (pk11DoCertCallback *) arg; - - cert = PK11_MakeCertFromHandle(slot, certID, NULL); - - if (cert == NULL) { - return SECFailure; - } - - if (certcb ) { - if (certcb->callback) { - (*certcb->callback)(slot, cert, certcb->callbackArg); - } - if (certcb->noslotcallback) { - (*certcb->noslotcallback)(cert, certcb->callbackArg); - } - if (certcb->itemcallback) { - (*certcb->itemcallback)(cert, NULL, certcb->callbackArg); - } - } - - CERT_DestroyCertificate(cert); - - return SECSuccess; -} - -static SECStatus -pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg) -{ - SECItem derCrl; - CERTCrlHeadNode *head = (CERTCrlHeadNode *) arg; - CERTCrlNode *new_node = NULL; - CK_ATTRIBUTE fetchCrl[3] = { - { CKA_VALUE, NULL, 0}, - { CKA_NETSCAPE_KRL, NULL, 0}, - { CKA_NETSCAPE_URL, NULL, 0}, - }; - const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]); - SECStatus rv; - - rv = PK11_GetAttributes(head->arena,slot,crlID,fetchCrl,fetchCrlSize); - if (rv == SECFailure) { - goto loser; - } - rv = SECFailure; - - new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode)); - if (new_node == NULL) { - goto loser; - } - - new_node->type = *((CK_BBOOL *)fetchCrl[1].pValue) ? - SEC_KRL_TYPE : SEC_CRL_TYPE; - derCrl.data = (unsigned char *)fetchCrl[0].pValue; - derCrl.len = fetchCrl[0].ulValueLen; - new_node->crl=CERT_DecodeDERCrl(head->arena,&derCrl,new_node->type); - if (new_node->crl == NULL) { - goto loser; - } - - if (fetchCrl[2].pValue) { - int nnlen = fetchCrl[2].ulValueLen; - new_node->crl->url = (char *)PORT_ArenaAlloc(head->arena, nnlen+1); - if ( !new_node->crl->url ) { - goto loser; - } - PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen); - new_node->crl->url[nnlen] = 0; - } else { - new_node->crl->url = NULL; - } - - - new_node->next = NULL; - if (head->last) { - head->last->next = new_node; - head->last = new_node; - } else { - head->first = head->last = new_node; - } - rv = SECSuccess; - -loser: - return(rv); -} - - -/* - * key call back structure. - */ -typedef struct pk11KeyCallbackStr { - SECStatus (* callback)(SECKEYPrivateKey *,void *); - void *callbackArg; - void *wincx; -} pk11KeyCallback; - -/* - * callback to map Object Handles to Private Keys; - */ -SECStatus -pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) -{ - SECStatus rv = SECSuccess; - SECKEYPrivateKey *privKey; - pk11KeyCallback *keycb = (pk11KeyCallback *) arg; - - privKey = PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,keycb->wincx); - - if (privKey == NULL) { - return SECFailure; - } - - if (keycb && (keycb->callback)) { - rv = (*keycb->callback)(privKey,keycb->callbackArg); - } - - SECKEY_DestroyPrivateKey(privKey); - return rv; -} - -/* Traverse slots callback */ -typedef struct pk11TraverseSlotStr { - SECStatus (*callback)(PK11SlotInfo *,CK_OBJECT_HANDLE, void *); - void *callbackArg; - CK_ATTRIBUTE *findTemplate; - int templateCount; -} pk11TraverseSlot; - -/* - * Extract all the certs on a card from a slot. - */ -SECStatus -PK11_TraverseSlot(PK11SlotInfo *slot, void *arg) -{ - int i; - CK_OBJECT_HANDLE *objID = NULL; - int object_count = 0; - pk11TraverseSlot *slotcb = (pk11TraverseSlot*) arg; - - objID = pk11_FindObjectsByTemplate(slot,slotcb->findTemplate, - slotcb->templateCount,&object_count); - - /*Actually this isn't a failure... there just were no objs to be found*/ - if (object_count == 0) { - return SECSuccess; - } - - if (objID == NULL) { - return SECFailure; - } - - for (i=0; i < object_count; i++) { - (*slotcb->callback)(slot,objID[i],slotcb->callbackArg); - } - PORT_Free(objID); - return SECSuccess; -} - -typedef struct pk11CertCallbackStr { - SECStatus(* callback)(CERTCertificate*,SECItem *,void *); - void *callbackArg; -} pk11CertCallback; - -/* - * Extract all the certs on a card from a slot. - */ -SECStatus -pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *arg,void *wincx) { - PK11SlotList *list; - PK11SlotListElement *le; - SECStatus rv; - - /* get them all! */ - list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,wincx); - if (list == NULL) return SECFailure; - - /* look at each slot and authenticate as necessary */ - for (le = list->head ; le; le = le->next) { - if (!PK11_IsFriendly(le->slot)) { - rv = PK11_Authenticate(le->slot, PR_FALSE, wincx); - if (rv != SECSuccess) continue; - } - if (callback) { - (*callback)(le->slot,arg); - } - } - - PK11_FreeSlotList(list); - - return SECSuccess; -} - -struct fake_der_cb_argstr -{ - SECStatus(* callback)(CERTCertificate*, SECItem *, void *); - void *arg; -}; - -static SECStatus fake_der_cb(CERTCertificate *c, void *a) -{ - struct fake_der_cb_argstr *fda = (struct fake_der_cb_argstr *)a; - return (*fda->callback)(c, &c->derCert, fda->arg); -} - -/* - * Extract all the certs on a card from a slot. - */ -SECStatus -PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *), - void *arg, void *wincx) { -#ifdef NSS_CLASSIC - pk11DoCertCallback caller; - pk11TraverseSlot creater; - CK_ATTRIBUTE theTemplate; - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - - PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass)); - - caller.callback = NULL; - caller.noslotcallback = NULL; - caller.itemcallback = callback; - caller.callbackArg = arg; - creater.callback = pk11_DoCerts; - creater.callbackArg = (void *) & caller; - creater.findTemplate = &theTemplate; - creater.templateCount = 1; - - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); -#else - NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); - struct fake_der_cb_argstr fda; - struct nss3_cert_cbstr pk11cb; - - /* authenticate to the tokens first */ - (void) pk11_TraverseAllSlots( NULL, NULL, wincx); - - fda.callback = callback; - fda.arg = arg; - pk11cb.callback = fake_der_cb; - pk11cb.arg = &fda; - NSSTrustDomain_TraverseCertificates(defaultTD, convert_cert, &pk11cb); - return SECSuccess; -#endif -} - -/* - * Extract all the certs on a card from a slot. - */ -SECStatus -PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) { - pk11TraverseSlot creater; - CK_ATTRIBUTE theTemplate[2]; - CK_ATTRIBUTE *attrs; - CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL; - - attrs = theTemplate; - PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++; - if (type != -1) { - CK_BBOOL isKrl = (CK_BBOOL) (type == SEC_KRL_TYPE); - PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl)); attrs++; - } - - creater.callback = pk11_CollectCrls; - creater.callbackArg = (void *) nodes; - creater.findTemplate = theTemplate; - creater.templateCount = (attrs - theTemplate); - - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); -} - -/*********************************************************************** - * PK11_TraversePrivateKeysInSlot - * - * Traverses all the private keys on a slot. - * - * INPUTS - * slot - * The PKCS #11 slot whose private keys you want to traverse. - * callback - * A callback function that will be called for each key. - * arg - * An argument that will be passed to the callback function. - */ -SECStatus -PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot, - SECStatus(* callback)(SECKEYPrivateKey*, void*), void *arg) -{ - pk11KeyCallback perKeyCB; - pk11TraverseSlot perObjectCB; - CK_OBJECT_CLASS privkClass = CKO_PRIVATE_KEY; - CK_BBOOL ckTrue = CK_TRUE; - CK_ATTRIBUTE theTemplate[2]; - int templateSize = 2; - - theTemplate[0].type = CKA_CLASS; - theTemplate[0].pValue = &privkClass; - theTemplate[0].ulValueLen = sizeof(privkClass); - theTemplate[1].type = CKA_TOKEN; - theTemplate[1].pValue = &ckTrue; - theTemplate[1].ulValueLen = sizeof(ckTrue); - - if(slot==NULL) { - return SECSuccess; - } - - perObjectCB.callback = pk11_DoKeys; - perObjectCB.callbackArg = &perKeyCB; - perObjectCB.findTemplate = theTemplate; - perObjectCB.templateCount = templateSize; - perKeyCB.callback = callback; - perKeyCB.callbackArg = arg; - perKeyCB.wincx = NULL; - - return PK11_TraverseSlot(slot, &perObjectCB); -} - -CK_OBJECT_HANDLE * -PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr, - CK_OBJECT_CLASS objclass, int *returnCount, void *wincx) -{ - char *tokenName; - char *delimit; - PK11SlotInfo *slot; - CK_OBJECT_HANDLE *objID; - CK_ATTRIBUTE findTemplate[] = { - { CKA_LABEL, NULL, 0}, - { CKA_CLASS, NULL, 0}, - }; - int findCount = sizeof(findTemplate)/sizeof(findTemplate[0]); - SECStatus rv; - PK11_SETATTRS(&findTemplate[1], CKA_CLASS, &objclass, sizeof(objclass)); - - *slotptr = slot = NULL; - *returnCount = 0; - /* first find the slot associated with this nickname */ - if ((delimit = PORT_Strchr(nickname,':')) != NULL) { - int len = delimit - nickname; - tokenName = (char*)PORT_Alloc(len+1); - PORT_Memcpy(tokenName,nickname,len); - tokenName[len] = 0; - - slot = *slotptr = PK11_FindSlotByName(tokenName); - PORT_Free(tokenName); - /* if we couldn't find a slot, assume the nickname is an internal cert - * with no proceding slot name */ - if (slot == NULL) { - slot = *slotptr = PK11_GetInternalKeySlot(); - } else { - nickname = delimit+1; - } - } else { - *slotptr = slot = PK11_GetInternalKeySlot(); - } - if (slot == NULL) { - return CK_INVALID_HANDLE; - } - - if (!PK11_IsFriendly(slot)) { - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) { - PK11_FreeSlot(slot); - *slotptr = NULL; - return CK_INVALID_HANDLE; - } - } - - findTemplate[0].pValue = nickname; - findTemplate[0].ulValueLen = PORT_Strlen(nickname); - objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount,returnCount); - if (objID == NULL) { - /* PKCS #11 isn't clear on whether or not the NULL is - * stored in the template.... try the find again with the - * full null terminated string. */ - findTemplate[0].ulValueLen += 1; - objID = pk11_FindObjectsByTemplate(slot,findTemplate,findCount, - returnCount); - if (objID == NULL) { - /* Well that's the best we can do. It's just not here */ - /* what about faked nicknames? */ - PK11_FreeSlot(slot); - *slotptr = NULL; - *returnCount = 0; - } - } - - return objID; -} - -static void -transfer_token_certs_to_collection(nssList *certList, NSSToken *token, - nssPKIObjectCollection *collection) -{ - NSSCertificate **certs; - PRUint32 i, count; - NSSToken **tokens, **tp; - count = nssList_Count(certList); - if (count == 0) { - return; - } - certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count); - if (!certs) { - return; - } - nssList_GetArray(certList, (void **)certs, count); - for (i=0; i<count; i++) { - tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL); - if (tokens) { - for (tp = tokens; *tp; tp++) { - if (*tp == token) { - nssPKIObjectCollection_AddObject(collection, - (nssPKIObject *)certs[i]); - } - } - nssTokenArray_Destroy(tokens); - } - /* *must* be a valid CERTCertificate, came from cache */ - CERT_DestroyCertificate(STAN_GetCERTCertificate(certs[i])); - } - nss_ZFreeIf(certs); -} - -CERTCertificate * -PK11_FindCertFromNickname(char *nickname, void *wincx) { -#ifdef NSS_CLASSIC - PK11SlotInfo *slot; - int count=0; - CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot, - CKO_CERTIFICATE, &count, wincx); - CERTCertificate *cert; - - if (certID == CK_INVALID_HANDLE) return NULL; - cert = PK11_MakeCertFromHandle(slot,certID[0],NULL); - PK11_FreeSlot(slot); - PORT_Free(certID); - return cert; -#else - PRStatus status; - CERTCertificate *rvCert = NULL; - NSSCertificate *cert = NULL; - NSSCertificate **certs = NULL; - NSSUsage usage; - NSSToken *token; - PK11SlotInfo *slot = NULL; - char *nickCopy; - char *delimit = NULL; - char *tokenName; - NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); - usage.anyUsage = PR_TRUE; - nickCopy = PORT_Strdup(nickname); - if ((delimit = PORT_Strchr(nickCopy,':')) != NULL) { - tokenName = nickCopy; - nickname = delimit + 1; - *delimit = '\0'; - /* find token by name */ - token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName); - if (token) { - slot = PK11_ReferenceSlot(token->pk11slot); - } - *delimit = ':'; - } else { - slot = PK11_GetInternalKeySlot(); - token = PK11Slot_GetNSSToken(slot); - } - if (token) { - nssList *certList; - nssCryptokiObject **instances; - nssPKIObjectCollection *collection; - nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; - if (!PK11_IsPresent(slot)) { - goto loser; - } - if (!PK11_IsFriendly(slot)) { - if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { - goto loser; - } - } - collection = nssCertificateCollection_Create(defaultTD, NULL); - if (!collection) { - goto loser; - } - certList = nssList_Create(NULL, PR_FALSE); - if (!certList) { - nssPKIObjectCollection_Destroy(collection); - goto loser; - } - (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, - nickname, - certList); - transfer_token_certs_to_collection(certList, token, collection); - instances = nssToken_FindCertificatesByNickname(token, - NULL, - nickname, - tokenOnly, - 0, - &status); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - /* if it wasn't found, repeat the process for email address */ - if (nssPKIObjectCollection_Count(collection) == 0 && - PORT_Strchr(nickname, '@') != NULL) - { - (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD, - nickname, - certList); - transfer_token_certs_to_collection(certList, token, collection); - instances = nssToken_FindCertificatesByEmail(token, - NULL, - nickname, - tokenOnly, - 0, - &status); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - } - certs = nssPKIObjectCollection_GetCertificates(collection, - NULL, 0, NULL); - nssPKIObjectCollection_Destroy(collection); - if (certs) { - cert = nssCertificateArray_FindBestCertificate(certs, NULL, - &usage, NULL); - if (cert) { - rvCert = STAN_GetCERTCertificate(cert); - } - nssCertificateArray_Destroy(certs); - } - nssList_Destroy(certList); - } - if (slot) { - PK11_FreeSlot(slot); - } - if (nickCopy) PORT_Free(nickCopy); - return rvCert; -loser: - if (slot) { - PK11_FreeSlot(slot); - } - if (nickCopy) PORT_Free(nickCopy); - return NULL; -#endif -} - -CERTCertList * -PK11_FindCertsFromNickname(char *nickname, void *wincx) { -#ifdef NSS_CLASSIC - PK11SlotInfo *slot; - int i,count = 0; - CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot, - CKO_CERTIFICATE, &count, wincx); - CERTCertList *certList = NULL; - - if (certID == NULL) return NULL; - - certList= CERT_NewCertList(); - - for (i=0; i < count; i++) { - CERTCertificate *cert = PK11_MakeCertFromHandle(slot,certID[i],NULL); - - if (cert) CERT_AddCertToListTail(certList,cert); - } - - if (CERT_LIST_HEAD(certList) == NULL) { - CERT_DestroyCertList(certList); - certList = NULL; - } - PK11_FreeSlot(slot); - PORT_Free(certID); - return certList; -#else - char *nickCopy; - char *delimit = NULL; - char *tokenName; - int i; - CERTCertList *certList = NULL; - nssPKIObjectCollection *collection = NULL; - NSSCertificate **foundCerts = NULL; - NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); - NSSCertificate *c; - NSSToken *token; - PK11SlotInfo *slot; - nickCopy = PORT_Strdup(nickname); - if ((delimit = PORT_Strchr(nickCopy,':')) != NULL) { - tokenName = nickCopy; - nickname = delimit + 1; - *delimit = '\0'; - /* find token by name */ - token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName); - if (token) { - slot = PK11_ReferenceSlot(token->pk11slot); - } else { - slot = NULL; - } - *delimit = ':'; - } else { - slot = PK11_GetInternalKeySlot(); - token = PK11Slot_GetNSSToken(slot); - } - if (token) { - PRStatus status; - nssList *nameList; - nssCryptokiObject **instances; - nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; - if (!PK11_IsFriendly(slot)) { - if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { - PK11_FreeSlot(slot); - if (nickCopy) PORT_Free(nickCopy); - return NULL; - } - } - collection = nssCertificateCollection_Create(defaultTD, NULL); - if (!collection) { - PK11_FreeSlot(slot); - if (nickCopy) PORT_Free(nickCopy); - return NULL; - } - nameList = nssList_Create(NULL, PR_FALSE); - if (!nameList) { - PK11_FreeSlot(slot); - if (nickCopy) PORT_Free(nickCopy); - return NULL; - } - (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, - nickname, - nameList); - transfer_token_certs_to_collection(nameList, token, collection); - instances = nssToken_FindCertificatesByNickname(token, - NULL, - nickname, - tokenOnly, - 0, - &status); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - nssList_Destroy(nameList); - foundCerts = nssPKIObjectCollection_GetCertificates(collection, - NULL, 0, NULL); - nssPKIObjectCollection_Destroy(collection); - } - if (slot) { - PK11_FreeSlot(slot); - } - if (nickCopy) PORT_Free(nickCopy); - if (foundCerts) { - PRTime now = PR_Now(); - certList = CERT_NewCertList(); - for (i=0, c = *foundCerts; c; c = foundCerts[++i]) { - CERTCertificate *certCert = STAN_GetCERTCertificate(c); - if (certCert) { - CERT_AddCertToListSorted(certList, certCert, - CERT_SortCBValidity, &now); - } - } - if (CERT_LIST_HEAD(certList) == NULL) { - CERT_DestroyCertList(certList); - certList = NULL; - } - nss_ZFreeIf(foundCerts); - } - return certList; -#endif -} - -/* - * extract a key ID for a certificate... - * NOTE: We call this function from PKCS11.c If we ever use - * pkcs11 to extract the public key (we currently do not), this will break. - */ -SECItem * -PK11_GetPubIndexKeyID(CERTCertificate *cert) { - SECKEYPublicKey *pubk; - SECItem *newItem = NULL; - - pubk = CERT_ExtractPublicKey(cert); - if (pubk == NULL) return NULL; - - switch (pubk->keyType) { - case rsaKey: - newItem = SECITEM_DupItem(&pubk->u.rsa.modulus); - break; - case dsaKey: - newItem = SECITEM_DupItem(&pubk->u.dsa.publicValue); - break; - case dhKey: - newItem = SECITEM_DupItem(&pubk->u.dh.publicValue); - break; - case fortezzaKey: - default: - newItem = NULL; /* Fortezza Fix later... */ - } - SECKEY_DestroyPublicKey(pubk); - /* make hash of it */ - return newItem; -} - -/* - * generate a CKA_ID from a certificate. - */ -SECItem * -pk11_mkcertKeyID(CERTCertificate *cert) { - SECItem *pubKeyData = PK11_GetPubIndexKeyID(cert) ; - SECItem *certCKA_ID; - - if (pubKeyData == NULL) return NULL; - - certCKA_ID = PK11_MakeIDFromPubKey(pubKeyData); - SECITEM_FreeItem(pubKeyData,PR_TRUE); - return certCKA_ID; -} - - -/* - * Generate a CKA_ID from the relevant public key data. The CKA_ID is generated - * from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make - * smart cards happy. - */ -SECItem * -PK11_MakeIDFromPubKey(SECItem *pubKeyData) { - PK11Context *context; - SECItem *certCKA_ID; - SECStatus rv; - - context = PK11_CreateDigestContext(SEC_OID_SHA1); - if (context == NULL) { - return NULL; - } - - rv = PK11_DigestBegin(context); - if (rv == SECSuccess) { - rv = PK11_DigestOp(context,pubKeyData->data,pubKeyData->len); - } - if (rv != SECSuccess) { - PK11_DestroyContext(context,PR_TRUE); - return NULL; - } - - certCKA_ID = (SECItem *)PORT_Alloc(sizeof(SECItem)); - if (certCKA_ID == NULL) { - PK11_DestroyContext(context,PR_TRUE); - return NULL; - } - - certCKA_ID->len = SHA1_LENGTH; - certCKA_ID->data = (unsigned char*)PORT_Alloc(certCKA_ID->len); - if (certCKA_ID->data == NULL) { - PORT_Free(certCKA_ID); - PK11_DestroyContext(context,PR_TRUE); - return NULL; - } - - rv = PK11_DigestFinal(context,certCKA_ID->data,&certCKA_ID->len, - SHA1_LENGTH); - PK11_DestroyContext(context,PR_TRUE); - if (rv != SECSuccess) { - SECITEM_FreeItem(certCKA_ID,PR_TRUE); - return NULL; - } - - return certCKA_ID; -} - -/* - * Write the cert into the token. - */ -SECStatus -PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, - CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust) { -#ifdef NSS_CLASSIC - int len = 0; - SECItem *keyID = pk11_mkcertKeyID(cert); - CK_ATTRIBUTE keyAttrs[] = { - { CKA_LABEL, NULL, 0}, - { CKA_SUBJECT, NULL, 0}, - }; - CK_OBJECT_CLASS certc = CKO_CERTIFICATE; - CK_CERTIFICATE_TYPE certType = CKC_X_509; - CK_OBJECT_HANDLE certID; - CK_SESSION_HANDLE rwsession; - CK_BBOOL cktrue = CK_TRUE; - SECStatus rv = SECFailure; - CK_ATTRIBUTE certAttrs[] = { - { CKA_ID, NULL, 0 }, - { CKA_LABEL, NULL, 0}, - { CKA_CLASS, NULL, 0}, - { CKA_TOKEN, NULL, 0}, - { CKA_CERTIFICATE_TYPE, NULL, 0}, - { CKA_SUBJECT, NULL, 0}, - { CKA_ISSUER, NULL, 0}, - { CKA_SERIAL_NUMBER, NULL, 0}, - { CKA_VALUE, NULL, 0}, - { CKA_NETSCAPE_TRUST, NULL, 0}, - { CKA_NETSCAPE_EMAIL, NULL, 0}, - }; - int certCount = sizeof(certAttrs)/sizeof(certAttrs[0]), keyCount = 2; - int realCount = 0; - CK_ATTRIBUTE *attrs; - CK_RV crv; - SECCertUsage *certUsage = NULL; - SECItem derSerial = { 0 }; - NSSToken *token; - - if (keyID == NULL) { - PORT_SetError(SEC_ERROR_ADDING_CERT); - return rv; - } - - len = ((nickname) ? PORT_Strlen(nickname) : 0); - - attrs = certAttrs; - PK11_SETATTRS(attrs,CKA_ID, keyID->data, keyID->len); attrs++; - if (nickname) { - PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++; - } - PK11_SETATTRS(attrs,CKA_CLASS, &certc, sizeof(certc) ); attrs++; - PK11_SETATTRS(attrs,CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++; - PK11_SETATTRS(attrs,CKA_CERTIFICATE_TYPE, &certType, - sizeof(certType)); attrs++; - PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data, - cert->derSubject.len ); attrs++; - PK11_SETATTRS(attrs,CKA_ISSUER, cert->derIssuer.data, - cert->derIssuer.len ); attrs++; - if (PR_TRUE) { - /* CERTCertificate stores serial numbers decoded. I need the DER - * here. sigh. - */ - CERT_SerialNumberFromDERCert(&cert->derCert, &derSerial); - PK11_SETATTRS(attrs,CKA_SERIAL_NUMBER, derSerial.data, derSerial.len); - attrs++; - } - PK11_SETATTRS(attrs,CKA_VALUE, cert->derCert.data, - cert->derCert.len); attrs++; - if (includeTrust && PK11_IsInternal(slot)) { - certUsage = (SECCertUsage*)PORT_Alloc(sizeof(SECCertUsage)); - if(!certUsage) { - SECITEM_FreeItem(keyID,PR_TRUE); - PORT_SetError(SEC_ERROR_NO_MEMORY); - return rv; - } - *certUsage = certUsageUserCertImport; - PK11_SETATTRS(attrs,CKA_NETSCAPE_TRUST, certUsage, - sizeof(SECCertUsage)); - attrs++; - if (cert->emailAddr) { - PK11_SETATTRS(attrs,CKA_NETSCAPE_EMAIL, cert->emailAddr, - PORT_Strlen(cert->emailAddr); - attrs++; - } - } - realCount = attrs - certAttrs; - PORT_Assert(realCount <= certCount); - - attrs = keyAttrs; - if(nickname) { - PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++; - } - PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data, - cert->derSubject.len ); - - if(!nickname) { - certCount--; - keyCount--; - } - - rwsession = PK11_GetRWSession(slot); - if (key != CK_INVALID_HANDLE) { - crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession,key,keyAttrs, - keyCount); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - goto done; - } - } - - crv = PK11_GETTAB(slot)-> - C_CreateObject(rwsession,certAttrs,realCount,&certID); - if (crv == CKR_OK) { - rv = SECSuccess; - } else { - PORT_SetError( PK11_MapError(crv) ); - } - - if (!cert->nickname && nickname) { - cert->nickname = PORT_ArenaStrdup(cert->arena, nickname); - } - - cert->pkcs11ID = certID; - cert->dbhandle = STAN_GetDefaultTrustDomain(); - if (cert->slot == NULL) { - cert->slot = PK11_ReferenceSlot(slot); - cert->series = slot->series; - cert->ownSlot = PR_TRUE; - if (cert->nssCertificate) { - nssCryptokiInstance *instance; - NSSCertificate *c = cert->nssCertificate; - instance = nss_ZNEW(c->object.arena, nssCryptokiInstance); - instance->token = slot->nssToken; - instance->handle = cert->pkcs11ID; - instance->isTokenObject = PR_TRUE; - nssPKIObject_AddInstance(&c->object, instance); - } else { - cert->nssCertificate = STAN_GetNSSCertificate(cert); - } - } - cert->trust = nssTrust_GetCERTCertTrustForCert(cert->nssCertificate, cert); - token = PK11Slot_GetNSSToken(slot); - -done: - if (derSerial.data) PORT_Free(derSerial.data); - SECITEM_FreeItem(keyID,PR_TRUE); - PK11_RestoreROSession(slot,rwsession); - if(certUsage) { - PORT_Free(certUsage); - } - return rv; -#else - PRStatus status; - NSSCertificate *c; - nssCryptokiObject *keyobj, *certobj; - NSSToken *token = PK11Slot_GetNSSToken(slot); - SECItem *keyID = pk11_mkcertKeyID(cert); - char *emailAddr = NULL; - - if (keyID == NULL) { - goto loser; - } - - if (PK11_IsInternal(slot) && cert->emailAddr) { - emailAddr = cert->emailAddr; - } - - /* need to get the cert as a stan cert */ - if (cert->nssCertificate) { - c = cert->nssCertificate; - } else { - c = STAN_GetNSSCertificate(cert); - } - - if (c->object.cryptoContext) { - /* Delete the temp instance */ - nssCertificateStore_Remove(c->object.cryptoContext->certStore, c); - c->object.cryptoContext = NULL; - cert->istemp = PR_FALSE; - cert->isperm = PR_TRUE; - } - - /* set the id for the cert */ - nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data); - if (!c->id.data) { - goto loser; - } - - if (key != CK_INVALID_HANDLE) { - /* create an object for the key, ... */ - keyobj = nss_ZNEW(NULL, nssCryptokiObject); - if (!keyobj) { - goto loser; - } - keyobj->token = nssToken_AddRef(token); - keyobj->handle = key; - keyobj->isTokenObject = PR_TRUE; - - /* ... in order to set matching attributes for the key */ - status = nssCryptokiPrivateKey_SetCertificate(keyobj, NULL, nickname, - &c->id, &c->subject); - nssCryptokiObject_Destroy(keyobj); - if (status != PR_SUCCESS) { - goto loser; - } - } - - /* do the token import */ - certobj = nssToken_ImportCertificate(token, NULL, - NSSCertificateType_PKIX, - &c->id, - nickname, - &c->encoding, - &c->issuer, - &c->subject, - &c->serial, - emailAddr, - PR_TRUE); - if (!certobj) { - goto loser; - } - /* add the new instance to the cert, force an update of the - * CERTCertificate, and finish - */ - nssPKIObject_AddInstance(&c->object, certobj); - nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1); - (void)STAN_ForceCERTCertificateUpdate(c); - SECITEM_FreeItem(keyID,PR_TRUE); - return SECSuccess; -loser: - SECITEM_FreeItem(keyID,PR_TRUE); - PORT_SetError(SEC_ERROR_ADDING_CERT); - return SECFailure; -#endif -} - -/* - * get a certificate handle, look at the cached handle first.. - */ -CK_OBJECT_HANDLE -pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert, - CK_ATTRIBUTE *theTemplate,int tsize) -{ - CK_OBJECT_HANDLE certh; - - if (cert->slot == slot) { - certh = cert->pkcs11ID; - if ((certh == CK_INVALID_HANDLE) || - (cert->series != slot->series)) { - certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize); - cert->pkcs11ID = certh; - cert->series = slot->series; - } - } else { - certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize); - } - return certh; -} - -/* - * return the private key From a given Cert - */ -SECKEYPrivateKey * -PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, - void *wincx) { - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_VALUE, NULL, 0 }, - { CKA_CLASS, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_OBJECT_HANDLE certh; - CK_OBJECT_HANDLE keyh; - CK_ATTRIBUTE *attrs = theTemplate; - SECStatus rv; - - PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, - cert->derCert.len); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); - - /* - * issue the find - */ - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) { - return NULL; - } - - certh = pk11_getcerthandle(slot,cert,theTemplate,tsize); - if (certh == CK_INVALID_HANDLE) { - return NULL; - } - keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY); - if (keyh == CK_INVALID_HANDLE) { return NULL; } - return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx); -} - - -/* - * return the private key with the given ID - */ -static CK_OBJECT_HANDLE -pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot, SECItem *keyID) { - CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY; - CK_ATTRIBUTE theTemplate[] = { - { CKA_ID, NULL, 0 }, - { CKA_CLASS, NULL, 0 }, - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_ATTRIBUTE *attrs = theTemplate; - - PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len ); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &privKey, sizeof(privKey)); - - return pk11_FindObjectByTemplate(slot,theTemplate,tsize); -} - -/* - * import a cert for a private key we have already generated. Set the label - * on both to be the nickname. This is for the Key Gen, orphaned key case. - */ -PK11SlotInfo * -PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, - void *wincx) { - PK11SlotList *list; - PK11SlotListElement *le; - SECItem *keyID; - CK_OBJECT_HANDLE key; - PK11SlotInfo *slot = NULL; - SECStatus rv; - - keyID = pk11_mkcertKeyID(cert); - /* get them all! */ - list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); - if ((keyID == NULL) || (list == NULL)) { - if (keyID) SECITEM_FreeItem(keyID,PR_TRUE); - if (list) PK11_FreeSlotList(list); - return NULL; - } - - /* Look for the slot that holds the Key */ - for (le = list->head ; le; le = le->next) { - rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); - if (rv != SECSuccess) continue; - - key = pk11_FindPrivateKeyFromCertID(le->slot,keyID); - if (key != CK_INVALID_HANDLE) { - slot = PK11_ReferenceSlot(le->slot); - if (keyPtr) *keyPtr = key; - break; - } - } - - SECITEM_FreeItem(keyID,PR_TRUE); - PK11_FreeSlotList(list); - return slot; - -} -/* - * import a cert for a private key we have already generated. Set the label - * on both to be the nickname. This is for the Key Gen, orphaned key case. - */ -PK11SlotInfo * -PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr, - void *wincx) { - CERTCertificate *cert; - PK11SlotInfo *slot = NULL; - - /* letting this use go -- the only thing that the cert is used for is - * to get the ID attribute. - */ - cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL); - if (cert == NULL) return NULL; - - slot = PK11_KeyForCertExists(cert, keyPtr, wincx); - CERT_DestroyCertificate (cert); - return slot; -} - -PK11SlotInfo * -PK11_ImportCertForKey(CERTCertificate *cert, char *nickname,void *wincx) { - PK11SlotInfo *slot = NULL; - CK_OBJECT_HANDLE key; - - slot = PK11_KeyForCertExists(cert,&key,wincx); - - if (slot) { - if (PK11_ImportCert(slot,cert,key,nickname,PR_FALSE) != SECSuccess) { - PK11_FreeSlot(slot); - slot = NULL; - } - } else { - PORT_SetError(SEC_ERROR_ADDING_CERT); - } - - return slot; -} - -PK11SlotInfo * -PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,void *wincx) { - CERTCertificate *cert; - PK11SlotInfo *slot = NULL; - - cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), - derCert, NULL, PR_FALSE, PR_FALSE); - if (cert == NULL) return NULL; - - slot = PK11_ImportCertForKey(cert, nickname, wincx); - CERT_DestroyCertificate (cert); - return slot; -} - -static CK_OBJECT_HANDLE -pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr, - CK_ATTRIBUTE *searchTemplate, int count, void *wincx) { - PK11SlotList *list; - PK11SlotListElement *le; - CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE; - PK11SlotInfo *slot = NULL; - SECStatus rv; - - *slotPtr = NULL; - - /* get them all! */ - list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); - if (list == NULL) { - if (list) PK11_FreeSlotList(list); - return CK_INVALID_HANDLE; - } - - - /* Look for the slot that holds the Key */ - for (le = list->head ; le; le = le->next) { - if (!PK11_IsFriendly(le->slot)) { - rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); - if (rv != SECSuccess) continue; - } - - certHandle = pk11_FindObjectByTemplate(le->slot,searchTemplate,count); - if (certHandle != CK_INVALID_HANDLE) { - slot = PK11_ReferenceSlot(le->slot); - break; - } - } - - PK11_FreeSlotList(list); - - if (slot == NULL) { - return CK_INVALID_HANDLE; - } - *slotPtr = slot; - return certHandle; -} - -CERTCertificate * -PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot, - CERTIssuerAndSN *issuerSN, void *wincx) -{ - CERTCertificate *rvCert = NULL; - NSSCertificate *cert = NULL; - NSSDER issuer, serial; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - NSSToken *token = slot->nssToken; - nssSession *session; - nssCryptokiObject *instance = NULL; - nssPKIObject *object = NULL; - SECItem *derSerial; - PRStatus status; - - /* Paranoia */ - if (token == NULL) { - PORT_SetError(SEC_ERROR_NO_TOKEN); - return NULL; - } - - - /* PKCS#11 needs to use DER-encoded serial numbers. Create a - * CERTIssuerAndSN that actually has the encoded value and pass that - * to PKCS#11 (and the crypto context). - */ - derSerial = SEC_ASN1EncodeItem(NULL, NULL, - &issuerSN->serialNumber, - SEC_IntegerTemplate); - if (!derSerial) { - return NULL; - } - - NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer); - NSSITEM_FROM_SECITEM(&serial, derSerial); - - session = nssToken_GetDefaultSession(token); - if (!session) { - goto loser; - } - - instance = nssToken_FindCertificateByIssuerAndSerialNumber(token,session, - &issuer, &serial, nssTokenSearchType_TokenForced, &status); - - SECITEM_FreeItem(derSerial, PR_TRUE); - - if (!instance) { - goto loser; - } - object = nssPKIObject_Create(NULL, instance, td, NULL); - if (!object) { - goto loser; - } - instance = NULL; /* adopted by the previous call */ - cert = nssCertificate_Create(object); - if (!cert) { - goto loser; - } - object = NULL; /* adopted by the previous call */ - nssTrustDomain_AddCertsToCache(td, &cert,1); - rvCert = STAN_GetCERTCertificate(cert); - if (!rvCert) { - goto loser; - } - return rvCert; - -loser: - if (instance) { - nssCryptokiObject_Destroy(instance); - } - if (object) { - nssPKIObject_Destroy(object); - } - if (cert) { - nssCertificate_Destroy(cert); - } - return NULL; -} - -/* - * We're looking for a cert which we have the private key for that's on the - * list of recipients. This searches one slot. - * this is the new version for NSS SMIME code - * this stuff should REALLY be in the SMIME code, but some things in here are not public - * (they should be!) - */ -static CERTCertificate * -pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipientlist, int *rlIndex, void *pwarg) -{ - NSSCMSRecipient *ri = NULL; - int i; - - for (i=0; (ri = recipientlist[i]) != NULL; i++) { - CERTCertificate *cert = NULL; - /* XXXXX fixme - not yet implemented! */ - if (ri->kind == RLSubjKeyID) - continue; - cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->id.issuerAndSN, - pwarg); - if (cert) { - ri->slot = PK11_ReferenceSlot(slot); - *rlIndex = i; - return cert; - } - - } - *rlIndex = -1; - return NULL; -} - -/* - * This function is the same as above, but it searches all the slots. - * this is the new version for NSS SMIME code - * this stuff should REALLY be in the SMIME code, but some things in here are not public - * (they should be!) - */ -static CERTCertificate * -pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *wincx, int *rlIndex) -{ - PK11SlotList *list; - PK11SlotListElement *le; - CERTCertificate *cert = NULL; - SECStatus rv; - - /* get them all! */ - list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); - if (list == NULL) { - if (list) PK11_FreeSlotList(list); - return CK_INVALID_HANDLE; - } - - /* Look for the slot that holds the Key */ - for (le = list->head ; le; le = le->next) { - if ( !PK11_IsFriendly(le->slot)) { - rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); - if (rv != SECSuccess) continue; - } - - cert = pk11_FindCertObjectByRecipientNew(le->slot, - recipientlist, rlIndex, wincx); - if (cert) - break; - } - - PK11_FreeSlotList(list); - - return cert; -} - -/* - * We're looking for a cert which we have the private key for that's on the - * list of recipients. This searches one slot. - */ -static CERTCertificate * -pk11_FindCertObjectByRecipient(PK11SlotInfo *slot, - SEC_PKCS7RecipientInfo **recipientArray, - SEC_PKCS7RecipientInfo **rip, void *pwarg) -{ - SEC_PKCS7RecipientInfo *ri = NULL; - int i; - - for (i=0; (ri = recipientArray[i]) != NULL; i++) { - CERTCertificate *cert; - - cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->issuerAndSN, - pwarg); - if (cert) { - *rip = ri; - return cert; - } - - } - *rip = NULL; - return NULL; -} - -/* - * This function is the same as above, but it searches all the slots. - */ -static CERTCertificate * -pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr, - SEC_PKCS7RecipientInfo **recipientArray,SEC_PKCS7RecipientInfo **rip, - void *wincx) { - PK11SlotList *list; - PK11SlotListElement *le; - CERTCertificate * cert; - PK11SlotInfo *slot = NULL; - SECStatus rv; - - *slotPtr = NULL; - - /* get them all! */ - list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); - if (list == NULL) { - if (list) PK11_FreeSlotList(list); - return CK_INVALID_HANDLE; - } - - *rip = NULL; - - /* Look for the slot that holds the Key */ - for (le = list->head ; le; le = le->next) { - if ( !PK11_IsFriendly(le->slot)) { - rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); - if (rv != SECSuccess) continue; - } - - cert = pk11_FindCertObjectByRecipient(le->slot, recipientArray, - rip, wincx); - if (cert) { - slot = PK11_ReferenceSlot(le->slot); - break; - } - } - - PK11_FreeSlotList(list); - - if (slot == NULL) { - return NULL; - } - *slotPtr = slot; - return cert; -} - -/* - * We need to invert the search logic for PKCS 7 because if we search for - * each cert on the list over all the slots, we wind up with lots of spurious - * password prompts. This way we get only one password prompt per slot, at - * the max, and most of the time we can find the cert, and only prompt for - * the key... - */ -CERTCertificate * -PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr, - SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip, - SECKEYPrivateKey**privKey, void *wincx) -{ - CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE keyHandle = CK_INVALID_HANDLE; - CERTCertificate *cert = NULL; - SECStatus rv; - - *privKey = NULL; - *slotPtr = NULL; - cert = pk11_AllFindCertObjectByRecipient(slotPtr,array,rip,wincx); - if (!cert) { - return NULL; - } - - rv = PK11_Authenticate(*slotPtr,PR_TRUE,wincx); - if (rv != SECSuccess) { - goto loser; - } - - *privKey = PK11_FindKeyByAnyCert(cert, wincx); - if (*privKey == NULL) { - goto loser; - } - - return cert; -loser: - if (cert) CERT_DestroyCertificate(cert); - if (*slotPtr) PK11_FreeSlot(*slotPtr); - *slotPtr = NULL; - return NULL; -} - -/* - * This is the new version of the above function for NSS SMIME code - * this stuff should REALLY be in the SMIME code, but some things in here are not public - * (they should be!) - */ -int -PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *wincx) -{ - CERTCertificate *cert; - NSSCMSRecipient *rl; - int rlIndex; - - cert = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex); - if (!cert) { - return -1; - } - - rl = recipientlist[rlIndex]; - - /* at this point, rl->slot is set */ - - /* authenticate to the token */ - if (PK11_Authenticate(rl->slot, PR_TRUE, wincx) != SECSuccess) { - goto loser; - } - - rl->privkey = PK11_FindKeyByAnyCert(cert, wincx); - if (rl->privkey == NULL) { - goto loser; - } - - /* make a cert from the cert handle */ - rl->cert = cert; - return rlIndex; - -loser: - if (cert) CERT_DestroyCertificate(cert); - if (rl->slot) PK11_FreeSlot(rl->slot); - rl->slot = NULL; - return -1; -} - -CERTCertificate * -PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN, - void *wincx) -{ -#ifdef NSS_CLASSIC - CK_OBJECT_HANDLE certHandle; - CERTCertificate *cert = NULL; - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE searchTemplate[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_ISSUER, NULL, 0 }, - { CKA_SERIAL_NUMBER, NULL, 0} - }; - int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE); - CK_ATTRIBUTE *attrs = searchTemplate; - - PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++; - PK11_SETATTRS(attrs, CKA_ISSUER, issuerSN->derIssuer.data, - issuerSN->derIssuer.len); attrs++; - PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER, issuerSN->serialNumber.data, - issuerSN->serialNumber.len); - - certHandle = pk11_FindCertObjectByTemplate - (slotPtr,searchTemplate,count,wincx); - if (certHandle == CK_INVALID_HANDLE) { - return NULL; - } - cert = PK11_MakeCertFromHandle(*slotPtr,certHandle,NULL); - if (cert == NULL) { - PK11_FreeSlot(*slotPtr); - return NULL; - } - return cert; -#else - CERTCertificate *rvCert = NULL; - NSSCertificate *cert; - NSSDER issuer, serial; - NSSCryptoContext *cc; - SECItem *derSerial; - - if (slotPtr) *slotPtr = NULL; - - /* PKCS#11 needs to use DER-encoded serial numbers. Create a - * CERTIssuerAndSN that actually has the encoded value and pass that - * to PKCS#11 (and the crypto context). - */ - derSerial = SEC_ASN1EncodeItem(NULL, NULL, - &issuerSN->serialNumber, - SEC_IntegerTemplate); - if (!derSerial) { - return NULL; - } - - NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer); - NSSITEM_FROM_SECITEM(&serial, derSerial); - - cc = STAN_GetDefaultCryptoContext(); - cert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(cc, - &issuer, - &serial); - if (cert) { - SECITEM_FreeItem(derSerial, PR_TRUE); - return STAN_GetCERTCertificate(cert); - } -retry: - cert = NSSTrustDomain_FindCertificateByIssuerAndSerialNumber( - STAN_GetDefaultTrustDomain(), - &issuer, - &serial); - if (cert) { - rvCert = STAN_GetCERTCertificate(cert); - /* Check to see if the cert's token is still there */ - if (!PK11_IsPresent(rvCert->slot)) { - CERT_DestroyCertificate(rvCert); - goto retry; - } - if (slotPtr) *slotPtr = PK11_ReferenceSlot(rvCert->slot); - } - SECITEM_FreeItem(derSerial, PR_TRUE); - return rvCert; -#endif -} - -CK_OBJECT_HANDLE -PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot) -{ - CK_OBJECT_HANDLE certHandle; - CK_ATTRIBUTE searchTemplate = { CKA_VALUE, NULL, 0 }; - - PK11_SETATTRS(&searchTemplate, CKA_VALUE, cert->derCert.data, - cert->derCert.len); - - if (cert->slot) { - certHandle = pk11_getcerthandle(cert->slot,cert,&searchTemplate,1); - if (certHandle != CK_INVALID_HANDLE) { - *pSlot = PK11_ReferenceSlot(cert->slot); - return certHandle; - } - } - - certHandle = pk11_FindCertObjectByTemplate(pSlot,&searchTemplate,1,wincx); - if (certHandle != CK_INVALID_HANDLE) { - if (cert->slot == NULL) { - cert->slot = PK11_ReferenceSlot(*pSlot); - cert->pkcs11ID = certHandle; - cert->ownSlot = PR_TRUE; - cert->series = cert->slot->series; - } - } - - return(certHandle); -} - -SECKEYPrivateKey * -PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx) -{ - CK_OBJECT_HANDLE certHandle; - CK_OBJECT_HANDLE keyHandle; - PK11SlotInfo *slot = NULL; - SECKEYPrivateKey *privKey; - SECStatus rv; - - certHandle = PK11_FindObjectForCert(cert, wincx, &slot); - if (certHandle == CK_INVALID_HANDLE) { - return NULL; - } - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) { - PK11_FreeSlot(slot); - return NULL; - } - keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY); - if (keyHandle == CK_INVALID_HANDLE) { - PK11_FreeSlot(slot); - return NULL; - } - privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx); - PK11_FreeSlot(slot); - return privKey; -} - -CK_OBJECT_HANDLE -pk11_FindPubKeyByAnyCert(CERTCertificate *cert, PK11SlotInfo **slot, void *wincx) -{ - CK_OBJECT_HANDLE certHandle; - CK_OBJECT_HANDLE keyHandle; - - certHandle = PK11_FindObjectForCert(cert, wincx, slot); - if (certHandle == CK_INVALID_HANDLE) { - return CK_INVALID_HANDLE; - } - keyHandle = PK11_MatchItem(*slot,certHandle,CKO_PUBLIC_KEY); - if (keyHandle == CK_INVALID_HANDLE) { - PK11_FreeSlot(*slot); - return CK_INVALID_HANDLE; - } - return keyHandle; -} - -SECKEYPrivateKey * -PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx) -{ - CK_OBJECT_HANDLE keyHandle; - SECKEYPrivateKey *privKey; - - keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID); - if (keyHandle == CK_INVALID_HANDLE) { - return NULL; - } - privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx); - return privKey; -} - -/* - * find the number of certs in the slot with the same subject name - */ -int -PK11_NumberCertsForCertSubject(CERTCertificate *cert) -{ - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, - }; - CK_ATTRIBUTE *attr = theTemplate; - int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]); - - PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++; - PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len); - - if (cert->slot == NULL) { - PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, - PR_FALSE,PR_TRUE,NULL); - PK11SlotListElement *le; - int count = 0; - - /* loop through all the fortezza tokens */ - for (le = list->head; le; le = le->next) { - count += PK11_NumberObjectsFor(le->slot,theTemplate,templateSize); - } - PK11_FreeSlotList(list); - return count; - } - - return PK11_NumberObjectsFor(cert->slot,theTemplate,templateSize); -} - -/* - * Walk all the certs with the same subject - */ -SECStatus -PK11_TraverseCertsForSubject(CERTCertificate *cert, - SECStatus(* callback)(CERTCertificate*, void *), void *arg) -{ - if(!cert) { - return SECFailure; - } - if (cert->slot == NULL) { - PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, - PR_FALSE,PR_TRUE,NULL); - PK11SlotListElement *le; - - /* loop through all the fortezza tokens */ - for (le = list->head; le; le = le->next) { - PK11_TraverseCertsForSubjectInSlot(cert,le->slot,callback,arg); - } - PK11_FreeSlotList(list); - return SECSuccess; - - } - - return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg); -} - -SECStatus -PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, - SECStatus(* callback)(CERTCertificate*, void *), void *arg) -{ -#ifdef NSS_CLASSIC - pk11DoCertCallback caller; - pk11TraverseSlot callarg; - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, - }; - CK_ATTRIBUTE *attr = theTemplate; - int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]); - - PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++; - PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len); - - if (slot == NULL) { - return SECSuccess; - } - caller.noslotcallback = callback; - caller.callback = NULL; - caller.itemcallback = NULL; - caller.callbackArg = arg; - callarg.callback = pk11_DoCerts; - callarg.callbackArg = (void *) & caller; - callarg.findTemplate = theTemplate; - callarg.templateCount = templateSize; - - return PK11_TraverseSlot(slot, &callarg); -#else - PRStatus nssrv = PR_SUCCESS; - NSSToken *token; - NSSDER subject; - NSSTrustDomain *td; - nssList *subjectList; - nssPKIObjectCollection *collection; - nssCryptokiObject **instances; - NSSCertificate **certs; - nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; - td = STAN_GetDefaultTrustDomain(); - NSSITEM_FROM_SECITEM(&subject, &cert->derSubject); - token = PK11Slot_GetNSSToken(slot); - if (!nssToken_IsPresent(token)) { - return SECSuccess; - } - collection = nssCertificateCollection_Create(td, NULL); - if (!collection) { - return SECFailure; - } - subjectList = nssList_Create(NULL, PR_FALSE); - if (!subjectList) { - nssPKIObjectCollection_Destroy(collection); - return SECFailure; - } - (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, - subjectList); - transfer_token_certs_to_collection(subjectList, token, collection); - instances = nssToken_FindCertificatesBySubject(token, NULL, - &subject, - tokenOnly, 0, &nssrv); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - nssList_Destroy(subjectList); - certs = nssPKIObjectCollection_GetCertificates(collection, - NULL, 0, NULL); - nssPKIObjectCollection_Destroy(collection); - if (certs) { - CERTCertificate *oldie; - NSSCertificate **cp; - for (cp = certs; *cp; cp++) { - oldie = STAN_GetCERTCertificate(*cp); - if ((*callback)(oldie, arg) != SECSuccess) { - nssrv = PR_FAILURE; - break; - } - } - nssCertificateArray_Destroy(certs); - } - return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; -#endif -} - -SECStatus -PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, - SECStatus(* callback)(CERTCertificate*, void *), void *arg) -{ -#ifdef NSS_CLASSIC - pk11DoCertCallback caller; - pk11TraverseSlot callarg; - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_LABEL, NULL, 0 }, - }; - CK_ATTRIBUTE *attr = theTemplate; - int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]); - - if(!nickname) { - return SECSuccess; - } - - PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++; - PK11_SETATTRS(attr,CKA_LABEL,nickname->data,nickname->len); - - if (slot == NULL) { - return SECSuccess; - } - - caller.noslotcallback = callback; - caller.callback = NULL; - caller.itemcallback = NULL; - caller.callbackArg = arg; - callarg.callback = pk11_DoCerts; - callarg.callbackArg = (void *) & caller; - callarg.findTemplate = theTemplate; - callarg.templateCount = templateSize; - - return PK11_TraverseSlot(slot, &callarg); -#else - struct nss3_cert_cbstr pk11cb; - PRStatus nssrv = PR_SUCCESS; - NSSToken *token; - NSSTrustDomain *td; - NSSUTF8 *nick; - PRBool created = PR_FALSE; - nssCryptokiObject **instances; - nssPKIObjectCollection *collection = NULL; - NSSCertificate **certs; - nssList *nameList = NULL; - nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; - pk11cb.callback = callback; - pk11cb.arg = arg; - token = PK11Slot_GetNSSToken(slot); - if (!nssToken_IsPresent(token)) { - return SECSuccess; - } - if (nickname->data[nickname->len-1] != '\0') { - nick = nssUTF8_Create(NULL, nssStringType_UTF8String, - nickname->data, nickname->len); - created = PR_TRUE; - } else { - nick = (NSSUTF8 *)nickname->data; - } - td = STAN_GetDefaultTrustDomain(); - collection = nssCertificateCollection_Create(td, NULL); - if (!collection) { - goto loser; - } - nameList = nssList_Create(NULL, PR_FALSE); - if (!nameList) { - goto loser; - } - (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList); - transfer_token_certs_to_collection(nameList, token, collection); - instances = nssToken_FindCertificatesByNickname(token, NULL, - nick, - tokenOnly, 0, &nssrv); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - nssList_Destroy(nameList); - certs = nssPKIObjectCollection_GetCertificates(collection, - NULL, 0, NULL); - nssPKIObjectCollection_Destroy(collection); - if (certs) { - CERTCertificate *oldie; - NSSCertificate **cp; - for (cp = certs; *cp; cp++) { - oldie = STAN_GetCERTCertificate(*cp); - if ((*callback)(oldie, arg) != SECSuccess) { - nssrv = PR_FAILURE; - break; - } - } - nssCertificateArray_Destroy(certs); - } - if (created) nss_ZFreeIf(nick); - return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; -loser: - if (created) { - nss_ZFreeIf(nick); - } - if (collection) { - nssPKIObjectCollection_Destroy(collection); - } - if (nameList) { - nssList_Destroy(nameList); - } - return SECFailure; -#endif -} - -SECStatus -PK11_TraverseCertsInSlot(PK11SlotInfo *slot, - SECStatus(* callback)(CERTCertificate*, void *), void *arg) -{ -#ifdef NSS_CLASSIC - pk11DoCertCallback caller; - pk11TraverseSlot callarg; - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_CLASS, NULL, 0 }, - }; - CK_ATTRIBUTE *attr = theTemplate; - int templateSize = sizeof(theTemplate)/sizeof(theTemplate[0]); - - PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++; - - if (slot == NULL) { - return SECSuccess; - } - - caller.noslotcallback = callback; - caller.callback = NULL; - caller.itemcallback = NULL; - caller.callbackArg = arg; - callarg.callback = pk11_DoCerts; - callarg.callbackArg = (void *) & caller; - callarg.findTemplate = theTemplate; - callarg.templateCount = templateSize; - return PK11_TraverseSlot(slot, &callarg); -#else - PRStatus nssrv; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - NSSToken *tok; - nssList *certList = NULL; - nssCryptokiObject **instances; - nssPKIObjectCollection *collection; - NSSCertificate **certs; - nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; - tok = PK11Slot_GetNSSToken(slot); - if (!nssToken_IsPresent(tok)) { - return SECSuccess; - } - collection = nssCertificateCollection_Create(td, NULL); - if (!collection) { - return SECFailure; - } - certList = nssList_Create(NULL, PR_FALSE); - if (!certList) { - nssPKIObjectCollection_Destroy(collection); - return SECFailure; - } - (void *)nssTrustDomain_GetCertsFromCache(td, certList); - transfer_token_certs_to_collection(certList, tok, collection); - instances = nssToken_FindCertificates(tok, NULL, - tokenOnly, 0, &nssrv); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - nssList_Destroy(certList); - certs = nssPKIObjectCollection_GetCertificates(collection, - NULL, 0, NULL); - nssPKIObjectCollection_Destroy(collection); - if (certs) { - CERTCertificate *oldie; - NSSCertificate **cp; - for (cp = certs; *cp; cp++) { - oldie = STAN_GetCERTCertificate(*cp); - if ((*callback)(oldie, arg) != SECSuccess) { - nssrv = PR_FAILURE; - break; - } - } - nssCertificateArray_Destroy(certs); - } - return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; -#endif -} - -/* - * return the certificate associated with a derCert - */ -CERTCertificate * -PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert, - void *wincx) -{ -#ifdef NSS_CLASSIC - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_VALUE, NULL, 0 }, - { CKA_CLASS, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_OBJECT_HANDLE certh; - CK_ATTRIBUTE *attrs = theTemplate; - SECStatus rv; - - PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, - cert->derCert.len); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); - - /* - * issue the find - */ - if ( !PK11_IsFriendly(slot)) { - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) return NULL; - } - - certh = pk11_getcerthandle(slot,cert,theTemplate,tsize); - if (certh == CK_INVALID_HANDLE) { - return NULL; - } - return PK11_MakeCertFromHandle(slot, certh, NULL); -#else - CERTCertificate *rvCert = NULL; - NSSCertificate *c; - NSSDER derCert; - NSSToken *tok; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - tok = PK11Slot_GetNSSToken(slot); - NSSITEM_FROM_SECITEM(&derCert, &cert->derCert); - if (!PK11_IsFriendly(slot)) { - if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { - PK11_FreeSlot(slot); - return NULL; - } - } - c = NSSTrustDomain_FindCertificateByEncodedCertificate(td, &derCert); - if (c) { - PRBool isToken = PR_FALSE; - NSSToken **tp; - NSSToken **tokens = nssPKIObject_GetTokens(&c->object, NULL); - if (tokens) { - for (tp = tokens; *tp; tp++) { - if (*tp == tok) { - isToken = PR_TRUE; - break; - } - } - if (!isToken) { - NSSCertificate_Destroy(c); - c = NULL; - } - nssTokenArray_Destroy(tokens); - } - } - if (c) { - rvCert = STAN_GetCERTCertificate(c); - } - return rvCert; -#endif -} - -/* mcgreer 3.4 -- nobody uses this, ignoring */ -/* - * return the certificate associated with a derCert - */ -CERTCertificate * -PK11_FindCertFromDERSubjectAndNickname(PK11SlotInfo *slot, - CERTCertificate *cert, - char *nickname, void *wincx) -{ - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_SUBJECT, NULL, 0 }, - { CKA_LABEL, NULL, 0 }, - { CKA_CLASS, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_OBJECT_HANDLE certh; - CK_ATTRIBUTE *attrs = theTemplate; - SECStatus rv; - - PK11_SETATTRS(attrs, CKA_SUBJECT, cert->derSubject.data, - cert->derSubject.len); attrs++; - PK11_SETATTRS(attrs, CKA_LABEL, nickname, PORT_Strlen(nickname)); - PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); - - /* - * issue the find - */ - if ( !PK11_IsFriendly(slot)) { - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) return NULL; - } - - certh = pk11_getcerthandle(slot,cert,theTemplate,tsize); - if (certh == CK_INVALID_HANDLE) { - return NULL; - } - - return PK11_MakeCertFromHandle(slot, certh, NULL); -} - -/* - * import a cert for a private key we have already generated. Set the label - * on both to be the nickname. - */ -static CK_OBJECT_HANDLE -pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, - void *wincx) -{ - SECItem *keyID; - CK_OBJECT_HANDLE key; - SECStatus rv; - - if((slot == NULL) || (cert == NULL)) { - return CK_INVALID_HANDLE; - } - - keyID = pk11_mkcertKeyID(cert); - if(keyID == NULL) { - return CK_INVALID_HANDLE; - } - - key = CK_INVALID_HANDLE; - - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) goto loser; - - key = pk11_FindPrivateKeyFromCertID(slot, keyID); - -loser: - SECITEM_ZfreeItem(keyID, PR_TRUE); - return key; -} - -SECKEYPrivateKey * -PK11_FindKeyByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, - void *wincx) -{ - CK_OBJECT_HANDLE keyHandle; - - if((slot == NULL) || (cert == NULL)) { - return NULL; - } - - keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx); - if (keyHandle == CK_INVALID_HANDLE) { - return NULL; - } - - return PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,wincx); -} - -SECStatus -PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert, - char *nickname, - PRBool addCertUsage,void *wincx) -{ - CK_OBJECT_HANDLE keyHandle; - - if((slot == NULL) || (cert == NULL) || (nickname == NULL)) { - return SECFailure; - } - - keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx); - if (keyHandle == CK_INVALID_HANDLE) { - return SECFailure; - } - - return PK11_ImportCert(slot, cert, keyHandle, nickname, addCertUsage); -} - - -/* remove when the real version comes out */ -#define SEC_OID_MISSI_KEA 300 /* until we have v3 stuff merged */ -PRBool -KEAPQGCompare(CERTCertificate *server,CERTCertificate *cert) { - - if ( SECKEY_KEAParamCompare(server,cert) == SECEqual ) { - return PR_TRUE; - } else { - return PR_FALSE; - } -} - -PRBool -PK11_FortezzaHasKEA(CERTCertificate *cert) { - /* look at the subject and see if it is a KEA for MISSI key */ - SECOidData *oid; - - if ((cert->trust == NULL) || - ((cert->trust->sslFlags & CERTDB_USER) != CERTDB_USER)) { - return PR_FALSE; - } - - oid = SECOID_FindOID(&cert->subjectPublicKeyInfo.algorithm.algorithm); - - - return (PRBool)((oid->offset == SEC_OID_MISSI_KEA_DSS_OLD) || - (oid->offset == SEC_OID_MISSI_KEA_DSS) || - (oid->offset == SEC_OID_MISSI_KEA)) ; -} - -/* - * Find a kea cert on this slot that matches the domain of it's peer - */ -static CERTCertificate -*pk11_GetKEAMate(PK11SlotInfo *slot,CERTCertificate *peer) -{ - int i; - CERTCertificate *returnedCert = NULL; - - for (i=0; i < slot->cert_count; i++) { - CERTCertificate *cert = slot->cert_array[i]; - - if (PK11_FortezzaHasKEA(cert) && KEAPQGCompare(peer,cert)) { - returnedCert = CERT_DupCertificate(cert); - break; - } - } - return returnedCert; -} - -/* - * The following is a FORTEZZA only Certificate request. We call this when we - * are doing a non-client auth SSL connection. We are only interested in the - * fortezza slots, and we are only interested in certs that share the same root - * key as the server. - */ -CERTCertificate * -PK11_FindBestKEAMatch(CERTCertificate *server, void *wincx) -{ - PK11SlotList *keaList = PK11_GetAllTokens(CKM_KEA_KEY_DERIVE, - PR_FALSE,PR_TRUE,wincx); - PK11SlotListElement *le; - CERTCertificate *returnedCert = NULL; - SECStatus rv; - - /* loop through all the fortezza tokens */ - for (le = keaList->head; le; le = le->next) { - rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); - if (rv != SECSuccess) continue; - if (le->slot->session == CK_INVALID_SESSION) { - continue; - } - returnedCert = pk11_GetKEAMate(le->slot,server); - if (returnedCert) break; - } - PK11_FreeSlotList(keaList); - - return returnedCert; -} - -/* - * find a matched pair of kea certs to key exchange parameters from one - * fortezza card to another as necessary. - */ -SECStatus -PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1, PK11SlotInfo *slot2, - CERTCertificate **cert1, CERTCertificate **cert2) -{ - CERTCertificate *returnedCert = NULL; - int i; - - for (i=0; i < slot1->cert_count; i++) { - CERTCertificate *cert = slot1->cert_array[i]; - - if (PK11_FortezzaHasKEA(cert)) { - returnedCert = pk11_GetKEAMate(slot2,cert); - if (returnedCert != NULL) { - *cert2 = returnedCert; - *cert1 = CERT_DupCertificate(cert); - return SECSuccess; - } - } - } - return SECFailure; -} - -SECOidTag -PK11_FortezzaMapSig(SECOidTag algTag) -{ - switch (algTag) { - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_DSS: - case SEC_OID_MISSI_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - return SEC_OID_ANSIX9_DSA_SIGNATURE; - default: - break; - } - return algTag; -} - -/* - * return the private key From a given Cert - */ -CK_OBJECT_HANDLE -PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx) -{ - CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_VALUE, NULL, 0 }, - { CKA_CLASS, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_ATTRIBUTE *attrs = theTemplate; - SECStatus rv; - - PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, - cert->derCert.len); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); - - /* - * issue the find - */ - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) { - return CK_INVALID_HANDLE; - } - - return pk11_getcerthandle(slot,cert,theTemplate,tsize); -} - -SECItem * -PK11_GetKeyIDFromCert(CERTCertificate *cert, void *wincx) -{ - CK_OBJECT_HANDLE handle; - PK11SlotInfo *slot = NULL; - CK_ATTRIBUTE theTemplate[] = { - { CKA_ID, NULL, 0 }, - }; - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - SECItem *item = NULL; - CK_RV crv; - - handle = PK11_FindObjectForCert(cert,wincx,&slot); - if (handle == CK_INVALID_HANDLE) { - goto loser; - } - - - crv = PK11_GetAttributes(NULL,slot,handle,theTemplate,tsize); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - goto loser; - } - - item = PORT_ZNew(SECItem); - if (item) { - item->data = theTemplate[0].pValue; - item->len = theTemplate[0].ulValueLen; - } - - -loser: - PK11_FreeSlot(slot); - return item; -} - -SECItem * -PK11_GetKeyIDFromPrivateKey(SECKEYPrivateKey *key, void *wincx) -{ - CK_ATTRIBUTE theTemplate[] = { - { CKA_ID, NULL, 0 }, - }; - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - SECItem *item = NULL; - CK_RV crv; - - crv = PK11_GetAttributes(NULL,key->pkcs11Slot,key->pkcs11ID, - theTemplate,tsize); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - goto loser; - } - - item = PORT_ZNew(SECItem); - if (item) { - item->data = theTemplate[0].pValue; - item->len = theTemplate[0].ulValueLen; - } - - -loser: - return item; -} - -struct listCertsStr { - PK11CertListType type; - CERTCertList *certList; -}; - -static PRBool -isOnList(CERTCertList *certList,NSSCertificate *c) -{ - CERTCertListNode *cln; - - for (cln = CERT_LIST_HEAD(certList); !CERT_LIST_END(cln,certList); - cln = CERT_LIST_NEXT(cln)) { - if (cln->cert->nssCertificate == c) { - return PR_TRUE; - } - } - return PR_FALSE; -} -static PRStatus -pk11ListCertCallback(NSSCertificate *c, void *arg) -{ - struct listCertsStr *listCertP = (struct listCertsStr *)arg; - CERTCertificate *newCert = NULL; - PK11CertListType type = listCertP->type; - CERTCertList *certList = listCertP->certList; - PRBool isUnique = PR_FALSE; - PRBool isCA = PR_FALSE; - char *nickname = NULL; - unsigned int certType; - - if ((type == PK11CertListUnique) || (type == PK11CertListRootUnique)) { - isUnique = PR_TRUE; - } - if ((type == PK11CertListCA) || (type == PK11CertListRootUnique)) { - isCA = PR_TRUE; - } - - - /* if we want user certs and we don't have one skip this cert */ - if ((type == PK11CertListUser) && - !NSSCertificate_IsPrivateKeyAvailable(c, NULL,NULL)) { - return PR_SUCCESS; - } - - /* if we want root certs, skip the user certs */ - if ((type == PK11CertListRootUnique) && - NSSCertificate_IsPrivateKeyAvailable(c, NULL,NULL)) { - return PR_SUCCESS; - } - - /* if we want Unique certs and we already have it on our list, skip it */ - if ( isUnique && isOnList(certList,c) ) { - return PR_SUCCESS; - } - - - newCert = STAN_GetCERTCertificate(c); - if (!newCert) { - return PR_SUCCESS; - } - /* if we want CA certs and it ain't one, skip it */ - if( isCA && (!CERT_IsCACert(newCert, &certType)) ) { - return PR_SUCCESS; - } - CERT_DupCertificate(newCert); - - nickname = STAN_GetCERTCertificateName(c); - - /* put slot certs at the end */ - if (newCert->slot && !PK11_IsInternal(newCert->slot)) { - CERT_AddCertToListTailWithData(certList,newCert,nickname); - } else { - CERT_AddCertToListHeadWithData(certList,newCert,nickname); - } - return PR_SUCCESS; -} - - -CERTCertList * -PK11_ListCerts(PK11CertListType type, void *pwarg) -{ -#ifdef NSS_CLASSIC - CERTCertList *certList = NULL; - struct listCertsStr listCerts; - - certList= CERT_NewCertList(); - listCerts.type = type; - listCerts.certList = certList; - - PK11_TraverseSlotCerts(pk11ListCertCallback,&listCerts,pwarg); - - if (CERT_LIST_HEAD(certList) == NULL) { - CERT_DestroyCertList(certList); - certList = NULL; - } - return certList; -#else - NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); - CERTCertList *certList = NULL; - struct listCertsStr listCerts; - certList = CERT_NewCertList(); - listCerts.type = type; - listCerts.certList = certList; - - /* authenticate to the slots */ - (void) pk11_TraverseAllSlots( NULL, NULL, pwarg); - NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback, - &listCerts); - return certList; -#endif -} - -static SECItem * -pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle) { - CK_ATTRIBUTE theTemplate[] = { - { CKA_ID, NULL, 0 }, - }; - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_RV crv; - SECItem *item; - - item = SECITEM_AllocItem(NULL, NULL, 0); - - if (item == NULL) { - return NULL; - } - - crv = PK11_GetAttributes(NULL,slot,handle,theTemplate,tsize); - if (crv != CKR_OK) { - SECITEM_FreeItem(item,PR_TRUE); - PORT_SetError( PK11_MapError(crv) ); - return NULL; - } - - item->data = theTemplate[0].pValue; - item->len =theTemplate[0].ulValueLen; - - return item; -} - -SECItem * -PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot, - CERTCertificate *cert, void *wincx) -{ - CK_ATTRIBUTE theTemplate[] = { - { CKA_VALUE, NULL, 0 }, - { CKA_CLASS, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_OBJECT_HANDLE certHandle; - CK_ATTRIBUTE *attrs = theTemplate; - PK11SlotInfo *slotRef = NULL; - SECItem *item; - SECStatus rv; - - if (slot) { - PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, - cert->derCert.len); attrs++; - - rv = PK11_Authenticate(slot, PR_TRUE, wincx); - if (rv != SECSuccess) { - return NULL; - } - certHandle = pk11_getcerthandle(slot,cert,theTemplate,tsize); - } else { - certHandle = PK11_FindObjectForCert(cert, wincx, &slotRef); - if (certHandle == CK_INVALID_HANDLE) { - return pk11_mkcertKeyID(cert); - } - slot = slotRef; - } - - if (certHandle == CK_INVALID_HANDLE) { - return NULL; - } - - item = pk11_GetLowLevelKeyFromHandle(slot,certHandle); - if (slotRef) PK11_FreeSlot(slotRef); - return item; -} - -SECItem * -PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *privKey) -{ - return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot,privKey->pkcs11ID); -} - -static SECStatus -listCertsCallback(CERTCertificate* cert, void*arg) -{ - CERTCertList *list = (CERTCertList*)arg; - char *nickname = NULL; - - if (cert->nickname) { - nickname = PORT_ArenaStrdup(list->arena,cert->nickname); - } - - return CERT_AddCertToListTailWithData(list, - CERT_DupCertificate(cert),nickname); -} - -CERTCertList * -PK11_ListCertsInSlot(PK11SlotInfo *slot) -{ - SECStatus status; - CERTCertList *certs; - - certs = CERT_NewCertList(); - if(certs == NULL) return NULL; - - status = PK11_TraverseCertsInSlot(slot, listCertsCallback, - (void*)certs); - - if( status != SECSuccess ) { - CERT_DestroyCertList(certs); - certs = NULL; - } - - return certs; -} - -static SECStatus -privateKeyListCallback(SECKEYPrivateKey *key, void *arg) -{ - SECKEYPrivateKeyList *list = (SECKEYPrivateKeyList*)arg; - return SECKEY_AddPrivateKeyToListTail(list, SECKEY_CopyPrivateKey(key)); -} - -SECKEYPrivateKeyList* -PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot) -{ - SECStatus status; - SECKEYPrivateKeyList *keys; - - keys = SECKEY_NewPrivateKeyList(); - if(keys == NULL) return NULL; - - status = PK11_TraversePrivateKeysInSlot(slot, privateKeyListCallback, - (void*)keys); - - if( status != SECSuccess ) { - SECKEY_DestroyPrivateKeyList(keys); - keys = NULL; - } - - return keys; -} - -SECKEYPublicKeyList* -PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname) -{ - CK_ATTRIBUTE findTemp[4]; - CK_ATTRIBUTE *attrs; - CK_BBOOL ckTrue = CK_TRUE; - CK_OBJECT_CLASS keyclass = CKO_PUBLIC_KEY; - int tsize = 0; - int objCount = 0; - CK_OBJECT_HANDLE *key_ids; - SECKEYPublicKeyList *keys; - int i,len; - - - attrs = findTemp; - PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; - if (nickname) { - len = PORT_Strlen(nickname)-1; - PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++; - } - tsize = attrs - findTemp; - PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); - - key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount); - if (key_ids == NULL) { - return NULL; - } - keys = SECKEY_NewPublicKeyList(); - if (keys == NULL) { - PORT_Free(key_ids); - } - - for (i=0; i < objCount ; i++) { - SECKEYPublicKey *pubKey = - PK11_ExtractPublicKey(slot,nullKey,key_ids[i]); - if (pubKey) { - SECKEY_AddPublicKeyToListTail(keys, pubKey); - } - } - - PORT_Free(key_ids); - return keys; -} - -SECKEYPrivateKeyList* -PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) -{ - CK_ATTRIBUTE findTemp[4]; - CK_ATTRIBUTE *attrs; - CK_BBOOL ckTrue = CK_TRUE; - CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY; - int tsize = 0; - int objCount = 0; - CK_OBJECT_HANDLE *key_ids; - SECKEYPrivateKeyList *keys; - int i,len; - - - attrs = findTemp; - PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; - if (nickname) { - len = PORT_Strlen(nickname)-1; - PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++; - } - tsize = attrs - findTemp; - PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); - - key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount); - if (key_ids == NULL) { - return NULL; - } - keys = SECKEY_NewPrivateKeyList(); - if (keys == NULL) { - PORT_Free(key_ids); - } - - for (i=0; i < objCount ; i++) { - SECKEYPrivateKey *privKey = - PK11_MakePrivKey(slot,nullKey,PR_TRUE,key_ids[i],wincx); - SECKEY_AddPrivateKeyToListTail(keys, privKey); - } - - PORT_Free(key_ids); - return keys; -} - -/* - * return the certificate associated with a derCert - */ -SECItem * -PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, - SECItem *name, int type, char **url) -{ -#ifdef NSS_CLASSIC - CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL; - CK_ATTRIBUTE theTemplate[] = { - { CKA_SUBJECT, NULL, 0 }, - { CKA_CLASS, NULL, 0 }, - { CKA_NETSCAPE_KRL, NULL, 0 }, - }; - CK_ATTRIBUTE crlData[] = { - { CKA_VALUE, NULL, 0 }, - { CKA_NETSCAPE_URL, NULL, 0 }, - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_BBOOL ck_true = CK_TRUE; - CK_BBOOL ck_false = CK_FALSE; - CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE; - CK_ATTRIBUTE *attrs = theTemplate; - CK_RV crv; - SECItem *derCrl = NULL; - - PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++; - PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ? - &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++; - - if (*slot) { - crlh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize); - } else { - PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, - PR_FALSE,PR_TRUE,NULL); - PK11SlotListElement *le; - - /* loop through all the fortezza tokens */ - for (le = list->head; le; le = le->next) { - crlh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize); - if (crlh != CK_INVALID_HANDLE) { - *slot = PK11_ReferenceSlot(le->slot); - break; - } - } - PK11_FreeSlotList(list); - } - - if (crlh == CK_INVALID_HANDLE) { - PORT_SetError(SEC_ERROR_NO_KRL); - return NULL; - } - crv = PK11_GetAttributes(NULL,*slot,crlh,crlData,2); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError (crv)); - goto loser; - } - - derCrl = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if (derCrl == NULL) { - goto loser; - } - - derCrl->data = crlData[0].pValue; - derCrl->len = crlData[0].ulValueLen; - - if (crlHandle) { - *crlHandle = crlh; - } - - if ((url) && crlData[1].ulValueLen != 0) { - /* make sure it's a null terminated string */ - *url = PORT_ZAlloc (crlData[1].ulValueLen+1); - if (*url) { - PORT_Memcpy(*url,crlData[1].pValue,crlData[1].ulValueLen); - } - } - - -loser: - if (!derCrl) { - if (crlData[0].pValue) PORT_Free(crlData[0].pValue); - } - if (crlData[1].pValue) PORT_Free(crlData[1].pValue); - return derCrl; -#else - NSSCRL **crls, **crlp, *crl; - NSSDER subject; - SECItem *rvItem; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - NSSITEM_FROM_SECITEM(&subject, name); - if (*slot) { - nssCryptokiObject **instances; - nssPKIObjectCollection *collection; - nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; - NSSToken *token = PK11Slot_GetNSSToken(*slot); - collection = nssCRLCollection_Create(td, NULL); - if (!collection) { - return NULL; - } - instances = nssToken_FindCRLsBySubject(token, NULL, &subject, - tokenOnly, 0, NULL); - nssPKIObjectCollection_AddInstances(collection, instances, 0); - nss_ZFreeIf(instances); - crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL); - nssPKIObjectCollection_Destroy(collection); - } else { - crls = nssTrustDomain_FindCRLsBySubject(td, &subject); - } - if (!crls) { - return NULL; - } - crl = NULL; - for (crlp = crls; *crlp; crlp++) { - if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) || - ((*crlp)->isKRL && type != SEC_CRL_TYPE)) - { - crl = nssCRL_AddRef(*crlp); - break; - } - } - nssCRLArray_Destroy(crls); - if (!crl) { - return NULL; - } - *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot); - *crlHandle = crl->object.instances[0]->handle; - if (crl->url) { - *url = PORT_Strdup(crl->url); - } - rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size); - if (!rvItem) { - PORT_Free(*url); - nssCRL_Destroy(crl); - return NULL; - } - memcpy(rvItem->data, crl->encoding.data, crl->encoding.size); - nssCRL_Destroy(crl); - return rvItem; -#endif -} - -CK_OBJECT_HANDLE -PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name, - char *url, int type) -{ -#ifdef NSS_CLASSIC - CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL; - CK_ATTRIBUTE theTemplate[] = { - { CKA_SUBJECT, NULL, 0 }, - { CKA_CLASS, NULL, 0 }, - { CKA_NETSCAPE_KRL, NULL, 0 }, - { CKA_NETSCAPE_URL, NULL, 0 }, - { CKA_VALUE, NULL, 0 }, - { CKA_TOKEN, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - int tsize; - CK_BBOOL ck_true = CK_TRUE; - CK_BBOOL ck_false = CK_FALSE; - CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE; - CK_ATTRIBUTE *attrs = theTemplate; - CK_SESSION_HANDLE rwsession; - CK_RV crv; - - PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++; - PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ? - &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++; - if (url) { - PK11_SETATTRS(attrs, CKA_NETSCAPE_URL, url, PORT_Strlen(url)+1); attrs++; - } - PK11_SETATTRS(attrs, CKA_VALUE,crl->data,crl->len); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true,sizeof(CK_BBOOL)); attrs++; - - tsize = attrs - &theTemplate[0]; - PORT_Assert(tsize <= sizeof(theTemplate)/sizeof(theTemplate[0])); - - rwsession = PK11_GetRWSession(slot); - if (rwsession == CK_INVALID_SESSION) { - PORT_SetError(SEC_ERROR_READ_ONLY); - return crlh; - } - - crv = PK11_GETTAB(slot)-> - C_CreateObject(rwsession,theTemplate,tsize,&crlh); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - } - - PK11_RestoreROSession(slot,rwsession); - - return crlh; -#else - NSSItem derCRL, derSubject; - NSSToken *token = PK11Slot_GetNSSToken(slot); - nssCryptokiObject *object; - PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE; - CK_OBJECT_HANDLE rvH; - - NSSITEM_FROM_SECITEM(&derSubject, name); - NSSITEM_FROM_SECITEM(&derCRL, crl); - - object = nssToken_ImportCRL(token, NULL, - &derSubject, &derCRL, isKRL, url, PR_TRUE); - - if (object) { - rvH = object->handle; - nssCryptokiObject_Destroy(object); - } else { - rvH = CK_INVALID_HANDLE; - } - return rvH; -#endif -} - - -/* - * delete a crl. - */ -SECStatus -SEC_DeletePermCRL(CERTSignedCrl *crl) -{ -#ifdef NSS_CLASSIC - PK11SlotInfo *slot = crl->slot; - CK_RV crv; - - if (slot == NULL) { - /* shouldn't happen */ - PORT_SetError( SEC_ERROR_CRL_INVALID); - return SECFailure; - } - - crv = PK11_DestroyTokenObject(slot,crl->pkcs11ID); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - crl->slot = NULL; - PK11_FreeSlot(slot); - return SECSuccess; -#else - PRStatus status; - NSSToken *token; - nssCryptokiObject *object; - PK11SlotInfo *slot = crl->slot; - - if (slot == NULL) { - /* shouldn't happen */ - PORT_SetError( SEC_ERROR_CRL_INVALID); - return SECFailure; - } - token = PK11Slot_GetNSSToken(slot); - - object = nss_ZNEW(NULL, nssCryptokiObject); - object->token = nssToken_AddRef(token); - object->handle = crl->pkcs11ID; - object->isTokenObject = PR_TRUE; - - status = nssToken_DeleteStoredObject(object); - - nssCryptokiObject_Destroy(object); - return (status == PR_SUCCESS) ? SECSuccess : SECFailure; -#endif -} - -/* - * return the certificate associated with a derCert - */ -SECItem * -PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr, - SECItem *name, SECItem **profileTime) -{ - CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME; - CK_ATTRIBUTE theTemplate[] = { - { CKA_SUBJECT, NULL, 0 }, - { CKA_CLASS, NULL, 0 }, - { CKA_NETSCAPE_EMAIL, NULL, 0 }, - }; - CK_ATTRIBUTE smimeData[] = { - { CKA_SUBJECT, NULL, 0 }, - { CKA_VALUE, NULL, 0 }, - }; - /* if you change the array, change the variable below as well */ - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE; - CK_ATTRIBUTE *attrs = theTemplate; - CK_RV crv; - SECItem *emailProfile = NULL; - - PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++; - PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr)); - attrs++; - - if (*slot) { - smimeh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize); - } else { - PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, - PR_FALSE,PR_TRUE,NULL); - PK11SlotListElement *le; - - /* loop through all the fortezza tokens */ - for (le = list->head; le; le = le->next) { - smimeh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize); - if (smimeh != CK_INVALID_HANDLE) { - *slot = PK11_ReferenceSlot(le->slot); - break; - } - } - PK11_FreeSlotList(list); - } - - if (smimeh == CK_INVALID_HANDLE) { - PORT_SetError(SEC_ERROR_NO_KRL); - return NULL; - } - - if (profileTime) { - PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0); - } - - crv = PK11_GetAttributes(NULL,*slot,smimeh,smimeData,2); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError (crv)); - goto loser; - } - - if (!profileTime) { - SECItem profileSubject; - - profileSubject.data = smimeData[0].pValue; - profileSubject.len = smimeData[0].ulValueLen; - if (!SECITEM_ItemsAreEqual(&profileSubject,name)) { - goto loser; - } - } - - emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if (emailProfile == NULL) { - goto loser; - } - - emailProfile->data = smimeData[1].pValue; - emailProfile->len = smimeData[1].ulValueLen; - - if (profileTime) { - *profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if (*profileTime) { - (*profileTime)->data = smimeData[0].pValue; - (*profileTime)->len = smimeData[0].ulValueLen; - } - } - -loser: - if (emailProfile == NULL) { - if (smimeData[1].pValue) { - PORT_Free(smimeData[1].pValue); - } - } - if (profileTime == NULL || *profileTime == NULL) { - if (smimeData[0].pValue) { - PORT_Free(smimeData[0].pValue); - } - } - return emailProfile; -} - - -SECStatus -PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, - SECItem *emailProfile, SECItem *profileTime) -{ - CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME; - CK_BBOOL ck_true = CK_TRUE; - CK_ATTRIBUTE theTemplate[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_TOKEN, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, - { CKA_NETSCAPE_EMAIL, NULL, 0 }, - { CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - /* if you change the array, change the variable below as well */ - int realSize = 0; - CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE; - CK_ATTRIBUTE *attrs = theTemplate; - CK_SESSION_HANDLE rwsession; - PK11SlotInfo *free_slot = NULL; - CK_RV crv; -#ifdef DEBUG - int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); -#endif - - PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true, sizeof(ck_true)); attrs++; - PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len); attrs++; - PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, - emailAddr, PORT_Strlen(emailAddr)+1); attrs++; - if (profileTime) { - PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data, - profileTime->len); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE,emailProfile->data, - emailProfile->len); attrs++; - } - realSize = attrs - theTemplate; - PORT_Assert (realSize <= tsize); - - if (slot == NULL) { - free_slot = slot = PK11_GetInternalKeySlot(); - /* we need to free the key slot in the end!!! */ - } - - rwsession = PK11_GetRWSession(slot); - if (rwsession == CK_INVALID_SESSION) { - PORT_SetError(SEC_ERROR_READ_ONLY); - if (free_slot) { - PK11_FreeSlot(free_slot); - } - return SECFailure; - } - - crv = PK11_GETTAB(slot)-> - C_CreateObject(rwsession,theTemplate,realSize,&smimeh); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - } - - PK11_RestoreROSession(slot,rwsession); - - if (free_slot) { - PK11_FreeSlot(free_slot); - } - return SECSuccess; -} - - -CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url, - CERTSignedCrl *newCrl, SECItem *derCrl, int type); - -/* import the CRL into the token */ - -CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, - int type, void *wincx, PRInt32 importOptions, PRArenaPool* arena, - PRInt32 decodeoptions) -{ - CERTSignedCrl *newCrl, *crl; - SECStatus rv; - - newCrl = crl = NULL; - - do { - newCrl = CERT_DecodeDERCrlEx(arena, derCRL, type, decodeoptions); - if (newCrl == NULL) { - if (type == SEC_CRL_TYPE) { - /* only promote error when the error code is too generic */ - if (PORT_GetError () == SEC_ERROR_BAD_DER) - PORT_SetError(SEC_ERROR_CRL_INVALID); - } else { - PORT_SetError(SEC_ERROR_KRL_INVALID); - } - break; - } - - if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){ - CERTCertificate *caCert; - CERTCertDBHandle* handle = CERT_GetDefaultCertDB(); - PR_ASSERT(handle != NULL); - caCert = CERT_FindCertByName (handle, - &newCrl->crl.derName); - if (caCert == NULL) { - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); - break; - } - - /* If caCert is a v3 certificate, make sure that it can be used for - crl signing purpose */ - rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN); - if (rv != SECSuccess) { - break; - } - - rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert, - PR_Now(), wincx); - if (rv != SECSuccess) { - if (type == SEC_CRL_TYPE) { - PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE); - } else { - PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE); - } - break; - } - } - - crl = crl_storeCRL(slot, url, newCrl, derCRL, type); - - } while (0); - - if (crl == NULL) { - SEC_DestroyCrl (newCrl); - } - return (crl); -} diff --git a/security/nss/lib/pk11wrap/pk11err.c b/security/nss/lib/pk11wrap/pk11err.c deleted file mode 100644 index b6846af84..000000000 --- a/security/nss/lib/pk11wrap/pk11err.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ -/* - * this file maps PKCS11 Errors into SECErrors - * This is an information reducing process, since most errors are reflected - * back to the user (the user doesn't care about invalid flags, or active - * operations). If any of these errors need more detail in the upper layers - * which call PK11 library functions, we can add more SEC_ERROR_XXX functions - * and change there mappings here. - */ -#include "pkcs11t.h" -#include "pk11func.h" -#include "secerr.h" - -#ifdef PK11_ERROR_USE_ARRAY - -/* - * build a static array of entries... - */ -static struct { - CK_RV pk11_error; - int sec_error; -} pk11_error_map = { -#define MAPERROR(x,y) {x, y}, - -#else - -/* the default is to use a big switch statement */ -int -PK11_MapError(CK_RV rv) { - - switch (rv) { -#define MAPERROR(x,y) case x: return y; - -#endif - -/* the guts mapping */ - MAPERROR(CKR_OK, 0) - MAPERROR(CKR_CANCEL, SEC_ERROR_IO) - MAPERROR(CKR_HOST_MEMORY, SEC_ERROR_NO_MEMORY) - MAPERROR(CKR_SLOT_ID_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_ATTRIBUTE_READ_ONLY, SEC_ERROR_READ_ONLY) - MAPERROR(CKR_ATTRIBUTE_SENSITIVE, SEC_ERROR_IO) /* XX SENSITIVE */ - MAPERROR(CKR_ATTRIBUTE_TYPE_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_ATTRIBUTE_VALUE_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_DATA_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_DATA_LEN_RANGE, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_DEVICE_ERROR, SEC_ERROR_IO) - MAPERROR(CKR_DEVICE_MEMORY, SEC_ERROR_NO_MEMORY) - MAPERROR(CKR_DEVICE_REMOVED, SEC_ERROR_NO_TOKEN) - MAPERROR(CKR_ENCRYPTED_DATA_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_ENCRYPTED_DATA_LEN_RANGE, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_FUNCTION_CANCELED, SEC_ERROR_LIBRARY_FAILURE) - MAPERROR(CKR_FUNCTION_NOT_PARALLEL, SEC_ERROR_LIBRARY_FAILURE) - MAPERROR(CKR_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_MECHANISM_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_MECHANISM_PARAM_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_OBJECT_HANDLE_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_OPERATION_ACTIVE, SEC_ERROR_LIBRARY_FAILURE) - MAPERROR(CKR_OPERATION_NOT_INITIALIZED,SEC_ERROR_LIBRARY_FAILURE ) - MAPERROR(CKR_PIN_INCORRECT, SEC_ERROR_BAD_PASSWORD) - MAPERROR(CKR_PIN_INVALID, SEC_ERROR_BAD_PASSWORD) - MAPERROR(CKR_PIN_LEN_RANGE, SEC_ERROR_BAD_PASSWORD) - MAPERROR(CKR_SESSION_CLOSED, SEC_ERROR_LIBRARY_FAILURE) - MAPERROR(CKR_SESSION_COUNT, SEC_ERROR_NO_MEMORY) /* XXXX? */ - MAPERROR(CKR_SESSION_HANDLE_INVALID, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_SESSION_PARALLEL_NOT_SUPPORTED, SEC_ERROR_LIBRARY_FAILURE) - MAPERROR(CKR_SESSION_READ_ONLY, SEC_ERROR_LIBRARY_FAILURE) - MAPERROR(CKR_SIGNATURE_INVALID, SEC_ERROR_BAD_SIGNATURE) - MAPERROR(CKR_SIGNATURE_LEN_RANGE, SEC_ERROR_BAD_SIGNATURE) - MAPERROR(CKR_TEMPLATE_INCOMPLETE, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_TEMPLATE_INCONSISTENT, SEC_ERROR_BAD_DATA) - MAPERROR(CKR_TOKEN_NOT_PRESENT, SEC_ERROR_NO_TOKEN) - MAPERROR(CKR_TOKEN_NOT_RECOGNIZED, SEC_ERROR_IO) - MAPERROR(CKR_TOKEN_WRITE_PROTECTED, SEC_ERROR_READ_ONLY) - MAPERROR(CKR_UNWRAPPING_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_UNWRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_USER_ALREADY_LOGGED_IN, 0) - MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_LIBRARY_FAILURE) /* XXXX */ - MAPERROR(CKR_USER_PIN_NOT_INITIALIZED, SEC_ERROR_NO_TOKEN) - MAPERROR(CKR_USER_TYPE_INVALID, SEC_ERROR_LIBRARY_FAILURE) - MAPERROR(CKR_WRAPPED_KEY_INVALID, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_WRAPPED_KEY_LEN_RANGE, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_WRAPPING_KEY_HANDLE_INVALID, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_WRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_WRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY) - MAPERROR(CKR_VENDOR_DEFINED, SEC_ERROR_LIBRARY_FAILURE) - - -#ifdef PK11_ERROR_USE_ARRAY - -int -PK11_MapError(CK_RV rv) { - int size = sizeof(pk11_error_map)/sizeof(pk11_error_map[0]); - - for (i=0; i < size; i++) { - if (pk11_error_map[i].pk11_error == rv) { - return pk11_error_map[i].sec_error; - } - } - return SEC_ERROR_IO; - } - - -#else - - default: - break; - } - return SEC_ERROR_IO; -} - - -#endif diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h deleted file mode 100644 index 360043ca4..000000000 --- a/security/nss/lib/pk11wrap/pk11func.h +++ /dev/null @@ -1,574 +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. - * - * PKCS #11 Wrapper functions which handles authenticating to the card's - * choosing the best cards, etc. - */ -#ifndef _PK11FUNC_H_ -#define _PK11FUNC_H_ -#include "plarena.h" -#include "seccomon.h" -#include "secoidt.h" -#include "secdert.h" -#include "keyt.h" -#include "certt.h" -#include "pkcs11t.h" -#include "secmodt.h" -#include "seccomon.h" -#include "pkcs7t.h" -#include "cmsreclist.h" - -SEC_BEGIN_PROTOS - -/************************************************************ - * Generic Slot Lists Management - ************************************************************/ -PK11SlotList * PK11_NewSlotList(void); -void PK11_FreeSlotList(PK11SlotList *list); -SECStatus PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot); -SECStatus PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le); -PK11SlotListElement * PK11_GetFirstSafe(PK11SlotList *list); -PK11SlotListElement *PK11_GetNextSafe(PK11SlotList *list, - PK11SlotListElement *le, PRBool restart); -PK11SlotListElement *PK11_FindSlotElement(PK11SlotList *list, - PK11SlotInfo *slot); - -/************************************************************ - * Generic Slot Management - ************************************************************/ -PK11SlotInfo *PK11_ReferenceSlot(PK11SlotInfo *slot); -PK11SlotInfo *PK11_FindSlotByID(SECMODModuleID modID,CK_SLOT_ID slotID); -void PK11_FreeSlot(PK11SlotInfo *slot); -SECStatus PK11_DestroyObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object); -SECStatus PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object); -CK_OBJECT_HANDLE PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject); -SECStatus PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type, PRArenaPool *arena, SECItem *result); -CK_ULONG PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type); -PK11SlotInfo *PK11_GetInternalKeySlot(void); -PK11SlotInfo *PK11_GetInternalSlot(void); -char * PK11_MakeString(PRArenaPool *arena,char *space,char *staticSring, - int stringLen); -int PK11_MapError(CK_RV error); -CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot); -void PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession); -PRBool PK11_RWSessionHasLock(PK11SlotInfo *slot, - CK_SESSION_HANDLE session_handle); -PK11SlotInfo *PK11_NewSlotInfo(void); -SECStatus PK11_Logout(PK11SlotInfo *slot); -void PK11_LogoutAll(void); -void PK11_EnterSlotMonitor(PK11SlotInfo *); -void PK11_ExitSlotMonitor(PK11SlotInfo *); -void PK11_CleanKeyList(PK11SlotInfo *slot); - - -/************************************************************ - * Slot Password Management - ************************************************************/ -void PK11_SetSlotPWValues(PK11SlotInfo *slot,int askpw, int timeout); -void PK11_GetSlotPWValues(PK11SlotInfo *slot,int *askpw, int *timeout); -SECStatus PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw); -SECStatus PK11_CheckUserPassword(PK11SlotInfo *slot,char *pw); -SECStatus PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx); -PRBool PK11_IsLoggedIn(PK11SlotInfo *slot, void *wincx); -SECStatus PK11_VerifyPW(PK11SlotInfo *slot,char *pw); -SECStatus PK11_InitPin(PK11SlotInfo *slot,char *ssopw, char *pk11_userpwd); -SECStatus PK11_ChangePW(PK11SlotInfo *slot,char *oldpw, char *newpw); -void PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx); -void PK11_SetPasswordFunc(PK11PasswordFunc func); -void PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func); -void PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func); -int PK11_GetMinimumPwdLength(PK11SlotInfo *slot); -SECStatus PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd); - -/************************************************************ - * Manage the built-In Slot Lists - ************************************************************/ -SECStatus PK11_InitSlotLists(void); -void PK11_DestroySlotLists(void); -PK11SlotList *PK11_GetSlotList(CK_MECHANISM_TYPE type); -void PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count); -void PK11_ClearSlotList(PK11SlotInfo *slot); - - -/****************************************************************** - * Slot initialization - ******************************************************************/ -PRBool PK11_VerifyMechanism(PK11SlotInfo *slot,PK11SlotInfo *intern, - CK_MECHANISM_TYPE mech, SECItem *data, SECItem *iv); -PRBool PK11_VerifySlotMechanisms(PK11SlotInfo *slot); -SECStatus pk11_CheckVerifyTest(PK11SlotInfo *slot); -SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts); -SECStatus PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx); -void PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot); - - -/****************************************************************** - * Slot info functions - ******************************************************************/ -PK11SlotInfo *PK11_FindSlotByName(char *name); -PK11SlotInfo *PK11_FindSlotBySerial(char *serial); -PRBool PK11_IsReadOnly(PK11SlotInfo *slot); -PRBool PK11_IsInternal(PK11SlotInfo *slot); -char * PK11_GetTokenName(PK11SlotInfo *slot); -char * PK11_GetSlotName(PK11SlotInfo *slot); -PRBool PK11_NeedLogin(PK11SlotInfo *slot); -PRBool PK11_IsFriendly(PK11SlotInfo *slot); -PRBool PK11_IsHW(PK11SlotInfo *slot); -PRBool PK11_NeedUserInit(PK11SlotInfo *slot); -PRBool PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot); -int PK11_GetSlotSeries(PK11SlotInfo *slot); -int PK11_GetCurrentWrapIndex(PK11SlotInfo *slot); -unsigned long PK11_GetDefaultFlags(PK11SlotInfo *slot); -CK_SLOT_ID PK11_GetSlotID(PK11SlotInfo *slot); -SECMODModuleID PK11_GetModuleID(PK11SlotInfo *slot); -SECStatus PK11_GetSlotInfo(PK11SlotInfo *slot, CK_SLOT_INFO *info); -SECStatus PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info); -PRBool PK11_IsDisabled(PK11SlotInfo *slot); -PRBool PK11_HasRootCerts(PK11SlotInfo *slot); -PK11DisableReasons PK11_GetDisabledReason(PK11SlotInfo *slot); -/* Prevents the slot from being used, and set disable reason to user-disable */ -/* NOTE: Mechanisms that were ON continue to stay ON */ -/* Therefore, when the slot is enabled, it will remember */ -/* what mechanisms needs to be turned on */ -PRBool PK11_UserDisableSlot(PK11SlotInfo *slot); -/* Allow all mechanisms that are ON before UserDisableSlot() */ -/* was called to be available again */ -PRBool PK11_UserEnableSlot(PK11SlotInfo *slot); - -PRBool PK11_NeedPWInit(void); -PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot); -PRBool PK11_TokenExists(CK_MECHANISM_TYPE); -SECStatus PK11_GetModInfo(SECMODModule *mod, CK_INFO *info); -PRBool PK11_IsFIPS(void); -SECMODModule *PK11_GetModule(PK11SlotInfo *slot); - -/********************************************************************* - * Slot mapping utility functions. - *********************************************************************/ -PRBool PK11_IsPresent(PK11SlotInfo *slot); -PRBool PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type); -PK11SlotList * PK11_GetAllTokens(CK_MECHANISM_TYPE type,PRBool needRW, - PRBool loadCerts, void *wincx); -PK11SlotList * PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type, - PRBool needRW,void *wincx); -PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int count, - void *wincx); -PK11SlotInfo *PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx); -CK_MECHANISM_TYPE PK11_GetBestWrapMechanism(PK11SlotInfo *slot); -int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type); - -/********************************************************************* - * Mechanism Mapping functions - *********************************************************************/ -void PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key, - CK_MECHANISM_TYPE keygen, int ivLen, int blocksize); -CK_MECHANISM_TYPE PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len); -CK_MECHANISM_TYPE PK11_GetKeyGen(CK_MECHANISM_TYPE type); -int PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params); -int PK11_GetIVLength(CK_MECHANISM_TYPE type); -SECItem *PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv); -unsigned char *PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len); -SECItem * PK11_BlockData(SECItem *data,unsigned long size); - -/* PKCS #11 to DER mapping functions */ -SECItem *PK11_ParamFromAlgid(SECAlgorithmID *algid); -SECItem *PK11_GenerateNewParam(CK_MECHANISM_TYPE, PK11SymKey *); -CK_MECHANISM_TYPE PK11_AlgtagToMechanism(SECOidTag algTag); -SECOidTag PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type); -SECOidTag PK11_FortezzaMapSig(SECOidTag algTag); -SECStatus PK11_ParamToAlgid(SECOidTag algtag, SECItem *param, - PRArenaPool *arena, SECAlgorithmID *algid); -SECStatus PK11_SeedRandom(PK11SlotInfo *,unsigned char *data,int len); -SECStatus PK11_RandomUpdate(void *data, size_t bytes); -SECStatus PK11_GenerateRandom(unsigned char *data,int len); -CK_RV PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism, - CK_MECHANISM_PTR pCryptoMechanism, - SECItem *pbe_pwd, PRBool bad3DES); -CK_MECHANISM_TYPE PK11_GetPadMechanism(CK_MECHANISM_TYPE); - -/********************************************************************** - * Symetric, Public, and Private Keys - **********************************************************************/ -PK11SymKey *PK11_CreateSymKey(PK11SlotInfo *slot, - CK_MECHANISM_TYPE type, void *wincx); -void PK11_FreeSymKey(PK11SymKey *key); -PK11SymKey *PK11_ReferenceSymKey(PK11SymKey *symKey); -PK11SymKey *PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx); -PK11SymKey *PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, - CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation, - SECItem *key, CK_FLAGS flags, PRBool isPerm, void *wincx); -PK11SymKey *PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, - PK11Origin origin, CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, - PRBool owner, void *wincx); -PK11SymKey *PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, - CK_MECHANISM_TYPE type,int series, void *wincx); -void PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey); -CK_MECHANISM_TYPE PK11_GetMechanism(PK11SymKey *symKey); -CK_OBJECT_HANDLE PK11_ImportPublicKey(PK11SlotInfo *slot, - SECKEYPublicKey *pubKey, PRBool isToken); -PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - SECItem *param, int keySize,void *wincx); -PK11SymKey * PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, - void *wincx); -PK11SymKey *PK11_GetNextSymKey(PK11SymKey *symKey); - -/* Key Generation specialized for SDR (fixed DES3 key) */ -PK11SymKey *PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx); - -SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, - PK11SymKey *symKey, SECItem *wrappedKey); -SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params, - PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey); -PK11SymKey *PK11_Derive(PK11SymKey *baseKey, CK_MECHANISM_TYPE mechanism, - SECItem *param, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize); -PK11SymKey *PK11_DeriveWithFlags( PK11SymKey *baseKey, - CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags); -PK11SymKey *PK11_PubDerive( SECKEYPrivateKey *privKey, - SECKEYPublicKey *pubKey, PRBool isSender, SECItem *randomA, SECItem *randomB, - CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx) ; -PK11SymKey *PK11_UnwrapSymKey(PK11SymKey *key, - CK_MECHANISM_TYPE wraptype, SECItem *param, SECItem *wrapppedKey, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize); -PK11SymKey *PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, - CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, - CK_FLAGS flags); -PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize); -PK11SymKey *PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - SECItem *keyID, void *wincx); -SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey,PRBool force); -SECStatus PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey); -SECStatus PK11_DeleteTokenSymKey(PK11SymKey *symKey); -SECStatus PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx); -SECKEYPrivateKey * PK11_LoadPrivKey(PK11SlotInfo *slot, - SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, - PRBool token, PRBool sensitive); -SECKEYPublicKey *PK11_ExtractPublicKey(PK11SlotInfo *slot, KeyType keyType, - CK_OBJECT_HANDLE id); -char * PK11_GetSymKeyNickname(PK11SymKey *symKey); -char * PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey); -char * PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey); -SECStatus PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname); -SECStatus PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, - const char *nickname); -SECStatus PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, - const char *nickname); - -/* size to hold key in bytes */ -unsigned int PK11_GetKeyLength(PK11SymKey *key); -/* size of actual secret parts of key in bits */ -/* algid is because RC4 strength is determined by the effective bits as well - * as the key bits */ -unsigned int PK11_GetKeyStrength(PK11SymKey *key,SECAlgorithmID *algid); -SECStatus PK11_ExtractKeyValue(PK11SymKey *symKey); -SECItem * PK11_GetKeyData(PK11SymKey *symKey); -PK11SlotInfo * PK11_GetSlotFromKey(PK11SymKey *symKey); -void *PK11_GetWindow(PK11SymKey *symKey); -SECKEYPrivateKey *PK11_GenerateKeyPair(PK11SlotInfo *slot, - CK_MECHANISM_TYPE type, void *param, SECKEYPublicKey **pubk, - PRBool isPerm, PRBool isSensitive, void *wincx); -SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType, - PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx); -SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, - CERTCertificate *cert, void *wincx); -SECKEYPrivateKey * PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx); -SECKEYPrivateKey * PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, - void *wincx); -CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert, - void *wincx, PK11SlotInfo **pSlot); -int PK11_GetPrivateModulusLen(SECKEYPrivateKey *key); -SECStatus PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, - unsigned *outLen, unsigned int maxLen, unsigned char *enc, unsigned encLen); -/* The encrypt version of the above function */ -SECStatus PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc, - unsigned char *data, unsigned dataLen, void *wincx); -SECStatus PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, - SECKEYPrivateKeyInfo *pki, SECItem *nickname, - SECItem *publicValue, PRBool isPerm, PRBool isPrivate, - unsigned int usage, void *wincx); -SECStatus PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, - SECKEYPrivateKeyInfo *pki, SECItem *nickname, - SECItem *publicValue, PRBool isPerm, PRBool isPrivate, - unsigned int usage, SECKEYPrivateKey** privk, void *wincx); -SECStatus PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, - SECItem *derPKI, SECItem *nickname, - SECItem *publicValue, PRBool isPerm, PRBool isPrivate, - unsigned int usage, void *wincx); -SECStatus PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, - SECItem *derPKI, SECItem *nickname, - SECItem *publicValue, PRBool isPerm, PRBool isPrivate, - unsigned int usage, SECKEYPrivateKey** privk, void *wincx); -SECStatus PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, - SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem, - SECItem *nickname, SECItem *publicValue, PRBool isPerm, - PRBool isPrivate, KeyType type, - unsigned int usage, void *wincx); -SECKEYPrivateKeyInfo *PK11_ExportPrivateKeyInfo( - CERTCertificate *cert, void *wincx); -SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivateKeyInfo( - PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem, - CERTCertificate *cert, int iteration, void *wincx); -SECKEYPrivateKey *PK11_FindKeyByDERCert(PK11SlotInfo *slot, - CERTCertificate *cert, void *wincx); -SECKEYPublicKey *PK11_MakeKEAPubKey(unsigned char *data, int length); -SECStatus PK11_DigestKey(PK11Context *context, PK11SymKey *key); -PRBool PK11_VerifyKeyOK(PK11SymKey *key); -SECKEYPrivateKey *PK11_UnwrapPrivKey(PK11SlotInfo *slot, - PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, - SECItem *param, SECItem *wrappedKey, SECItem *label, - SECItem *publicValue, PRBool token, PRBool sensitive, - CK_KEY_TYPE keyType, CK_ATTRIBUTE_TYPE *usage, int usageCount, - void *wincx); -SECStatus PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, - SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType, - SECItem *param, SECItem *wrappedKey, void *wincx); -PK11SymKey * pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey); -SECItem *PK11_GetKeyIDFromCert(CERTCertificate *cert, void *wincx); -SECItem * PK11_GetKeyIDFromPrivateKey(SECKEYPrivateKey *key, void *wincx); -SECItem* PK11_DEREncodePublicKey(SECKEYPublicKey *pubk); -PK11SymKey* PK11_CopySymKeyForSigning(PK11SymKey *originalKey, - CK_MECHANISM_TYPE mech); -SECKEYPrivateKeyList* PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, - char *nickname, void *wincx); -SECKEYPublicKeyList* PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, - char *nickname); -SECKEYPQGParams *PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey); -/* depricated */ -SECKEYPrivateKeyList* PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot); - -/********************************************************************** - * Certs - **********************************************************************/ -SECItem *PK11_MakeIDFromPubKey(SECItem *pubKeyData); -CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey); -SECStatus PK11_TraverseSlotCerts( - SECStatus(* callback)(CERTCertificate*,SECItem *,void *), - void *arg, void *wincx); -SECStatus PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot, - SECStatus(* callback)(SECKEYPrivateKey*, void*), void *arg); -CERTCertificate * PK11_FindCertFromNickname(char *nickname, void *wincx); -CERTCertList * PK11_FindCertsFromNickname(char *nickname, void *wincx); -SECKEYPrivateKey * PK11_FindPrivateKeyFromNickname(char *nickname, void *wincx); -SECStatus PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, - CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust); -PK11SlotInfo *PK11_ImportCertForKey(CERTCertificate *cert, char *nickname, - void *wincx); -PK11SlotInfo *PK11_ImportDERCertForKey(SECItem *derCert, char *nickname, - void *wincx); -CK_OBJECT_HANDLE * PK11_FindObjectsFromNickname(char *nickname, - PK11SlotInfo **slotptr, CK_OBJECT_CLASS objclass, int *returnCount, - void *wincx); -PK11SlotInfo *PK11_KeyForCertExists(CERTCertificate *cert, - CK_OBJECT_HANDLE *keyPtr, void *wincx); -PK11SlotInfo *PK11_KeyForDERCertExists(SECItem *derCert, - CK_OBJECT_HANDLE *keyPtr, void *wincx); -CK_OBJECT_HANDLE PK11_MatchItem(PK11SlotInfo *slot,CK_OBJECT_HANDLE peer, - CK_OBJECT_CLASS o_class); -CERTCertificate * PK11_FindCertByIssuerAndSN(PK11SlotInfo **slot, - CERTIssuerAndSN *sn, void *wincx); -CERTCertificate * PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slot, - SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip, - SECKEYPrivateKey**privKey, void *wincx); -int PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, - void *wincx); -CK_BBOOL PK11_HasAttributeSet( PK11SlotInfo *slot, - CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type ); -CK_RV PK11_GetAttributes(PRArenaPool *arena,PK11SlotInfo *slot, - CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count); -int PK11_NumberCertsForCertSubject(CERTCertificate *cert); -SECStatus PK11_TraverseCertsForSubject(CERTCertificate *cert, - SECStatus(*callback)(CERTCertificate *, void *), void *arg); -SECStatus PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, - PK11SlotInfo *slot, SECStatus(*callback)(CERTCertificate *, void *), - void *arg); -CERTCertificate *PK11_FindCertFromDERCert(PK11SlotInfo *slot, - CERTCertificate *cert, void *wincx); -CERTCertificate *PK11_FindCertFromDERSubjectAndNickname( - PK11SlotInfo *slot, - CERTCertificate *cert, char *nickname, - void *wincx); -SECStatus PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert, - char *nickname, PRBool addUsage, - void *wincx); -CERTCertificate *PK11_FindBestKEAMatch(CERTCertificate *serverCert,void *wincx); -SECStatus PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1, - PK11SlotInfo *slot2, CERTCertificate **cert1, CERTCertificate **cert2); -PRBool PK11_FortezzaHasKEA(CERTCertificate *cert); -CK_OBJECT_HANDLE PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, - void *wincx); -SECStatus PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, - PK11SlotInfo *slot, SECStatus(*callback)(CERTCertificate *, void *), - void *arg); -SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot, - SECStatus(* callback)(CERTCertificate*, void *), void *arg); -CERTCertList * PK11_ListCerts(PK11CertListType type, void *pwarg); -CERTCertList * PK11_ListCertsInSlot(PK11SlotInfo *slot); -SECStatus PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx); -CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, - int type, void *wincx, PRInt32 importOptions, PRArenaPool* arena, PRInt32 decodeOptions); -/* import options */ -#define CRL_IMPORT_DEFAULT_OPTIONS 0x00000000 -#define CRL_IMPORT_BYPASS_CHECKS 0x00000001 - -/********************************************************************** - * Sign/Verify - **********************************************************************/ -int PK11_SignatureLen(SECKEYPrivateKey *key); -PK11SlotInfo * PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key); -SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, SECItem *hash); -SECStatus PK11_VerifyRecover(SECKEYPublicKey *key, SECItem *sig, - SECItem *dsig, void * wincx); -SECStatus PK11_Verify(SECKEYPublicKey *key, SECItem *sig, - SECItem *hash, void *wincx); - - - -/********************************************************************** - * Crypto Contexts - **********************************************************************/ -void PK11_DestroyContext(PK11Context *context, PRBool freeit); -PK11Context * PK11_CreateContextByRawKey(PK11SlotInfo *slot, - CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation, - SECItem *key, SECItem *param, void *wincx); -PK11Context *PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, SECItem *param); -PK11Context *PK11_CreateDigestContext(SECOidTag hashAlg); -PK11Context *PK11_CloneContext(PK11Context *old); -SECStatus PK11_DigestBegin(PK11Context *cx); -SECStatus PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, unsigned char *in, - int32 len); -SECStatus PK11_DigestOp(PK11Context *context, const unsigned char *in, - unsigned len); -SECStatus PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen, - int maxout, unsigned char *in, int inlen); -SECStatus PK11_Finalize(PK11Context *context); -SECStatus PK11_DigestFinal(PK11Context *context, unsigned char *data, - unsigned int *outLen, unsigned int length); -PRBool PK11_HashOK(SECOidTag hashAlg); -SECStatus PK11_SaveContext(PK11Context *cx,unsigned char *save, - int *len, int saveLength); - -/* Save the context's state, with possible allocation. - * The caller may supply an already allocated buffer in preAllocBuf, - * with length pabLen. If the buffer is large enough for the context's - * state, it will receive the state. - * If the buffer is not large enough (or NULL), then a new buffer will - * be allocated with PORT_Alloc. - * In either case, the state will be returned as a buffer, and the length - * of the state will be given in *stateLen. - */ -unsigned char * -PK11_SaveContextAlloc(PK11Context *cx, - unsigned char *preAllocBuf, unsigned int pabLen, - unsigned int *stateLen); - -SECStatus PK11_RestoreContext(PK11Context *cx,unsigned char *save,int len); -SECStatus PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len); -SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot); -void PK11_FreeSlotCerts(PK11SlotInfo *slot); -void PK11_SetFortezzaHack(PK11SymKey *symKey) ; - - -/********************************************************************** - * PBE functions - **********************************************************************/ - -/* This function creates PBE parameters from the given inputs. The result - * can be used to create a password integrity key for PKCS#12, by sending - * the return value to PK11_KeyGen along with the appropriate mechanism. - */ -SECItem * -PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations); - -/* free params created above (can be called after keygen is done */ -void PK11_DestroyPBEParams(SECItem *params); - -SECAlgorithmID * -PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt); -PK11SymKey * -PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem, - PRBool faulty3DES, void *wincx); -PK11SymKey * -PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *params, - SECItem *pwitem, PRBool faulty3DES, void *wincx); -SECItem * -PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem); - -/********************************************************************** - * New fucntions which are already depricated.... - **********************************************************************/ -SECItem * -PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot, - CERTCertificate *cert, void *pwarg); -SECItem * -PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key); - -SECItem * -PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *handle, - SECItem *derName, int type, char **url); - -CK_OBJECT_HANDLE -PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, - SECItem *name, char *url, int type); - -SECItem * -PK11_FindSMimeProfile(PK11SlotInfo **slotp, char *emailAddr, SECItem *derSubj, - SECItem **profileTime); -SECStatus -PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, - SECItem *emailProfile, SECItem *profileTime); - -PRBool SECMOD_HasRootCerts(void); - -PRBool PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle); - -char * PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id) ; -SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - const char *nickname) ; - - -/* private */ -SECStatus pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *cbArg, void *pwArg); - -SEC_END_PROTOS - -#endif diff --git a/security/nss/lib/pk11wrap/pk11init.h b/security/nss/lib/pk11wrap/pk11init.h deleted file mode 100644 index b5fa0b4ec..000000000 --- a/security/nss/lib/pk11wrap/pk11init.h +++ /dev/null @@ -1,63 +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. - */ -/* - * Internal header file included in pk11wrap dir, or in softoken - */ -#ifndef _PK11_INIT_H_ -#define _PK11_INIT_H_ 1 - -/* hold slot default flags until we initialize a slot. This structure is only - * useful between the time we define a module (either by hand or from the - * database) and the time the module is loaded. Not reference counted */ -struct PK11PreSlotInfoStr { - CK_SLOT_ID slotID; /* slot these flags are for */ - unsigned long defaultFlags; /* bit mask of default implementation this slot - * provides */ - int askpw; /* slot specific password bits */ - long timeout; /* slot specific timeout value */ - char hasRootCerts; /* is this the root cert PKCS #11 module? */ - char hasRootTrust; /* is this the root cert PKCS #11 module? */ -}; - -#define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES]" - -#define SECMOD_MAKE_NSS_FLAGS(fips,slot) \ -"Flags=internal,critical"fips" slotparams=("#slot"={"SECMOD_SLOT_FLAGS"})" - -#define SECMOD_INT_NAME "NSS Internal PKCS #11 Module" -#define SECMOD_INT_FLAGS SECMOD_MAKE_NSS_FLAGS("",1) -#define SECMOD_FIPS_NAME "NSS Internal FIPS PKCS #11 Module" -#define SECMOD_FIPS_FLAGS SECMOD_MAKE_NSS_FLAGS(",fips",3) - - -#endif /* _PK11_INIT_H_ 1 */ diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c deleted file mode 100644 index d6046bd99..000000000 --- a/security/nss/lib/pk11wrap/pk11kea.c +++ /dev/null @@ -1,228 +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. - */ -/* - * This file implements the Symkey wrapper and the PKCS context - * Interfaces. - */ - -#include "seccomon.h" -#include "secmod.h" -#include "nssilock.h" -#include "secmodi.h" -#include "pkcs11.h" -#include "pk11func.h" -#include "secitem.h" -#include "key.h" -#include "secasn1.h" -#include "sechash.h" -#include "cert.h" -#include "secerr.h" - -/* - * find an RSA public key on a card - */ -static CK_OBJECT_HANDLE -pk11_FindRSAPubKey(PK11SlotInfo *slot) -{ - CK_KEY_TYPE key_type = CKK_RSA; - CK_OBJECT_CLASS class_type = CKO_PUBLIC_KEY; - CK_ATTRIBUTE theTemplate[2]; - int template_count = sizeof(theTemplate)/sizeof(theTemplate[0]); - CK_ATTRIBUTE *attrs = theTemplate; - - PK11_SETATTRS(attrs,CKA_CLASS,&class_type,sizeof(class_type)); attrs++; - PK11_SETATTRS(attrs,CKA_KEY_TYPE,&key_type,sizeof(key_type)); attrs++; - template_count = attrs - theTemplate; - PR_ASSERT(template_count <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)); - - return pk11_FindObjectByTemplate(slot,theTemplate,template_count); -} - -PK11SymKey * -pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) -{ - PK11SymKey *newSymKey = NULL; - SECStatus rv; - /* performance improvement can go here --- use a generated key to as a - * per startup wrapping key. If it exists, use it, otherwise do a full - * key exchange. */ - - /* find a common Key Exchange algorithm */ - /* RSA */ - if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) && - PK11_DoesMechanism(slot,CKM_RSA_PKCS)) { - CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_HANDLE; - SECKEYPublicKey *pubKey = NULL; - SECKEYPrivateKey *privKey = NULL; - SECItem wrapData; - - wrapData.data = NULL; - - /* find RSA Public Key on target */ - pubKeyHandle = pk11_FindRSAPubKey(slot); - if (pubKeyHandle != CK_INVALID_HANDLE) { - privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY); - } - - /* if no key exists, generate a key pair */ - if (privKeyHandle == CK_INVALID_HANDLE) { - unsigned int symKeyLength = PK11_GetKeyLength(symKey); - PK11RSAGenParams rsaParams; - - if (symKeyLength > 60) /* bytes */ { - /* we'd have to generate an RSA key pair > 512 bits long, - ** and that's too costly. Don't even try. - */ - PORT_SetError( SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY ); - goto rsa_failed; - } - rsaParams.keySizeInBits = - (symKeyLength > 28 || symKeyLength == 0) ? 512 : 256; - rsaParams.pe = 0x10001; - privKey = PK11_GenerateKeyPair(slot,CKM_RSA_PKCS_KEY_PAIR_GEN, - &rsaParams, &pubKey,PR_FALSE,PR_TRUE,symKey->cx); - } else { - /* if keys exist, build SECKEY data structures for them */ - privKey = PK11_MakePrivKey(slot,nullKey, PR_TRUE, privKeyHandle, - symKey->cx); - if (privKey != NULL) { - pubKey = PK11_ExtractPublicKey(slot, rsaKey, pubKeyHandle); - if (pubKey && pubKey->pkcs11Slot) { - PK11_FreeSlot(pubKey->pkcs11Slot); - pubKey->pkcs11Slot = NULL; - pubKey->pkcs11ID = CK_INVALID_HANDLE; - } - } - } - if (privKey == NULL) goto rsa_failed; - if (pubKey == NULL) goto rsa_failed; - - wrapData.len = SECKEY_PublicKeyStrength(pubKey); - if (!wrapData.len) goto rsa_failed; - wrapData.data = PORT_Alloc(wrapData.len); - if (wrapData.data == NULL) goto rsa_failed; - - /* now wrap the keys in and out */ - rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, pubKey, symKey, &wrapData); - if (rv == SECSuccess) { - newSymKey = PK11_PubUnwrapSymKey(privKey,&wrapData,type,operation, - symKey->size); - } -rsa_failed: - if (wrapData.data != NULL) PORT_Free(wrapData.data); - if (privKey != NULL) SECKEY_DestroyPrivateKey(privKey); - if (pubKey != NULL) SECKEY_DestroyPublicKey(pubKey); - - return newSymKey; - } - /* KEA */ - if (PK11_DoesMechanism(symKey->slot, CKM_KEA_KEY_DERIVE) && - PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) { - CERTCertificate *certSource = NULL; - CERTCertificate *certTarget = NULL; - SECKEYPublicKey *pubKeySource = NULL; - SECKEYPublicKey *pubKeyTarget = NULL; - SECKEYPrivateKey *privKeySource = NULL; - SECKEYPrivateKey *privKeyTarget = NULL; - PK11SymKey *tekSource = NULL; - PK11SymKey *tekTarget = NULL; - SECItem Ra,wrap; - - /* can only exchange skipjack keys */ - if (type != CKM_SKIPJACK_CBC64) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - /* find a pair of certs we can use */ - rv = PK11_GetKEAMatchedCerts(symKey->slot,slot,&certSource,&certTarget); - if (rv != SECSuccess) goto kea_failed; - - /* get all the key pairs */ - pubKeyTarget = CERT_ExtractPublicKey(certSource); - pubKeySource = CERT_ExtractPublicKey(certTarget); - privKeySource = - PK11_FindKeyByDERCert(symKey->slot,certSource,symKey->cx); - privKeyTarget = - PK11_FindKeyByDERCert(slot,certTarget,symKey->cx); - - if ((pubKeySource == NULL) || (pubKeyTarget == NULL) || - (privKeySource == NULL) || (privKeyTarget == NULL)) goto kea_failed; - - /* generate the wrapping TEK's */ - Ra.data = (unsigned char*)PORT_Alloc(128 /* FORTEZZA RA MAGIC */); - Ra.len = 128; - if (Ra.data == NULL) goto kea_failed; - - tekSource = PK11_PubDerive(privKeySource,pubKeyTarget,PR_TRUE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - tekTarget = PK11_PubDerive(privKeyTarget,pubKeySource,PR_FALSE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - PORT_Free(Ra.data); - - if ((tekSource == NULL) || (tekTarget == NULL)) { goto kea_failed; } - - /* wrap the key out of Source into target */ - wrap.data = (unsigned char*)PORT_Alloc(12); /* MAGIC SKIPJACK LEN */ - wrap.len = 12; - - /* paranoia to prevent infinite recursion on bugs */ - PORT_Assert(tekSource->slot == symKey->slot); - if (tekSource->slot != symKey->slot) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP,NULL,tekSource,symKey,&wrap); - if (rv == SECSuccess) { - newSymKey = PK11_UnwrapSymKey(tekTarget, CKM_SKIPJACK_WRAP, NULL, - &wrap, type, operation, symKey->size); - } - PORT_Free(wrap.data); -kea_failed: - if (certSource == NULL) CERT_DestroyCertificate(certSource); - if (certTarget == NULL) CERT_DestroyCertificate(certTarget); - if (pubKeySource == NULL) SECKEY_DestroyPublicKey(pubKeySource); - if (pubKeyTarget == NULL) SECKEY_DestroyPublicKey(pubKeyTarget); - if (privKeySource == NULL) SECKEY_DestroyPrivateKey(privKeySource); - if (privKeyTarget == NULL) SECKEY_DestroyPrivateKey(privKeyTarget); - if (tekSource == NULL) PK11_FreeSymKey(tekSource); - if (tekTarget == NULL) PK11_FreeSymKey(tekTarget); - return newSymKey; - } - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; -} - diff --git a/security/nss/lib/pk11wrap/pk11list.c b/security/nss/lib/pk11wrap/pk11list.c deleted file mode 100644 index 67bef9573..000000000 --- a/security/nss/lib/pk11wrap/pk11list.c +++ /dev/null @@ -1,169 +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. - */ -/* - * Locking and queue management primatives - * - */ - -#include "seccomon.h" -#include "nssilock.h" -#include "prmon.h" -#include "secmod.h" -#include "secmodi.h" -#include "prlong.h" - -#define ISREADING 1 -#define ISWRITING 2 -#define WANTWRITE 4 -#define ISLOCKED 3 - -/* - * create a new lock for a Module List - */ -SECMODListLock *SECMOD_NewListLock() { - SECMODListLock *modLock; - - modLock = (SECMODListLock*)PORT_Alloc(sizeof(SECMODListLock)); -#ifdef PKCS11_USE_THREADS - modLock->mutex = NULL; - modLock->monitor = PZ_NewMonitor(nssILockList); -#else - modLock->mutex = NULL; - modLock->monitor = NULL; -#endif - modLock->state = 0; - modLock->count = 0; - return modLock; -} - -/* - * destroy the lock - */ -void SECMOD_DestroyListLock(SECMODListLock *lock) { - PK11_USE_THREADS(PZ_DestroyMonitor(lock->monitor);) - PORT_Free(lock); -} - - -/* - * Lock the List for Read: NOTE: this assumes the reading isn't so common - * the writing will be starved. - */ -void SECMOD_GetReadLock(SECMODListLock *modLock) { -#ifdef PKCS11_USE_THREADS - if (modLock == NULL) return; - PZ_EnterMonitor(modLock->monitor); - while (modLock->state & ISWRITING) { - PZ_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */ - } - modLock->state |= ISREADING; - modLock->count++; - PZ_ExitMonitor(modLock->monitor); -#endif -} - -/* - * Release the Read lock - */ -void SECMOD_ReleaseReadLock(SECMODListLock *modLock) { -#ifdef PKCS11_USE_THREADS - if (modLock == NULL) return; - PZ_EnterMonitor(modLock->monitor); - modLock->count--; - if (modLock->count == 0) { - modLock->state &= ~ISREADING; - if (modLock->state & WANTWRITE) { - PZ_Notify(modLock->monitor); /* only one writer at a time */ - } - } - PZ_ExitMonitor(modLock->monitor); -#endif -} - - -/* - * lock the list for Write - */ -void SECMOD_GetWriteLock(SECMODListLock *modLock) { -#ifdef PKCS11_USE_THREADS - if (modLock == NULL) return; - PZ_EnterMonitor(modLock->monitor); - while (modLock->state & ISLOCKED) { - modLock->state |= WANTWRITE; - PZ_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */ - } - modLock->state = ISWRITING; - PZ_ExitMonitor(modLock->monitor); -#endif -} - - -/* - * Release the Write Lock: NOTE, this code is pretty inefficient if you have - * lots of write collisions. - */ -void SECMOD_ReleaseWriteLock(SECMODListLock *modLock) { -#ifdef PKCS11_USE_THREADS - if (modLock == NULL) return; - PZ_EnterMonitor(modLock->monitor); - modLock->state = 0; - PR_NotifyAll(modLock->monitor); /* enable all the readers */ - PZ_ExitMonitor(modLock->monitor); -#endif -} - - -/* - * must Hold the Write lock - */ -void -SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child) { - *parent = child->next; - child->next = NULL; -} - -/* - * if lock is not specified, it must already be held - */ -void -SECMOD_AddList(SECMODModuleList *parent, SECMODModuleList *child, - SECMODListLock *lock) { - if (lock) { SECMOD_GetWriteLock(lock); } - - child->next = parent->next; - parent->next = child; - - if (lock) { SECMOD_ReleaseWriteLock(lock); } -} - - diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c deleted file mode 100644 index 65c61c15e..000000000 --- a/security/nss/lib/pk11wrap/pk11load.c +++ /dev/null @@ -1,333 +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. - */ -/* - * The following handles the loading, unloading and management of - * various PCKS #11 modules - */ -#include "seccomon.h" -#include "pkcs11.h" -#include "secmod.h" -#include "prlink.h" -#include "pk11func.h" -#include "secmodi.h" -#include "nssilock.h" - -extern void FC_GetFunctionList(void); -extern void NSC_GetFunctionList(void); -extern void NSC_ModuleDBFunc(void); - -static char *modToDBG = NULL; - -#ifdef DEBUG -#define DEBUG_MODULE 1 -#endif - -#ifdef DEBUG_MODULE -#include "debug_module.c" -#endif - -/* build the PKCS #11 2.01 lock files */ -CK_RV PR_CALLBACK secmodCreateMutext(CK_VOID_PTR_PTR pmutex) { - *pmutex = (CK_VOID_PTR) PZ_NewLock(nssILockOther); - if ( *pmutex ) return CKR_OK; - return CKR_HOST_MEMORY; -} - -CK_RV PR_CALLBACK secmodDestroyMutext(CK_VOID_PTR mutext) { - PZ_DestroyLock((PZLock *)mutext); - return CKR_OK; -} - -CK_RV PR_CALLBACK secmodLockMutext(CK_VOID_PTR mutext) { - PZ_Lock((PZLock *)mutext); - return CKR_OK; -} - -CK_RV PR_CALLBACK secmodUnlockMutext(CK_VOID_PTR mutext) { - PZ_Unlock((PZLock *)mutext); - return CKR_OK; -} - -static SECMODModuleID nextModuleID = 1; -static CK_C_INITIALIZE_ARGS secmodLockFunctions = { - secmodCreateMutext, secmodDestroyMutext, secmodLockMutext, - secmodUnlockMutext, CKF_LIBRARY_CANT_CREATE_OS_THREADS| - CKF_OS_LOCKING_OK - ,NULL -}; - -/* - * set the hasRootCerts flags in the module so it can be stored back - * into the database. - */ -void -SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod) { - PK11PreSlotInfo *psi = NULL; - int i; - - if (slot->hasRootCerts) { - for (i=0; i < mod->slotInfoCount; i++) { - if (slot->slotID == mod->slotInfo[i].slotID) { - psi = &mod->slotInfo[i]; - break; - } - } - if (psi == NULL) { - /* allocate more slots */ - PK11PreSlotInfo *psi_list = (PK11PreSlotInfo *) - PORT_ArenaAlloc(mod->arena, - (mod->slotInfoCount+1)* sizeof(PK11PreSlotInfo)); - /* copy the old ones */ - if (mod->slotInfoCount > 0) { - PORT_Memcpy(psi_list,mod->slotInfo, - (mod->slotInfoCount)*sizeof(PK11PreSlotInfo)); - } - /* assign psi to the last new slot */ - psi = &psi_list[mod->slotInfoCount]; - psi->slotID = slot->slotID; - psi->askpw = 0; - psi->timeout = 0; - psi ->defaultFlags = 0; - - /* increment module count & store new list */ - mod->slotInfo = psi_list; - mod->slotInfoCount++; - - } - psi->hasRootCerts = 1; - } -} - -/* - * load a new module into our address space and initialize it. - */ -SECStatus -SECMOD_LoadPKCS11Module(SECMODModule *mod) { - PRLibrary *library = NULL; - CK_C_GetFunctionList entry = NULL; - char * full_name; - CK_INFO info; - CK_ULONG slotCount = 0; - - - if (mod->loaded) return SECSuccess; - - /* intenal modules get loaded from their internal list */ - if (mod->internal) { - /* internal, statically get the C_GetFunctionList function */ - if (mod->isFIPS) { - entry = (CK_C_GetFunctionList) FC_GetFunctionList; - } else { - entry = (CK_C_GetFunctionList) NSC_GetFunctionList; - } - if (mod->isModuleDB) { - mod->moduleDBFunc = (void *) NSC_ModuleDBFunc; - } - if (mod->moduleDBOnly) { - mod->loaded = PR_TRUE; - return SECSuccess; - } - } else { - /* Not internal, load the DLL and look up C_GetFunctionList */ - if (mod->dllName == NULL) { - return SECFailure; - } - -#ifdef notdef - /* look up the library name */ - full_name = PR_GetLibraryName(PR_GetLibraryPath(),mod->dllName); - if (full_name == NULL) { - return SECFailure; - } -#else - full_name = PORT_Strdup(mod->dllName); -#endif - - /* load the library. If this succeeds, then we have to remember to - * unload the library if anything goes wrong from here on out... - */ - library = PR_LoadLibrary(full_name); - mod->library = (void *)library; - PORT_Free(full_name); - if (library == NULL) { - return SECFailure; - } - - /* - * now we need to get the entry point to find the function pointers - */ - if (!mod->moduleDBOnly) { - entry = (CK_C_GetFunctionList) - PR_FindSymbol(library, "C_GetFunctionList"); - } - if (mod->isModuleDB) { - mod->moduleDBFunc = (void *) - PR_FindSymbol(library, "NSS_ReturnModuleSpecData"); - } - if (mod->moduleDBFunc == NULL) mod->isModuleDB = PR_FALSE; - if (entry == NULL) { - if (mod->isModuleDB) { - mod->loaded = PR_TRUE; - mod->moduleDBOnly = PR_TRUE; - return SECSuccess; - } - PR_UnloadLibrary(library); - return SECFailure; - } - } - - /* - * We need to get the function list - */ - if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK) - goto fail; - -#ifdef DEBUG_MODULE - if (PR_TRUE) { - modToDBG = PR_GetEnv("NSS_DEBUG_PKCS11_MODULE"); - if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) { - mod->functionList = (void *)nss_InsertDeviceLog( - (CK_FUNCTION_LIST_PTR)mod->functionList); - } - } -#endif - - mod->isThreadSafe = PR_TRUE; - /* Now we initialize the module */ - if (mod->libraryParams) { - secmodLockFunctions.LibraryParameters = (void *) mod->libraryParams; - } else { - secmodLockFunctions.LibraryParameters = NULL; - } - if (PK11_GETTAB(mod)->C_Initialize(&secmodLockFunctions) != CKR_OK) { - mod->isThreadSafe = PR_FALSE; - if (PK11_GETTAB(mod)->C_Initialize(NULL) != CKR_OK) goto fail; - } - - /* check the version number */ - if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2; - if (info.cryptokiVersion.major != 2) goto fail2; - /* all 2.0 are a priori *not* thread safe */ - if (info.cryptokiVersion.minor < 1) mod->isThreadSafe = PR_FALSE; - - - /* If we don't have a common name, get it from the PKCS 11 module */ - if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) { - mod->commonName = PK11_MakeString(mod->arena,NULL, - (char *)info.libraryDescription, sizeof(info.libraryDescription)); - if (mod->commonName == NULL) goto fail2; - } - - - /* initialize the Slots */ - if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) { - CK_SLOT_ID *slotIDs; - int i; - CK_RV rv; - - mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena, - sizeof(PK11SlotInfo *) * slotCount); - if (mod->slots == NULL) goto fail2; - - slotIDs = (CK_SLOT_ID *) PORT_Alloc(sizeof(CK_SLOT_ID)*slotCount); - if (slotIDs == NULL) { - goto fail2; - } - rv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount); - if (rv != CKR_OK) { - PORT_Free(slotIDs); - goto fail2; - } - - /* Initialize each slot */ - for (i=0; i < (int)slotCount; i++) { - mod->slots[i] = PK11_NewSlotInfo(); - PK11_InitSlot(mod,slotIDs[i],mod->slots[i]); - /* look down the slot info table */ - PK11_LoadSlotList(mod->slots[i],mod->slotInfo,mod->slotInfoCount); - SECMOD_SetRootCerts(mod->slots[i],mod); - } - mod->slotCount = slotCount; - mod->slotInfoCount = 0; - PORT_Free(slotIDs); - } - - mod->loaded = PR_TRUE; - mod->moduleID = nextModuleID++; - return SECSuccess; -fail2: - PK11_GETTAB(mod)->C_Finalize(NULL); -fail: - mod->functionList = NULL; - if (library) PR_UnloadLibrary(library); - return SECFailure; -} - -SECStatus -SECMOD_UnloadModule(SECMODModule *mod) { - PRLibrary *library; - - if (!mod->loaded) { - return SECFailure; - } - - if (!mod->moduleDBOnly) PK11_GETTAB(mod)->C_Finalize(NULL); - mod->moduleID = 0; - mod->loaded = PR_FALSE; - - /* do we want the semantics to allow unloading the internal library? - * if not, we should change this to SECFailure and move it above the - * mod->loaded = PR_FALSE; */ - if (mod->internal) { - return SECSuccess; - } - - library = (PRLibrary *)mod->library; - /* paranoia */ - if (library == NULL) { - return SECFailure; - } - - PR_UnloadLibrary(library); - return SECSuccess; -} - -void -nss_DumpModuleLog(void) -{ -#ifdef DEBUG_MODULE - if (modToDBG) { - print_final_statistics(); - } -#endif -} diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c deleted file mode 100644 index b1602f1c8..000000000 --- a/security/nss/lib/pk11wrap/pk11pars.c +++ /dev/null @@ -1,395 +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) 2001 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. - */ -/* - * The following handles the loading, unloading and management of - * various PCKS #11 modules - */ - -#include <ctype.h> -#include "pkcs11.h" -#include "seccomon.h" -#include "secmod.h" -#include "secmodi.h" -#include "pki3hack.h" - -#include "pk11pars.h" - -/* create a new module */ -static SECMODModule * -secmod_NewModule(void) -{ - SECMODModule *newMod; - PRArenaPool *arena; - - - /* create an arena in which dllName and commonName can be - * allocated. - */ - arena = PORT_NewArena(512); - if (arena == NULL) { - return NULL; - } - - newMod = (SECMODModule *)PORT_ArenaAlloc(arena,sizeof (SECMODModule)); - if (newMod == NULL) { - PORT_FreeArena(arena,PR_FALSE); - return NULL; - } - - /* - * initialize of the fields of the module - */ - newMod->arena = arena; - newMod->internal = PR_FALSE; - newMod->loaded = PR_FALSE; - newMod->isFIPS = PR_FALSE; - newMod->dllName = NULL; - newMod->commonName = NULL; - newMod->library = NULL; - newMod->functionList = NULL; - newMod->slotCount = 0; - newMod->slots = NULL; - newMod->slotInfo = NULL; - newMod->slotInfoCount = 0; - newMod->refCount = 1; - newMod->ssl[0] = 0; - newMod->ssl[1] = 0; - newMod->libraryParams = NULL; - newMod->moduleDBFunc = NULL; - newMod->parent = NULL; - newMod->isCritical = PR_FALSE; - newMod->isModuleDB = PR_FALSE; - newMod->moduleDBOnly = PR_FALSE; - newMod->trustOrder = 0; - newMod->cipherOrder = 0; -#ifdef PKCS11_USE_THREADS - newMod->refLock = (void *)PZ_NewLock(nssILockRefLock); - if (newMod->refLock == NULL) { - PORT_FreeArena(arena,PR_FALSE); - return NULL; - } -#else - newMod->refLock = NULL; -#endif - return newMod; - -} - -/* - * for 3.4 we continue to use the old SECMODModule structure - */ -SECMODModule * -SECMOD_CreateModule(char *library, char *moduleName, char *parameters, char *nss) -{ - SECMODModule *mod = secmod_NewModule(); - char *slotParams,*ciphers; - if (mod == NULL) return NULL; - - mod->commonName = PORT_ArenaStrdup(mod->arena,moduleName ? moduleName : ""); - if (library) { - mod->dllName = PORT_ArenaStrdup(mod->arena,library); - } - /* new field */ - if (parameters) { - mod->libraryParams = PORT_ArenaStrdup(mod->arena,parameters); - } - mod->internal = pk11_argHasFlag("flags","internal",nss); - mod->isFIPS = pk11_argHasFlag("flags","FIPS",nss); - mod->isCritical = pk11_argHasFlag("flags","critical",nss); - slotParams = pk11_argGetParamValue("slotParams",nss); - mod->slotInfo = pk11_argParseSlotInfo(mod->arena,slotParams, - &mod->slotInfoCount); - if (slotParams) PORT_Free(slotParams); - /* new field */ - mod->trustOrder = pk11_argReadLong("trustOrder",nss, - PK11_DEFAULT_TRUST_ORDER,NULL); - /* new field */ - mod->cipherOrder = pk11_argReadLong("cipherOrder",nss, - PK11_DEFAULT_CIPHER_ORDER,NULL); - /* new field */ - mod->isModuleDB = pk11_argHasFlag("flags","moduleDB",nss); - mod->moduleDBOnly = pk11_argHasFlag("flags","moduleDBOnly",nss); - if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE; - - ciphers = pk11_argGetParamValue("ciphers",nss); - pk11_argSetNewCipherFlags(&mod->ssl[0],ciphers); - if (ciphers) PORT_Free(ciphers); - - secmod_PrivateModuleCount++; - - return mod; -} - -static char * -pk11_mkModuleSpec(SECMODModule * module) -{ - char *nss = NULL, *modSpec = NULL, **slotStrings = NULL; - int slotCount, i, si; - - /* allocate target slot info strings */ - slotCount = 0; - if (module->slotCount) { - for (i=0; i < module->slotCount; i++) { - if (module->slots[i]->defaultFlags !=0) { - slotCount++; - } - } - } else { - slotCount = module->slotInfoCount; - } - - slotStrings = (char **)PORT_ZAlloc(slotCount*sizeof(char *)); - if (slotStrings == NULL) { - goto loser; - } - - - /* build the slot info strings */ - if (module->slotCount) { - for (i=0, si= 0; i < module->slotCount; i++) { - if (module->slots[i]->defaultFlags) { - PORT_Assert(si < slotCount); - if (si >= slotCount) break; - slotStrings[si] = pk11_mkSlotString(module->slots[i]->slotID, - module->slots[i]->defaultFlags, - module->slots[i]->timeout, - module->slots[i]->askpw, - module->slots[i]->hasRootCerts, - module->slots[i]->hasRootTrust); - si++; - } - } - } else { - for (i=0; i < slotCount; i++) { - slotStrings[i] = pk11_mkSlotString(module->slotInfo[i].slotID, - module->slotInfo[i].defaultFlags, - module->slotInfo[i].timeout, - module->slotInfo[i].askpw, - module->slotInfo[i].hasRootCerts, - module->slotInfo[i].hasRootTrust); - } - } - - nss = pk11_mkNSS(slotStrings,slotCount,module->internal, module->isFIPS, - module->isModuleDB, module->moduleDBOnly, module->isCritical, - module->trustOrder,module->cipherOrder,module->ssl[0],module->ssl[1]); - modSpec= pk11_mkNewModuleSpec(module->dllName,module->commonName, - module->libraryParams,nss); - PORT_Free(slotStrings); - PR_smprintf_free(nss); -loser: - return (modSpec); -} - - -char ** -SECMOD_GetModuleSpecList(SECMODModule *module) -{ - SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc; - if (func) { - return (*func)(SECMOD_MODULE_DB_FUNCTION_FIND, - module->libraryParams,NULL); - } - return NULL; -} - -SECStatus -SECMOD_AddPermDB(SECMODModule *module) -{ - SECMODModuleDBFunc func; - char *moduleSpec; - char **retString; - - if (module->parent == NULL) return SECFailure; - - func = (SECMODModuleDBFunc) module->parent->moduleDBFunc; - if (func) { - moduleSpec = pk11_mkModuleSpec(module); - retString = (*func)(SECMOD_MODULE_DB_FUNCTION_ADD, - module->parent->libraryParams,moduleSpec); - PORT_Free(moduleSpec); - if (retString != NULL) return SECSuccess; - } - return SECFailure; -} - -SECStatus -SECMOD_DeletePermDB(SECMODModule *module) -{ - SECMODModuleDBFunc func; - char *moduleSpec; - char **retString; - - if (module->parent == NULL) return SECFailure; - - func = (SECMODModuleDBFunc) module->parent->moduleDBFunc; - if (func) { - moduleSpec = pk11_mkModuleSpec(module); - retString = (*func)(SECMOD_MODULE_DB_FUNCTION_DEL, - module->parent->libraryParams,moduleSpec); - PORT_Free(moduleSpec); - if (retString != NULL) return SECSuccess; - } - return SECFailure; -} - -SECStatus -SECMOD_FreeModuleSpecList(SECMODModule *module, char **moduleSpecList) -{ - SECMODModuleDBFunc func = (SECMODModuleDBFunc) module->moduleDBFunc; - char **retString; - if (func) { - retString = (*func)(SECMOD_MODULE_DB_FUNCTION_RELEASE, - module->libraryParams,moduleSpecList); - if (retString != NULL) return SECSuccess; - } - return SECFailure; -} - -/* - * load a PKCS#11 module but do not add it to the default NSS trust domain - */ -SECMODModule * -SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse) -{ - char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL; - SECStatus status; - SECMODModule *module = NULL; - SECStatus rv; - - /* initialize the underlying module structures */ - SECMOD_Init(); - - status = pk11_argParseModuleSpec(modulespec, &library, &moduleName, - ¶meters, &nss); - if (status != SECSuccess) { - goto loser; - } - - module = SECMOD_CreateModule(library, moduleName, parameters, nss); - if (library) PORT_Free(library); - if (moduleName) PORT_Free(moduleName); - if (parameters) PORT_Free(parameters); - if (nss) PORT_Free(nss); - - /* load it */ - rv = SECMOD_LoadPKCS11Module(module); - if (rv != SECSuccess) { - goto loser; - } - - if (recurse && module->isModuleDB) { - char ** moduleSpecList; - char **index; - - moduleSpecList = SECMOD_GetModuleSpecList(module); - - for (index = moduleSpecList; index && *index; index++) { - SECMODModule *child; - child = SECMOD_LoadModule(*index,module,PR_TRUE); - if (!child) break; - if (child->isCritical && !child->loaded) { - rv = SECFailure; - SECMOD_DestroyModule(child); - break; - } - SECMOD_DestroyModule(child); - } - - SECMOD_FreeModuleSpecList(module,moduleSpecList); - } - - if (rv != SECSuccess) { - goto loser; - } - - if (parent) { - module->parent = SECMOD_ReferenceModule(parent); - } - - /* inherit the reference */ - if (!module->moduleDBOnly) { - SECMOD_AddModuleToList(module); - } else { - SECMOD_AddModuleToDBOnlyList(module); - } - - /* handle any additional work here */ - return module; - -loser: - if (module) { - if (module->loaded) { - SECMOD_UnloadModule(module); - } - SECMOD_AddModuleToUnloadList(module); - } - return module; -} - -/* - * load a PKCS#11 module and add it to the default NSS trust domain - */ -SECMODModule * -SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse) -{ - SECStatus rv = SECSuccess; - SECMODModule * newmod = SECMOD_LoadModule(modulespec, parent, recurse); - if (newmod) { - rv = STAN_AddModuleToDefaultTrustDomain(newmod); - if (SECSuccess != rv) { - SECMOD_DestroyModule(newmod); - return NULL; - } - } - return newmod; -} - -/* - * remove the PKCS#11 module from the default NSS trust domain, call - * C_Finalize, and destroy the module structure - */ -SECStatus SECMOD_UnloadUserModule(SECMODModule *mod) -{ - SECStatus rv = SECSuccess; - int atype = 0; - if (!mod) { - return SECFailure; - } - rv = STAN_RemoveModuleFromDefaultTrustDomain(mod); - if (SECSuccess != rv) { - return SECFailure; - } - return SECMOD_DeleteModuleEx(NULL, mod, &atype, PR_FALSE); -} - diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c deleted file mode 100644 index ae574d731..000000000 --- a/security/nss/lib/pk11wrap/pk11pbe.c +++ /dev/null @@ -1,687 +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 "secport.h" -#include "hasht.h" -#include "pkcs11t.h" -#include "sechash.h" -#include "secasn1.h" -#include "secder.h" -#include "secoid.h" -#include "alghmac.h" -#include "secerr.h" -#include "secmod.h" -#include "pk11func.h" -#include "secpkcs5.h" - -typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter; -struct SEC_PKCS5PBEParameterStr { - PRArenaPool *poolp; - SECItem salt; /* octet string */ - SECItem iteration; /* integer */ -}; - - -/* template for PKCS 5 PBE Parameter. This template has been expanded - * based upon the additions in PKCS 12. This should eventually be moved - * if RSA updates PKCS 5. - */ -const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] = -{ - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, - { SEC_ASN1_OCTET_STRING, - offsetof(SEC_PKCS5PBEParameter, salt) }, - { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS5PBEParameter, iteration) }, - { 0 } -}; - -const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] = -{ - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, - { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) }, - { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) }, - { 0 } -}; - -/* maps crypto algorithm from PBE algorithm. - */ -SECOidTag -SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid) -{ - - SECOidTag algorithm; - - if(algid == NULL) - return SEC_OID_UNKNOWN; - - algorithm = SECOID_GetAlgorithmTag(algid); - switch(algorithm) - { - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: - return SEC_OID_DES_EDE3_CBC; - case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: - case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: - case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: - return SEC_OID_DES_CBC; - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: - return SEC_OID_RC2_CBC; - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: - return SEC_OID_RC4; - default: - break; - } - - return SEC_OID_UNKNOWN; -} - -/* check to see if an oid is a pbe algorithm - */ -PRBool -SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid) -{ - return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN); -} - -/* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing. - */ -SECOidTag -SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen) -{ - switch(algTag) - { - case SEC_OID_DES_EDE3_CBC: - switch(keyLen) { - case 168: - case 192: - return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC; - case 128: - case 92: - return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC; - default: - break; - } - break; - case SEC_OID_DES_CBC: - return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC; - case SEC_OID_RC2_CBC: - switch(keyLen) { - case 40: - return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC; - case 128: - return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC; - default: - break; - } - break; - case SEC_OID_RC4: - switch(keyLen) { - case 40: - return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4; - case 128: - return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4; - default: - break; - } - break; - default: - break; - } - - return SEC_OID_UNKNOWN; -} - - -/* get the key length needed for the PBE algorithm - */ - -int -SEC_PKCS5GetKeyLength(SECAlgorithmID *algid) -{ - - SECOidTag algorithm; - - if(algid == NULL) - return SEC_OID_UNKNOWN; - - algorithm = SECOID_GetAlgorithmTag(algid); - - switch(algorithm) - { - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: - return 24; - case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: - case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: - case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: - return 8; - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: - return 5; - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: - return 16; - default: - break; - } - return -1; -} - - -/* the V2 algorithms only encode the salt, there is no iteration - * count so we need a check for V2 algorithm parameters. - */ -static PRBool -sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm) -{ - switch(algorithm) - { - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: - return PR_TRUE; - default: - break; - } - - return PR_FALSE; -} -/* destroy a pbe parameter. it assumes that the parameter was - * generated using the appropriate create function and therefor - * contains an arena pool. - */ -static void -sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param) -{ - if(pbe_param != NULL) - PORT_FreeArena(pbe_param->poolp, PR_TRUE); -} - -/* creates a PBE parameter based on the PBE algorithm. the only required - * parameters are algorithm and interation. the return is a PBE parameter - * which conforms to PKCS 5 parameter unless an extended parameter is needed. - * this is primarily if keyLen and a variable key length algorithm are - * specified. - * salt - if null, a salt will be generated from random bytes. - * iteration - number of iterations to perform hashing. - * keyLen - only used in variable key length algorithms - * iv - if null, the IV will be generated based on PKCS 5 when needed. - * params - optional, currently unsupported additional parameters. - * once a parameter is allocated, it should be destroyed calling - * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter. - */ -#define DEFAULT_SALT_LENGTH 16 -static SEC_PKCS5PBEParameter * -sec_pkcs5_create_pbe_parameter(SECOidTag algorithm, - SECItem *salt, - int iteration) -{ - PRArenaPool *poolp = NULL; - SEC_PKCS5PBEParameter *pbe_param = NULL; - SECStatus rv= SECSuccess; - void *dummy = NULL; - - if(iteration < 0) { - return NULL; - } - - poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if(poolp == NULL) - return NULL; - - pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp, - sizeof(SEC_PKCS5PBEParameter)); - if(!pbe_param) { - PORT_FreeArena(poolp, PR_TRUE); - return NULL; - } - - pbe_param->poolp = poolp; - - rv = SECFailure; - if (salt && salt->data) { - rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt); - } else { - /* sigh, the old interface generated salt on the fly, so we have to - * preserve the semantics */ - pbe_param->salt.len = DEFAULT_SALT_LENGTH; - pbe_param->salt.data = PORT_ArenaZAlloc(poolp,DEFAULT_SALT_LENGTH); - if (pbe_param->salt.data) { - rv = PK11_GenerateRandom(pbe_param->salt.data,DEFAULT_SALT_LENGTH); - } - } - - if(rv != SECSuccess) { - PORT_FreeArena(poolp, PR_TRUE); - return NULL; - } - - /* encode the integer */ - dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration, - iteration); - rv = (dummy) ? SECSuccess : SECFailure; - - if(rv != SECSuccess) { - PORT_FreeArena(poolp, PR_FALSE); - return NULL; - } - - return pbe_param; -} - -/* creates a algorithm ID containing the PBE algorithm and appropriate - * parameters. the required parameter is the algorithm. if salt is - * not specified, it is generated randomly. if IV is specified, it overrides - * the PKCS 5 generation of the IV. - * - * the returned SECAlgorithmID should be destroyed using - * SECOID_DestroyAlgorithmID - */ -SECAlgorithmID * -SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm, - SECItem *salt, - int iteration) -{ - PRArenaPool *poolp = NULL; - SECAlgorithmID *algid, *ret_algid; - SECItem der_param; - SECStatus rv = SECFailure; - SEC_PKCS5PBEParameter *pbe_param; - - if(iteration <= 0) { - return NULL; - } - - der_param.data = NULL; - der_param.len = 0; - - /* generate the parameter */ - pbe_param = sec_pkcs5_create_pbe_parameter(algorithm, salt, iteration); - if(!pbe_param) { - return NULL; - } - - poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if(!poolp) { - sec_pkcs5_destroy_pbe_param(pbe_param); - return NULL; - } - - /* generate the algorithm id */ - algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID)); - if(algid != NULL) { - void *dummy; - if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { - dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, - SEC_PKCS5PBEParameterTemplate); - } else { - dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, - SEC_V2PKCS12PBEParameterTemplate); - } - - if(dummy) { - rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param); - } - } - - ret_algid = NULL; - if(algid != NULL) { - ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID)); - if(ret_algid != NULL) { - rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid); - if(rv != SECSuccess) { - SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE); - ret_algid = NULL; - } - } - } - - if(poolp != NULL) { - PORT_FreeArena(poolp, PR_TRUE); - algid = NULL; - } - - sec_pkcs5_destroy_pbe_param(pbe_param); - - return ret_algid; -} - -SECStatus -pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech) -{ - CK_PBE_PARAMS *pbe_params = NULL; - SEC_PKCS5PBEParameter p5_param; - SECItem *salt = NULL; - SECOidTag algorithm = SECOID_GetAlgorithmTag(algid); - PRArenaPool *arena = NULL; - SECStatus rv = SECFailure; - int iv_len; - - - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) { - goto loser; - } - iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm)); - if (iv_len < 0) { - goto loser; - } - - if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { - rv = SEC_ASN1DecodeItem(arena, &p5_param, - SEC_V2PKCS12PBEParameterTemplate, &algid->parameters); - } else { - rv = SEC_ASN1DecodeItem(arena,&p5_param,SEC_PKCS5PBEParameterTemplate, - &algid->parameters); - } - - if (rv != SECSuccess) { - goto loser; - } - - salt = &p5_param.salt; - - pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)+ - salt->len+iv_len); - if (pbe_params == NULL) { - goto loser; - } - - /* get salt */ - pbe_params->pSalt = ((CK_CHAR_PTR) pbe_params)+sizeof(CK_PBE_PARAMS); - if (iv_len) { - pbe_params->pInitVector = ((CK_CHAR_PTR) pbe_params)+ - sizeof(CK_PBE_PARAMS)+salt->len; - } - PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); - pbe_params->ulSaltLen = (CK_ULONG) salt->len; - - /* get iteration count */ - pbe_params->ulIteration = (CK_ULONG) DER_GetInteger(&p5_param.iteration); - - /* copy into the mechanism sec item */ - mech->data = (unsigned char *)pbe_params; - mech->len = sizeof(*pbe_params); - if (arena) { - PORT_FreeArena(arena,PR_TRUE); - } - return SECSuccess; - -loser: - if (pbe_params) { - PORT_Free(pbe_params); - } - if (arena) { - PORT_FreeArena(arena,PR_TRUE); - } - return SECFailure; -} - -SECStatus -PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena, - SECAlgorithmID *algId) -{ - CK_PBE_PARAMS *pbe_param; - SECItem pbeSalt; - SECAlgorithmID *pbeAlgID = NULL; - SECStatus rv; - - if(!param || !algId) { - return SECFailure; - } - - pbe_param = (CK_PBE_PARAMS *)param->data; - pbeSalt.data = (unsigned char *)pbe_param->pSalt; - pbeSalt.len = pbe_param->ulSaltLen; - pbeAlgID = SEC_PKCS5CreateAlgorithmID(algTag, &pbeSalt, - (int)pbe_param->ulIteration); - if(!pbeAlgID) { - return SECFailure; - } - - rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID); - SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE); - return rv; -} - -PBEBitGenContext * -PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose, - SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded, - unsigned int iterations) -{ - SECItem *context = NULL; - SECItem mechItem; - CK_PBE_PARAMS pbe_params; - CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; - PK11SlotInfo *slot; - PK11SymKey *symKey = NULL; - unsigned char ivData[8]; - - - /* use the purpose to select the low level keygen algorithm */ - switch (bitGenPurpose) { - case pbeBitGenIntegrityKey: - switch (hashAlgorithm) { - case SEC_OID_SHA1: - mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC; - break; - case SEC_OID_MD2: - mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN; - break; - case SEC_OID_MD5: - mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN; - break; - default: - break; - } - break; - case pbeBitGenCipherIV: - if (bitsNeeded > 64) { - break; - } - if (hashAlgorithm != SEC_OID_SHA1) { - break; - } - mechanism = CKM_PBE_SHA1_DES3_EDE_CBC; - break; - case pbeBitGenCipherKey: - if (hashAlgorithm != SEC_OID_SHA1) { - break; - } - switch (bitsNeeded) { - case 40: - mechanism = CKM_PBE_SHA1_RC4_40; - break; - case 128: - mechanism = CKM_PBE_SHA1_RC4_128; - break; - default: - break; - } - case pbeBitGenIDNull: - break; - } - - if (mechanism == CKM_INVALID_MECHANISM) { - /* we should set an error, but this is a depricated function, and - * we are keeping bug for bug compatibility;)... */ - return NULL; - } - - pbe_params.pInitVector = ivData; - pbe_params.pPassword = pwitem->data; - pbe_params.ulPasswordLen = pwitem->len; - pbe_params.pSalt = salt->data; - pbe_params.ulSaltLen = salt->len; - pbe_params.ulIteration = iterations; - mechItem.data = (unsigned char *) &pbe_params; - mechItem.len = sizeof(pbe_params); - - - slot = PK11_GetInternalSlot(); - symKey = PK11_RawPBEKeyGen(slot,mechanism, - &mechItem, pwitem, PR_FALSE, NULL); - PK11_FreeSlot(slot); - if (symKey != NULL) { - if (bitGenPurpose == pbeBitGenCipherIV) { - /* NOTE: this assumes that bitsNeeded is a multiple of 8! */ - SECItem ivItem; - - ivItem.data = ivData; - ivItem.len = bitsNeeded/8; - context = SECITEM_DupItem(&ivItem); - } else { - SECItem *keyData; - PK11_ExtractKeyValue(symKey); - keyData = PK11_GetKeyData(symKey); - - /* assert bitsNeeded with length? */ - if (keyData) { - context = SECITEM_DupItem(keyData); - } - } - PK11_FreeSymKey(symKey); - } - - return (PBEBitGenContext *)context; -} - -SECItem * -PBE_GenerateBits(PBEBitGenContext *context) -{ - return (SECItem *)context; -} - -void -PBE_DestroyContext(PBEBitGenContext *context) -{ - SECITEM_FreeItem((SECItem *)context,PR_TRUE); -} - -SECItem * -SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES) -{ - SECItem mechItem; - SECOidTag algorithm = SECOID_GetAlgorithmTag(algid); - CK_PBE_PARAMS *pbe_params; - CK_MECHANISM_TYPE mechanism; - SECItem *iv = NULL; - SECStatus rv; - int iv_len; - PK11SlotInfo *slot; - PK11SymKey *symKey; - - rv = pbe_PK11AlgidToParam(algid,&mechItem); - if (rv != SECSuccess) { - return NULL; - } - - mechanism = PK11_AlgtagToMechanism(algorithm); - iv_len = PK11_GetIVLength(mechanism); - pbe_params = (CK_PBE_PARAMS_PTR)mechItem.data; - - slot = PK11_GetInternalSlot(); - symKey = PK11_RawPBEKeyGen(slot,mechanism, - &mechItem, pwitem, faulty3DES,NULL); - PK11_FreeSlot(slot); - - if (symKey) { - SECItem tmp; - - tmp.data = pbe_params->pInitVector; - tmp.len = iv_len; - iv = SECITEM_DupItem(&tmp); - PK11_FreeSymKey(symKey); - } - - if (mechItem.data) { - PORT_ZFree(mechItem.data,mechItem.len); - } - - return iv; -} - -/* - * Subs from nss 3.x that are depricated - */ -PBEBitGenContext * -__PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose, - SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded, - unsigned int iterations) -{ - PORT_Assert("__PBE_CreateContext is Depricated" == NULL); - return NULL; -} - -SECItem * -__PBE_GenerateBits(PBEBitGenContext *context) -{ - PORT_Assert("__PBE_GenerateBits is Depricated" == NULL); - return NULL; -} - -void -__PBE_DestroyContext(PBEBitGenContext *context) -{ - PORT_Assert("__PBE_DestroyContext is Depricated" == NULL); -} - -SECStatus -RSA_FormatBlock(SECItem *result, unsigned modulusLen, - int blockType, SECItem *data) -{ - PORT_Assert("RSA_FormatBlock is Depricated" == NULL); - return SECFailure; -} - diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c deleted file mode 100644 index 991edba57..000000000 --- a/security/nss/lib/pk11wrap/pk11pk12.c +++ /dev/null @@ -1,550 +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. - * - * 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. - */ -/* - * This file PKCS #12 fuctions that should really be moved to the - * PKCS #12 directory, however we can't do that in a point release - * because that will break binary compatibility, so we keep them here for now. - */ - -#include "seccomon.h" -#include "secmod.h" -#include "secmodi.h" -#include "pkcs11.h" -#include "pk11func.h" -#include "secitem.h" -#include "key.h" -#include "secoid.h" -#include "secasn1.h" -#include "secerr.h" - - - -/* These data structures should move to a common .h file shared between the - * wrappers and the pkcs 12 code. */ - -/* -** RSA Raw Private Key structures -*/ - -/* member names from PKCS#1, section 7.2 */ -struct SECKEYRSAPrivateKeyStr { - PRArenaPool * arena; - SECItem version; - SECItem modulus; - SECItem publicExponent; - SECItem privateExponent; - SECItem prime1; - SECItem prime2; - SECItem exponent1; - SECItem exponent2; - SECItem coefficient; -}; -typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey; - - -/* -** DSA Raw Private Key structures -*/ - -struct SECKEYDSAPrivateKeyStr { - SECKEYPQGParams params; - SECItem privateValue; -}; -typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey; - -/* -** Diffie-Hellman Raw Private Key structures -** Structure member names suggested by PKCS#3. -*/ -struct SECKEYDHPrivateKeyStr { - PRArenaPool * arena; - SECItem prime; - SECItem base; - SECItem privateValue; -}; -typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey; - -/* -** raw private key object -*/ -struct SECKEYRawPrivateKeyStr { - PLArenaPool *arena; - KeyType keyType; - union { - SECKEYRSAPrivateKey rsa; - SECKEYDSAPrivateKey dsa; - SECKEYDHPrivateKey dh; - } u; -}; -typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey; - - -/* ASN1 Templates for new decoder/encoder */ -/* - * Attribute value for PKCS8 entries (static?) - */ -const SEC_ASN1Template SECKEY_AttributeTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SECKEYAttribute) }, - { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) }, - { SEC_ASN1_SET_OF, offsetof(SECKEYAttribute, attrValue), - SEC_AnyTemplate }, - { 0 } -}; - -const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = { - { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate }, -}; - -const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) }, - { SEC_ASN1_INLINE, offsetof(SECKEYPrivateKeyInfo,algorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(SECKEYPrivateKeyInfo,attributes), - SECKEY_SetOfAttributeTemplate }, - { 0 } -}; - -const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = { - { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate } -}; - -const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.modulus) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.publicExponent) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.privateExponent) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime1) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime2) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent1) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent2) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.coefficient) }, - { 0 } -}; - -const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dsa.privateValue) }, -}; - -const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.privateValue) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.base) }, - { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.prime) }, -}; - -const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) }, - { SEC_ASN1_INLINE, - offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm), - SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_OCTET_STRING, - offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) }, - { 0 } -}; - -const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = { - { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate } -}; - -SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate) -SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate) - -/* - * See bugzilla bug 125359 - * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, - * all of the templates above that en/decode into integers must be converted - * from ASN.1's signed integer type. This is done by marking either the - * source or destination (encoding or decoding, respectively) type as - * siUnsignedInteger. - */ - -static void -prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) -{ - key->u.rsa.modulus.type = siUnsignedInteger; - key->u.rsa.publicExponent.type = siUnsignedInteger; - key->u.rsa.privateExponent.type = siUnsignedInteger; - key->u.rsa.prime1.type = siUnsignedInteger; - key->u.rsa.prime2.type = siUnsignedInteger; - key->u.rsa.exponent1.type = siUnsignedInteger; - key->u.rsa.exponent2.type = siUnsignedInteger; - key->u.rsa.coefficient.type = siUnsignedInteger; -} - -static void -prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) -{ - key->u.dsa.privateValue.type = siUnsignedInteger; - key->u.dsa.params.prime.type = siUnsignedInteger; - key->u.dsa.params.subPrime.type = siUnsignedInteger; - key->u.dsa.params.base.type = siUnsignedInteger; -} - -static void -prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) -{ - key->u.dh.privateValue.type = siUnsignedInteger; - key->u.dh.prime.type = siUnsignedInteger; - key->u.dh.base.type = siUnsignedInteger; -} - - -SECStatus -PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI, - SECItem *nickname, SECItem *publicValue, PRBool isPerm, - PRBool isPrivate, unsigned int keyUsage, void *wincx) -{ - return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI, - nickname, publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); -} - -SECStatus -PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, - SECItem *nickname, SECItem *publicValue, PRBool isPerm, - PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey** privk, - void *wincx) -{ - SECKEYPrivateKeyInfo *pki = NULL; - PRArenaPool *temparena = NULL; - SECStatus rv = SECFailure; - - temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo); - pki->arena = temparena; - - rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate, - derPKI); - if( rv != SECSuccess ) { - goto finish; - } - - rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, - publicValue, isPerm, isPrivate, keyUsage, privk, wincx); - -finish: - if( pki != NULL ) { - /* this zeroes the key and frees the arena */ - SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); - } - return rv; -} - -SECStatus -PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, - SECItem *nickname, SECItem *publicValue, PRBool isPerm, - PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk, - void *wincx) -{ - CK_BBOOL cktrue = CK_TRUE; - CK_BBOOL ckfalse = CK_FALSE; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_KEY_TYPE keyType = CKK_RSA; - CK_OBJECT_HANDLE objectID; - CK_ATTRIBUTE theTemplate[20]; - int templateCount = 0; - SECStatus rv = SECFailure; - PRArenaPool *arena; - CK_ATTRIBUTE *attrs; - CK_ATTRIBUTE *signedattr = NULL; - int signedcount = 0; - CK_ATTRIBUTE *ap; - SECItem *ck_id = NULL; - - arena = PORT_NewArena(2048); - if(!arena) { - return SECFailure; - } - - attrs = theTemplate; - - - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse, - sizeof(CK_BBOOL) ); attrs++; - PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse, - sizeof(CK_BBOOL) ); attrs++; - PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse, - sizeof(CK_BBOOL) ); attrs++; - - switch (lpk->keyType) { - case rsaKey: - PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? - &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; - PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? - &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; - PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? - &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; - PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, - (keyUsage & KU_DIGITAL_SIGNATURE) ? - &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; - ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus); - if (ck_id == NULL) { - goto loser; - } - PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; - if (nickname) { - PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); attrs++; - } - signedattr = attrs; - PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data, - lpk->u.rsa.modulus.len); attrs++; - PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, - lpk->u.rsa.publicExponent.data, - lpk->u.rsa.publicExponent.len); attrs++; - PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT, - lpk->u.rsa.privateExponent.data, - lpk->u.rsa.privateExponent.len); attrs++; - PK11_SETATTRS(attrs, CKA_PRIME_1, - lpk->u.rsa.prime1.data, - lpk->u.rsa.prime1.len); attrs++; - PK11_SETATTRS(attrs, CKA_PRIME_2, - lpk->u.rsa.prime2.data, - lpk->u.rsa.prime2.len); attrs++; - PK11_SETATTRS(attrs, CKA_EXPONENT_1, - lpk->u.rsa.exponent1.data, - lpk->u.rsa.exponent1.len); attrs++; - PK11_SETATTRS(attrs, CKA_EXPONENT_2, - lpk->u.rsa.exponent2.data, - lpk->u.rsa.exponent2.len); attrs++; - PK11_SETATTRS(attrs, CKA_COEFFICIENT, - lpk->u.rsa.coefficient.data, - lpk->u.rsa.coefficient.len); attrs++; - break; - case dsaKey: - /* To make our intenal PKCS #11 module work correctly with - * our database, we need to pass in the public key value for - * this dsa key. We have a netscape only CKA_ value to do this. - * Only send it to internal slots */ - if( publicValue == NULL ) { - goto loser; - } - if (PK11_IsInternal(slot)) { - PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, - publicValue->data, publicValue->len); attrs++; - } - PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL)); attrs++; - if(nickname) { - PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); - attrs++; - } - ck_id = PK11_MakeIDFromPubKey(publicValue); - if (ck_id == NULL) { - goto loser; - } - PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; - signedattr = attrs; - PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data, - lpk->u.dsa.params.prime.len); attrs++; - PK11_SETATTRS(attrs,CKA_SUBPRIME,lpk->u.dsa.params.subPrime.data, - lpk->u.dsa.params.subPrime.len); attrs++; - PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data, - lpk->u.dsa.params.base.len); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data, - lpk->u.dsa.privateValue.len); attrs++; - break; - case dhKey: - /* To make our intenal PKCS #11 module work correctly with - * our database, we need to pass in the public key value for - * this dh key. We have a netscape only CKA_ value to do this. - * Only send it to internal slots */ - if (PK11_IsInternal(slot)) { - PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, - publicValue->data, publicValue->len); attrs++; - } - PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); attrs++; - if(nickname) { - PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); - attrs++; - } - ck_id = PK11_MakeIDFromPubKey(publicValue); - if (ck_id == NULL) { - goto loser; - } - PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; - signedattr = attrs; - PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data, - lpk->u.dh.prime.len); attrs++; - PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data, - lpk->u.dh.base.len); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data, - lpk->u.dh.privateValue.len); attrs++; - break; - /* what about fortezza??? */ - default: - PORT_SetError(SEC_ERROR_BAD_KEY); - goto loser; - } - templateCount = attrs - theTemplate; - PORT_Assert(templateCount <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)); - PORT_Assert(signedattr != NULL); - signedcount = attrs - signedattr; - - for (ap=signedattr; signedcount; ap++, signedcount--) { - pk11_SignedToUnsigned(ap); - } - - rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, - theTemplate, templateCount, isPerm, &objectID); - - /* create and return a SECKEYPrivateKey */ - if( rv == SECSuccess && privk != NULL) { - *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx); - if( *privk == NULL ) { - rv = SECFailure; - } - } -loser: - if (ck_id) { - SECITEM_ZfreeItem(ck_id, PR_TRUE); - } - return rv; -} - -SECStatus -PK11_ImportPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, - SECItem *nickname, SECItem *publicValue, PRBool isPerm, - PRBool isPrivate, unsigned int keyUsage, void *wincx) -{ - return PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, - isPerm, isPrivate, keyUsage, NULL, wincx); -} - -SECStatus -PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, - SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue, - PRBool isPerm, PRBool isPrivate, unsigned int keyUsage, - SECKEYPrivateKey **privk, void *wincx) -{ - CK_KEY_TYPE keyType = CKK_RSA; - SECStatus rv = SECFailure; - SECKEYRawPrivateKey *lpk = NULL; - const SEC_ASN1Template *keyTemplate, *paramTemplate; - void *paramDest = NULL; - PRArenaPool *arena; - - arena = PORT_NewArena(2048); - if(!arena) { - return SECFailure; - } - - /* need to change this to use RSA/DSA keys */ - lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena, - sizeof(SECKEYRawPrivateKey)); - if(lpk == NULL) { - goto loser; - } - lpk->arena = arena; - - switch(SECOID_GetAlgorithmTag(&pki->algorithm)) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - prepare_rsa_priv_key_export_for_asn1(lpk); - keyTemplate = SECKEY_RSAPrivateKeyExportTemplate; - paramTemplate = NULL; - paramDest = NULL; - lpk->keyType = rsaKey; - keyType = CKK_RSA; - break; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - prepare_dsa_priv_key_export_for_asn1(lpk); - keyTemplate = SECKEY_DSAPrivateKeyExportTemplate; - paramTemplate = SECKEY_PQGParamsTemplate; - paramDest = &(lpk->u.dsa.params); - lpk->keyType = dsaKey; - keyType = CKK_DSA; - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: - if(!publicValue) { - goto loser; - } - prepare_dh_priv_key_export_for_asn1(lpk); - keyTemplate = SECKEY_DHPrivateKeyExportTemplate; - paramTemplate = NULL; - paramDest = NULL; - lpk->keyType = dhKey; - keyType = CKK_DH; - break; - - default: - keyTemplate = NULL; - paramTemplate = NULL; - paramDest = NULL; - break; - } - - if(!keyTemplate) { - goto loser; - } - - /* decode the private key and any algorithm parameters */ - rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey); - if(rv != SECSuccess) { - goto loser; - } - if(paramDest && paramTemplate) { - rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate, - &(pki->algorithm.parameters)); - if(rv != SECSuccess) { - goto loser; - } - } - - rv = PK11_ImportAndReturnPrivateKey(slot,lpk,nickname,publicValue, isPerm, - isPrivate, keyUsage, privk, wincx); - - -loser: - if (lpk!= NULL) { - PORT_FreeArena(arena, PR_TRUE); - } - - return rv; -} - -SECStatus -PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki, - SECItem *nickname, SECItem *publicValue, PRBool isPerm, - PRBool isPrivate, unsigned int keyUsage, void *wincx) -{ - return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, - publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); - -} - diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c deleted file mode 100644 index f58fd60cb..000000000 --- a/security/nss/lib/pk11wrap/pk11pqg.c +++ /dev/null @@ -1,374 +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-2001 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. - */ -/* Thse functions are stub functions which will get replaced with calls through - * PKCS #11. - */ - -#include "pk11func.h" -#include "secmod.h" -#include "secmodi.h" -#include "pkcs11t.h" -#include "pk11pqg.h" -#include "secerr.h" - - -/* Generate PQGParams and PQGVerify structs. - * Length of P specified by j. Length of h will match length of P. - * Length of SEED in bytes specified in seedBytes. - * seedBbytes must be in the range [20..255] or an error will result. - */ -extern SECStatus -PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, - PQGParams **pParams, PQGVerify **pVfy) -{ - PK11SlotInfo *slot = NULL; - CK_ATTRIBUTE genTemplate[5]; - CK_ATTRIBUTE *attrs = genTemplate; - int count = sizeof(genTemplate)/sizeof(genTemplate[0]); - CK_MECHANISM mechanism; - CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE; - CK_RV crv; - CK_BBOOL cktrue = CK_TRUE; - CK_ATTRIBUTE pTemplate[] = { - { CKA_PRIME, NULL, 0 }, - { CKA_SUBPRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - }; - CK_ATTRIBUTE vTemplate[] = { - { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, - { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, - { CKA_NETSCAPE_PQG_H, NULL, 0 }, - }; - int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]); - int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]); - PRArenaPool *parena = NULL; - PRArenaPool *varena = NULL; - PQGParams *params = NULL; - PQGVerify *verify = NULL; - CK_ULONG primeBits = j; - CK_ULONG seedBits = seedBytes*8; - - *pParams = NULL; - *pVfy = NULL; - - PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++; - if (seedBits != 0) { - PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS, - &seedBits, sizeof(seedBits)); attrs++; - } - count = attrs - genTemplate; - PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); - - slot = PK11_GetInternalSlot(); - if (slot == NULL) { - /* set error */ - goto loser; - } - - /* Initialize the Key Gen Mechanism */ - mechanism.mechanism = CKM_DSA_PARAMETER_GEN; - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, - &mechanism, genTemplate, count, &objectID); - PK11_ExitSlotMonitor(slot); - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - goto loser; - } - - parena = PORT_NewArena(60); - crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - goto loser; - } - - - params = (PQGParams *)PORT_ArenaAlloc(parena,sizeof(PQGParams)); - if (params == NULL) { - goto loser; - } - - /* fill in Params */ - params->arena = parena; - params->prime.data = pTemplate[0].pValue; - params->prime.len = pTemplate[0].ulValueLen; - params->subPrime.data = pTemplate[1].pValue; - params->subPrime.len = pTemplate[1].ulValueLen; - params->base.data = pTemplate[2].pValue; - params->base.len = pTemplate[2].ulValueLen; - - - varena = PORT_NewArena(60); - crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - goto loser; - } - - - verify = (PQGVerify *)PORT_ArenaAlloc(varena,sizeof(PQGVerify)); - if (verify == NULL) { - goto loser; - } - /* fill in Params */ - verify->arena = varena; - verify->counter = (unsigned int)(*(CK_ULONG*)vTemplate[0].pValue); - verify->seed.data = vTemplate[1].pValue; - verify->seed.len = vTemplate[1].ulValueLen; - verify->h.data = vTemplate[2].pValue; - verify->h.len = vTemplate[2].ulValueLen; - - PK11_DestroyObject(slot,objectID); - PK11_FreeSlot(slot); - - *pParams = params; - *pVfy = verify; - - return SECSuccess; - -loser: - if (objectID != CK_INVALID_HANDLE) { - PK11_DestroyObject(slot,objectID); - } - if (parena != NULL) { - PORT_FreeArena(parena,PR_FALSE); - } - if (varena != NULL) { - PORT_FreeArena(varena,PR_FALSE); - } - if (slot) { - PK11_FreeSlot(slot); - } - return SECFailure; -} - -/* Generate PQGParams and PQGVerify structs. - * Length of seed and length of h both equal length of P. - * All lengths are specified by "j", according to the table above. - */ -extern SECStatus -PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) -{ - return PK11_PQG_ParamGenSeedLen(j, 0, pParams, pVfy); -} - -/* Test PQGParams for validity as DSS PQG values. - * If vfy is non-NULL, test PQGParams to make sure they were generated - * using the specified seed, counter, and h values. - * - * Return value indicates whether Verification operation ran succesfully - * to completion, but does not indicate if PQGParams are valid or not. - * If return value is SECSuccess, then *pResult has these meanings: - * SECSuccess: PQGParams are valid. - * SECFailure: PQGParams are invalid. - */ - -extern SECStatus -PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy, - SECStatus *result) -{ - CK_ATTRIBUTE keyTempl[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_KEY_TYPE, NULL, 0 }, - { CKA_PRIME, NULL, 0 }, - { CKA_SUBPRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - { CKA_TOKEN, NULL, 0 }, - { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, - { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, - { CKA_NETSCAPE_PQG_H, NULL, 0 }, - }; - CK_ATTRIBUTE *attrs; - CK_BBOOL ckfalse = CK_FALSE; - CK_OBJECT_CLASS class = CKO_KG_PARAMETERS; - CK_KEY_TYPE keyType = CKK_DSA; - SECStatus rv = SECSuccess; - PK11SlotInfo *slot; - int keyCount; - CK_OBJECT_HANDLE objectID; - CK_ULONG counter; - CK_RV crv; - - attrs = keyTempl; - PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; - PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, - params->prime.len); attrs++; - PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, - params->subPrime.len); attrs++; - PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++; - if (vfy) { - counter = vfy->counter; - PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, - &counter, sizeof(counter)); attrs++; - PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, - vfy->seed.data, vfy->seed.len); attrs++; - PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, - vfy->h.data, vfy->h.len); attrs++; - } - - keyCount = attrs - keyTempl; - PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0])); - - - slot = PK11_GetInternalSlot(); - if (slot == NULL) { - return SECFailure; - } - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount, - &objectID); - PK11_ExitSlotMonitor(slot); - - /* throw away the keys, we only wanted the return code */ - PK11_DestroyObject(slot,objectID); - PK11_FreeSlot(slot); - - *result = SECSuccess; - if (crv == CKR_ATTRIBUTE_VALUE_INVALID) { - *result = SECFailure; - } else if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - rv = SECFailure; - } - return rv; - -} - - - -/************************************************************************** - * Free the PQGParams struct and the things it points to. * - **************************************************************************/ -extern void -PK11_PQG_DestroyParams(PQGParams *params) { - PQG_DestroyParams(params); - return; -} - -/************************************************************************** - * Free the PQGVerify struct and the things it points to. * - **************************************************************************/ -extern void -PK11_PQG_DestroyVerify(PQGVerify *vfy) { - PQG_DestroyVerify(vfy); - return; -} - -/************************************************************************** - * Return a pointer to a new PQGParams struct that is constructed from * - * copies of the arguments passed in. * - * Return NULL on failure. * - **************************************************************************/ -extern PQGParams * -PK11_PQG_NewParams(const SECItem * prime, const SECItem * subPrime, - const SECItem * base) { - return PQG_NewParams(prime, subPrime, base); -} - - -/************************************************************************** - * Fills in caller's "prime" SECItem with the prime value in params. - * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE); - **************************************************************************/ -extern SECStatus -PK11_PQG_GetPrimeFromParams(const PQGParams *params, SECItem * prime) { - return PQG_GetPrimeFromParams(params, prime); -} - - -/************************************************************************** - * Fills in caller's "subPrime" SECItem with the prime value in params. - * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE); - **************************************************************************/ -extern SECStatus -PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, SECItem * subPrime) { - return PQG_GetSubPrimeFromParams(params, subPrime); -} - - -/************************************************************************** - * Fills in caller's "base" SECItem with the base value in params. - * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE); - **************************************************************************/ -extern SECStatus -PK11_PQG_GetBaseFromParams(const PQGParams *params, SECItem *base) { - return PQG_GetBaseFromParams(params, base); -} - - -/************************************************************************** - * Return a pointer to a new PQGVerify struct that is constructed from * - * copies of the arguments passed in. * - * Return NULL on failure. * - **************************************************************************/ -extern PQGVerify * -PK11_PQG_NewVerify(unsigned int counter, const SECItem * seed, - const SECItem * h) { - return PQG_NewVerify(counter, seed, h); -} - - -/************************************************************************** - * Returns "counter" value from the PQGVerify. - **************************************************************************/ -extern unsigned int -PK11_PQG_GetCounterFromVerify(const PQGVerify *verify) { - return PQG_GetCounterFromVerify(verify); -} - -/************************************************************************** - * Fills in caller's "seed" SECItem with the seed value in verify. - * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE); - **************************************************************************/ -extern SECStatus -PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, SECItem *seed) { - return PQG_GetSeedFromVerify(verify, seed); -} - - -/************************************************************************** - * Fills in caller's "h" SECItem with the h value in verify. - * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE); - **************************************************************************/ -extern SECStatus -PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h) { - return PQG_GetHFromVerify(verify, h); -} diff --git a/security/nss/lib/pk11wrap/pk11pqg.h b/security/nss/lib/pk11wrap/pk11pqg.h deleted file mode 100644 index 20becf821..000000000 --- a/security/nss/lib/pk11wrap/pk11pqg.h +++ /dev/null @@ -1,153 +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-2001 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. - */ -/* Thse functions are stub functions which will get replaced with calls through - * PKCS #11. - */ - -#ifndef _PK11PQG_H_ -#define _PK11PQG_H_ 1 - -#include "blapit.h" -#include "pqgutil.h" - -SEC_BEGIN_PROTOS - -/* Generate PQGParams and PQGVerify structs. - * Length of seed and length of h both equal length of P. - * All lengths are specified by "j", according to the table above. - */ -extern SECStatus PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, - PQGVerify **pVfy); - -/* Generate PQGParams and PQGVerify structs. - * Length of P specified by j. Length of h will match length of P. - * Length of SEED in bytes specified in seedBytes. - * seedBbytes must be in the range [20..255] or an error will result. - */ -extern SECStatus PK11_PQG_ParamGenSeedLen( unsigned int j, - unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy); - -/* Test PQGParams for validity as DSS PQG values. - * If vfy is non-NULL, test PQGParams to make sure they were generated - * using the specified seed, counter, and h values. - * - * Return value indicates whether Verification operation ran succesfully - * to completion, but does not indicate if PQGParams are valid or not. - * If return value is SECSuccess, then *pResult has these meanings: - * SECSuccess: PQGParams are valid. - * SECFailure: PQGParams are invalid. - * - * Verify the following 12 facts about PQG counter SEED g and h - * 1. Q is 160 bits long. - * 2. P is one of the 9 valid lengths. - * 3. G < P - * 4. P % Q == 1 - * 5. Q is prime - * 6. P is prime - * Steps 7-12 are done only if the optional PQGVerify is supplied. - * 7. counter < 4096 - * 8. g >= 160 and g < 2048 (g is length of seed in bits) - * 9. Q generated from SEED matches Q in PQGParams. - * 10. P generated from (L, counter, g, SEED, Q) matches P in PQGParams. - * 11. 1 < h < P-1 - * 12. G generated from h matches G in PQGParams. - */ - -extern SECStatus PK11_PQG_VerifyParams(const PQGParams *params, - const PQGVerify *vfy, SECStatus *result); -extern void PK11_PQG_DestroyParams(PQGParams *params); -extern void PK11_PQG_DestroyVerify(PQGVerify *vfy); - -/************************************************************************** - * Return a pointer to a new PQGParams struct that is constructed from * - * copies of the arguments passed in. * - * Return NULL on failure. * - **************************************************************************/ -extern PQGParams * PK11_PQG_NewParams(const SECItem * prime, const - SECItem * subPrime, const SECItem * base); - - -/************************************************************************** - * Fills in caller's "prime" SECItem with the prime value in params. - * Contents can be freed by calling SECITEM_FreeItem(prime, PR_FALSE); - **************************************************************************/ -extern SECStatus PK11_PQG_GetPrimeFromParams(const PQGParams *params, - SECItem * prime); - - -/************************************************************************** - * Fills in caller's "subPrime" SECItem with the prime value in params. - * Contents can be freed by calling SECITEM_FreeItem(subPrime, PR_FALSE); - **************************************************************************/ -extern SECStatus PK11_PQG_GetSubPrimeFromParams(const PQGParams *params, - SECItem * subPrime); - - -/************************************************************************** - * Fills in caller's "base" SECItem with the base value in params. - * Contents can be freed by calling SECITEM_FreeItem(base, PR_FALSE); - **************************************************************************/ -extern SECStatus PK11_PQG_GetBaseFromParams(const PQGParams *params, - SECItem *base); - - -/************************************************************************** - * Return a pointer to a new PQGVerify struct that is constructed from * - * copies of the arguments passed in. * - * Return NULL on failure. * - **************************************************************************/ -extern PQGVerify * PK11_PQG_NewVerify(unsigned int counter, - const SECItem * seed, const SECItem * h); - - -/************************************************************************** - * Returns "counter" value from the PQGVerify. - **************************************************************************/ -extern unsigned int PK11_PQG_GetCounterFromVerify(const PQGVerify *verify); - -/************************************************************************** - * Fills in caller's "seed" SECItem with the seed value in verify. - * Contents can be freed by calling SECITEM_FreeItem(seed, PR_FALSE); - **************************************************************************/ -extern SECStatus PK11_PQG_GetSeedFromVerify(const PQGVerify *verify, - SECItem *seed); - -/************************************************************************** - * Fills in caller's "h" SECItem with the h value in verify. - * Contents can be freed by calling SECITEM_FreeItem(h, PR_FALSE); - **************************************************************************/ -extern SECStatus PK11_PQG_GetHFromVerify(const PQGVerify *verify, SECItem * h); - -SEC_END_PROTOS - -#endif diff --git a/security/nss/lib/pk11wrap/pk11sdr.c b/security/nss/lib/pk11wrap/pk11sdr.c deleted file mode 100644 index 630be0245..000000000 --- a/security/nss/lib/pk11wrap/pk11sdr.c +++ /dev/null @@ -1,295 +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): - * thayes@netscape.com - * - * 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. - * - * PKCS #11 Wrapper functions which handles authenticating to the card's - * choosing the best cards, etc. - */ - -#include "seccomon.h" -#include "secoid.h" -#include "secasn1.h" -#include "pkcs11.h" -#include "pk11func.h" -#include "pk11sdr.h" - -/* - * Data structure and template for encoding the result of an SDR operation - * This is temporary. It should include the algorithm ID of the encryption mechanism - */ -struct SDRResult -{ - SECItem keyid; - SECAlgorithmID alg; - SECItem data; -}; -typedef struct SDRResult SDRResult; - -static SEC_ASN1Template template[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof (SDRResult) }, - { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, keyid) }, - { SEC_ASN1_INLINE, offsetof(SDRResult, alg), SECOID_AlgorithmIDTemplate }, - { SEC_ASN1_OCTET_STRING, offsetof(SDRResult, data) }, - { 0 } -}; - -static unsigned char keyID[] = { - 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 -}; - -static SECItem keyIDItem = { - 0, - keyID, - sizeof keyID -}; - -/* local utility function for padding an incoming data block - * to the mechanism block size. - */ -static SECStatus -padBlock(SECItem *data, int blockSize, SECItem *result) -{ - SECStatus rv = SECSuccess; - int padLength; - unsigned int i; - - result->data = 0; - result->len = 0; - - /* This algorithm always adds to the block (to indicate the number - * of pad bytes). So allocate a block large enough. - */ - padLength = blockSize - (data->len % blockSize); - result->len = data->len + padLength; - result->data = (unsigned char *)PORT_Alloc(result->len); - - /* Copy the data */ - PORT_Memcpy(result->data, data->data, data->len); - - /* Add the pad values */ - for(i = data->len; i < result->len; i++) - result->data[i] = (unsigned char)padLength; - - return rv; -} - -static SECStatus -unpadBlock(SECItem *data, int blockSize, SECItem *result) -{ - SECStatus rv = SECSuccess; - int padLength; - - result->data = 0; - result->len = 0; - - /* Remove the padding from the end if the input data */ - if (data->len == 0 || data->len % blockSize != 0) { rv = SECFailure; goto loser; } - - padLength = data->data[data->len-1]; - if (padLength > blockSize) { rv = SECFailure; goto loser; } - - result->len = data->len - padLength; - result->data = (unsigned char *)PORT_Alloc(result->len); - if (!result->data) { rv = SECFailure; goto loser; } - - PORT_Memcpy(result->data, data->data, result->len); - -loser: - return rv; -} - -/* - * PK11SDR_Encrypt - * Encrypt a block of data using the symmetric key identified. The result - * is an ASN.1 (DER) encoded block of keyid, params and data. - */ -SECStatus -PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx) -{ - SECStatus rv = SECSuccess; - PK11SlotInfo *slot = 0; - PK11SymKey *key = 0; - SECItem *params = 0; - PK11Context *ctx = 0; - CK_MECHANISM_TYPE type; - SDRResult sdrResult; - SECItem paddedData; - SECItem *pKeyID; - PLArenaPool *arena = 0; - - /* Initialize */ - paddedData.len = 0; - paddedData.data = 0; - - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (!arena) { rv = SECFailure; goto loser; } - - /* 1. Locate the requested keyid, or the default key (which has a keyid) - * 2. Create an encryption context - * 3. Encrypt - * 4. Encode the results (using ASN.1) - */ - - slot = PK11_GetInternalKeySlot(); - if (!slot) { rv = SECFailure; goto loser; } - - /* Use triple-DES */ - type = CKM_DES3_CBC; - - /* - * Login to the internal token before we look for the key, otherwise we - * won't find it. - */ - rv = PK11_Authenticate(slot, PR_TRUE, cx); - if (rv != SECSuccess) goto loser; - - /* Find the key to use */ - pKeyID = keyid; - if (pKeyID->len == 0) { - pKeyID = &keyIDItem; /* Use default value */ - - /* Try to find the key */ - key = PK11_FindFixedKey(slot, type, pKeyID, cx); - - /* If the default key doesn't exist yet, try to create it */ - if (!key) key = PK11_GenDES3TokenKey(slot, pKeyID, cx); - } else { - key = PK11_FindFixedKey(slot, type, pKeyID, cx); - } - - if (!key) { rv = SECFailure; goto loser; } - - params = PK11_GenerateNewParam(type, key); - if (!params) { rv = SECFailure; goto loser; } - - ctx = PK11_CreateContextBySymKey(type, CKA_ENCRYPT, key, params); - if (!ctx) { rv = SECFailure; goto loser; } - - rv = padBlock(data, PK11_GetBlockSize(type, 0), &paddedData); - if (rv != SECSuccess) goto loser; - - sdrResult.data.len = paddedData.len; - sdrResult.data.data = (unsigned char *)PORT_ArenaAlloc(arena, sdrResult.data.len); - - rv = PK11_CipherOp(ctx, sdrResult.data.data, (int*)&sdrResult.data.len, sdrResult.data.len, - paddedData.data, paddedData.len); - if (rv != SECSuccess) goto loser; - - PK11_Finalize(ctx); - - sdrResult.keyid = *pKeyID; - - rv = PK11_ParamToAlgid(SEC_OID_DES_EDE3_CBC, params, arena, &sdrResult.alg); - if (rv != SECSuccess) goto loser; - - if (!SEC_ASN1EncodeItem(0, result, &sdrResult, template)) { rv = SECFailure; goto loser; } - -loser: - SECITEM_ZfreeItem(&paddedData, PR_FALSE); - if (arena) PORT_FreeArena(arena, PR_TRUE); - if (ctx) PK11_DestroyContext(ctx, PR_TRUE); - if (params) SECITEM_ZfreeItem(params, PR_TRUE); - if (key) PK11_FreeSymKey(key); - if (slot) PK11_FreeSlot(slot); - - return rv; -} - -/* - * PK11SDR_Decrypt - * Decrypt a block of data produced by PK11SDR_Encrypt. The key used is identified - * by the keyid field within the input. - */ -SECStatus -PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx) -{ - SECStatus rv = SECSuccess; - PK11SlotInfo *slot = 0; - PK11SymKey *key = 0; - PK11Context *ctx = 0; - CK_MECHANISM_TYPE type; - SDRResult sdrResult; - SECItem *params = 0; - SECItem paddedResult; - PLArenaPool *arena = 0; - - paddedResult.len = 0; - paddedResult.data = 0; - - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (!arena) { rv = SECFailure; goto loser; } - - /* Decode the incoming data */ - memset(&sdrResult, 0, sizeof sdrResult); - rv = SEC_ASN1DecodeItem(arena, &sdrResult, template, data); - if (rv != SECSuccess) goto loser; /* Invalid format */ - - /* Find the slot and key for the given keyid */ - slot = PK11_GetInternalKeySlot(); - if (!slot) { rv = SECFailure; goto loser; } - - /* Use triple-DES (Should look up the algorithm) */ - type = CKM_DES3_CBC; - key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx); - if (!key) { rv = SECFailure; goto loser; } - - /* Get the parameter values from the data */ - params = PK11_ParamFromAlgid(&sdrResult.alg); - if (!params) { rv = SECFailure; goto loser; } - - ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params); - if (!ctx) { rv = SECFailure; goto loser; } - - paddedResult.len = sdrResult.data.len; - paddedResult.data = PORT_ArenaAlloc(arena, paddedResult.len); - - rv = PK11_CipherOp(ctx, paddedResult.data, (int*)&paddedResult.len, paddedResult.len, - sdrResult.data.data, sdrResult.data.len); - if (rv != SECSuccess) goto loser; - - PK11_Finalize(ctx); - - /* Remove the padding */ - rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result); - if (rv) goto loser; - -loser: - /* SECITEM_ZfreeItem(&paddedResult, PR_FALSE); */ - if (arena) PORT_FreeArena(arena, PR_TRUE); - if (ctx) PK11_DestroyContext(ctx, PR_TRUE); - if (key) PK11_FreeSymKey(key); - if (params) SECITEM_ZfreeItem(params, PR_TRUE); - if (slot) PK11_FreeSlot(slot); - - return rv; -} diff --git a/security/nss/lib/pk11wrap/pk11sdr.h b/security/nss/lib/pk11wrap/pk11sdr.h deleted file mode 100644 index 652098cad..000000000 --- a/security/nss/lib/pk11wrap/pk11sdr.h +++ /dev/null @@ -1,59 +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. - * - * PKCS #11 Wrapper functions which handles authenticating to the card's - * choosing the best cards, etc. - */ - -#ifndef _PK11SDR_H_ -#define _PK11SDR_H_ - -#include "seccomon.h" - -SEC_BEGIN_PROTOS - -/* - * PK11SDR_Encrypt - encrypt data using the specified key id or SDR default - * - */ -SECStatus -PK11SDR_Encrypt(SECItem *keyid, SECItem *data, SECItem *result, void *cx); - -/* - * PK11SDR_Decrypt - decrypt data previously encrypted with PK11SDR_Encrypt - */ -SECStatus -PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx); - -SEC_END_PROTOS - -#endif diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c deleted file mode 100644 index 6dc7c3359..000000000 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ /dev/null @@ -1,5095 +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): - * Dr Stephen Henson <stephen.henson@gemplus.com> - * - * 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. - */ -/* - * This file implements the Symkey wrapper and the PKCS context - * Interfaces. - */ - -#include "seccomon.h" -#include "secmod.h" -#include "nssilock.h" -#include "secmodi.h" -#include "pkcs11.h" -#include "pk11func.h" -#include "secitem.h" -#include "key.h" -#include "secoid.h" -#include "secasn1.h" -#include "sechash.h" -#include "cert.h" -#include "secerr.h" -#include "secpkcs5.h" - -#define PAIRWISE_SECITEM_TYPE siBuffer -#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */ -#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */ - -/* forward static declarations. */ -static PK11SymKey *pk11_DeriveWithTemplate(PK11SymKey *baseKey, - CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize, CK_ATTRIBUTE *userAttr, - unsigned int numAttrs); - - -/* - * strip leading zero's from key material - */ -void -pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib) { - char *ptr = (char *)attrib->pValue; - unsigned long len = attrib->ulValueLen; - - while (len && (*ptr == 0)) { - len--; - ptr++; - } - attrib->pValue = ptr; - attrib->ulValueLen = len; -} - -/* - * get a new session on a slot. If we run out of session, use the slot's - * 'exclusive' session. In this case owner becomes false. - */ -static CK_SESSION_HANDLE -pk11_GetNewSession(PK11SlotInfo *slot,PRBool *owner) -{ - CK_SESSION_HANDLE session; - *owner = PR_TRUE; - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - if ( PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION, - slot,pk11_notify,&session) != CKR_OK) { - *owner = PR_FALSE; - session = slot->session; - } - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - - return session; -} - -static void -pk11_CloseSession(PK11SlotInfo *slot,CK_SESSION_HANDLE session,PRBool owner) -{ - if (!owner) return; - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - (void) PK11_GETTAB(slot)->C_CloseSession(session); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); -} - - -SECStatus -PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session, - CK_ATTRIBUTE *theTemplate, int count, - PRBool token, CK_OBJECT_HANDLE *objectID) -{ - CK_SESSION_HANDLE rwsession; - CK_RV crv; - SECStatus rv = SECSuccess; - - rwsession = session; - if (rwsession == CK_INVALID_SESSION) { - if (token) { - rwsession = PK11_GetRWSession(slot); - } else { - rwsession = slot->session; - PK11_EnterSlotMonitor(slot); - } - } - crv = PK11_GETTAB(slot)->C_CreateObject(rwsession, theTemplate, - count,objectID); - if(crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - rv = SECFailure; - } - - if (session == CK_INVALID_SESSION) { - if (token) { - PK11_RestoreROSession(slot, rwsession); - } else { - PK11_ExitSlotMonitor(slot); - } - } - - return rv; -} - -static void -pk11_EnterKeyMonitor(PK11SymKey *symKey) { - if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe)) - PK11_EnterSlotMonitor(symKey->slot); -} - -static void -pk11_ExitKeyMonitor(PK11SymKey *symKey) { - if (!symKey->sessionOwner || !(symKey->slot->isThreadSafe)) - PK11_ExitSlotMonitor(symKey->slot); -} - - -static PK11SymKey * -pk11_getKeyFromList(PK11SlotInfo *slot) { - PK11SymKey *symKey = NULL; - - PK11_USE_THREADS(PZ_Lock(slot->freeListLock);) - if (slot->freeSymKeysHead) { - symKey = slot->freeSymKeysHead; - slot->freeSymKeysHead = symKey->next; - slot->keyCount--; - } - PK11_USE_THREADS(PZ_Unlock(slot->freeListLock);) - if (symKey) { - symKey->next = NULL; - if ((symKey->series != slot->series) || (!symKey->sessionOwner)) - symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner); - return symKey; - } - - symKey = (PK11SymKey *)PORT_ZAlloc(sizeof(PK11SymKey)); - if (symKey == NULL) { - return NULL; - } - symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner); - symKey->next = NULL; - return symKey; -} - -void -PK11_CleanKeyList(PK11SlotInfo *slot) -{ - PK11SymKey *symKey = NULL; - - while (slot->freeSymKeysHead) { - symKey = slot->freeSymKeysHead; - slot->freeSymKeysHead = symKey->next; - pk11_CloseSession(slot, symKey->session,symKey->sessionOwner); - PORT_Free(symKey); - }; - return; -} - -/* - * create a symetric key: - * Slot is the slot to create the key in. - * type is the mechainism type - */ -PK11SymKey * -PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx) -{ - - PK11SymKey *symKey = pk11_getKeyFromList(slot); - - - if (symKey == NULL) { - return NULL; - } - - symKey->type = type; - symKey->data.data = NULL; - symKey->data.len = 0; - symKey->owner = PR_TRUE; - symKey->objectID = CK_INVALID_HANDLE; - symKey->slot = slot; - symKey->series = slot->series; - symKey->cx = wincx; - symKey->size = 0; - symKey->refCount = 1; - symKey->origin = PK11_OriginNULL; - symKey->origin = PK11_OriginNULL; - PK11_ReferenceSlot(slot); - return symKey; -} - -/* - * destroy a symetric key - */ -void -PK11_FreeSymKey(PK11SymKey *symKey) -{ - PK11SlotInfo *slot; - PRBool freeit = PR_TRUE; - - if (PR_AtomicDecrement(&symKey->refCount) == 0) { - if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) { - pk11_EnterKeyMonitor(symKey); - (void) PK11_GETTAB(symKey->slot)-> - C_DestroyObject(symKey->session, symKey->objectID); - pk11_ExitKeyMonitor(symKey); - } - if (symKey->data.data) { - PORT_Memset(symKey->data.data, 0, symKey->data.len); - PORT_Free(symKey->data.data); - } - slot = symKey->slot; - PK11_USE_THREADS(PZ_Lock(slot->freeListLock);) - if (slot->keyCount < slot->maxKeyCount) { - symKey->next = slot->freeSymKeysHead; - slot->freeSymKeysHead = symKey; - slot->keyCount++; - symKey->slot = NULL; - freeit = PR_FALSE; - } - PK11_USE_THREADS(PZ_Unlock(slot->freeListLock);) - if (freeit) { - pk11_CloseSession(symKey->slot, symKey->session, - symKey->sessionOwner); - PORT_Free(symKey); - } - PK11_FreeSlot(slot); - } -} - -PK11SymKey * -PK11_ReferenceSymKey(PK11SymKey *symKey) -{ - PR_AtomicIncrement(&symKey->refCount); - return symKey; -} - -/* - * turn key handle into an appropriate key object - */ -PK11SymKey * -PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin, - CK_MECHANISM_TYPE type, CK_OBJECT_HANDLE keyID, PRBool owner, void *wincx) -{ - PK11SymKey *symKey; - - if (keyID == CK_INVALID_HANDLE) { - return NULL; - } - - symKey = PK11_CreateSymKey(slot,type,wincx); - if (symKey == NULL) { - return NULL; - } - - symKey->objectID = keyID; - symKey->origin = origin; - symKey->owner = owner; - - return symKey; -} - -/* - * turn key handle into an appropriate key object - */ -PK11SymKey * -PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type, - int series, void *wincx) -{ - PK11SymKey *symKey = NULL; - - if (slot->series != series) return NULL; - if (slot->refKeys[wrap] == CK_INVALID_HANDLE) return NULL; - if (type == CKM_INVALID_MECHANISM) type = slot->wrapMechanism; - - symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, - slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx); - return symKey; -} - -void -PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey) -{ - /* save the handle and mechanism for the wrapping key */ - /* mark the key and session as not owned by us to they don't get freed - * when the key goes way... that lets us reuse the key later */ - slot->refKeys[wrap] = wrapKey->objectID; - wrapKey->owner = PR_FALSE; - wrapKey->sessionOwner = PR_FALSE; - slot->wrapMechanism = wrapKey->type; -} - -CK_MECHANISM_TYPE -PK11_GetMechanism(PK11SymKey *symKey) -{ - return symKey->type; -} - -/* - * figure out if a key is still valid or if it is stale. - */ -PRBool -PK11_VerifyKeyOK(PK11SymKey *key) { - if (!PK11_IsPresent(key->slot)) { - return PR_FALSE; - } - return (PRBool)(key->series == key->slot->series); -} - -#define MAX_TEMPL_ATTRS 16 /* maximum attributes in template */ - -/* This mask includes all CK_FLAGs with an equivalent CKA_ attribute. */ -#define CKF_KEY_OPERATION_FLAGS 0x000e7b00UL - -static unsigned int -pk11_FlagsToAttributes(CK_FLAGS flags, CK_ATTRIBUTE *attrs, CK_BBOOL *ckTrue) -{ - - const static CK_ATTRIBUTE_TYPE attrTypes[12] = { - CKA_ENCRYPT, CKA_DECRYPT, 0 /* DIGEST */, CKA_SIGN, - CKA_SIGN_RECOVER, CKA_VERIFY, CKA_VERIFY_RECOVER, 0 /* GEN */, - 0 /* GEN PAIR */, CKA_WRAP, CKA_UNWRAP, CKA_DERIVE - }; - - const CK_ATTRIBUTE_TYPE *pType = attrTypes; - CK_ATTRIBUTE *attr = attrs; - CK_FLAGS test = CKF_ENCRYPT; - - - PR_ASSERT(!(flags & ~CKF_KEY_OPERATION_FLAGS)); - flags &= CKF_KEY_OPERATION_FLAGS; - - for (; flags && test <= CKF_DERIVE; test <<= 1, ++pType) { - if (test & flags) { - flags ^= test; - PK11_SETATTRS(attr, *pType, ckTrue, sizeof *ckTrue); - ++attr; - } - } - return (attr - attrs); -} - -static PK11SymKey * -pk11_ImportSymKeyWithTempl(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE *keyTemplate, - unsigned int templateCount, SECItem *key, void *wincx) -{ - PK11SymKey * symKey; - SECStatus rv; - - symKey = PK11_CreateSymKey(slot,type,wincx); - if (symKey == NULL) { - return NULL; - } - - symKey->size = key->len; - - PK11_SETATTRS(&keyTemplate[templateCount], CKA_VALUE, key->data, key->len); - templateCount++; - - if (SECITEM_CopyItem(NULL,&symKey->data,key) != SECSuccess) { - PK11_FreeSymKey(symKey); - return NULL; - } - - symKey->origin = origin; - - /* import the keys */ - rv = PK11_CreateNewObject(slot, symKey->session, keyTemplate, - templateCount, PR_FALSE, &symKey->objectID); - if ( rv != SECSuccess) { - PK11_FreeSymKey(symKey); - return NULL; - } - - return symKey; -} - -/* - * turn key bits into an appropriate key object - */ -PK11SymKey * -PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,void *wincx) -{ - PK11SymKey * symKey; - unsigned int templateCount = 0; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_BBOOL cktrue = CK_TRUE; /* sigh */ - CK_ATTRIBUTE keyTemplate[5]; - CK_ATTRIBUTE * attrs = keyTemplate; - - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; - PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); - - keyType = PK11_GetKeyType(type,key->len); - symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, keyTemplate, - templateCount, key, wincx); - return symKey; -} - - -/* - * turn key bits into an appropriate key object - */ -PK11SymKey * -PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, - CK_FLAGS flags, PRBool isPerm, void *wincx) -{ - PK11SymKey * symKey; - unsigned int templateCount = 0; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_BBOOL cktrue = CK_TRUE; /* sigh */ - CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; - CK_ATTRIBUTE * attrs = keyTemplate; - - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; - if (isPerm) { - PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(keyType) ); attrs++; - } - templateCount = attrs - keyTemplate; - templateCount += pk11_FlagsToAttributes(flags, attrs, &cktrue); - PR_ASSERT(templateCount+1 <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); - - keyType = PK11_GetKeyType(type,key->len); - symKey = pk11_ImportSymKeyWithTempl(slot, type, origin, keyTemplate, - templateCount, key, wincx); - if (isPerm) { - symKey->owner = PR_FALSE; - } - return symKey; -} - -/* - * import a public key into the desired slot - */ -CK_OBJECT_HANDLE -PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey, - PRBool isToken) -{ - CK_BBOOL cktrue = CK_TRUE; - CK_BBOOL ckfalse = CK_FALSE; - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_OBJECT_HANDLE objectID; - CK_ATTRIBUTE theTemplate[10]; - CK_ATTRIBUTE *signedattr = NULL; - CK_ATTRIBUTE *attrs = theTemplate; - int signedcount = 0; - int templateCount = 0; - SECStatus rv; - - /* if we already have an object in the desired slot, use it */ - if (!isToken && pubKey->pkcs11Slot == slot) { - return pubKey->pkcs11ID; - } - - /* free the existing key */ - if (pubKey->pkcs11Slot != NULL) { - PK11SlotInfo *oSlot = pubKey->pkcs11Slot; - PK11_EnterSlotMonitor(oSlot); - (void) PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session, - pubKey->pkcs11ID); - PK11_ExitSlotMonitor(oSlot); - PK11_FreeSlot(oSlot); - pubKey->pkcs11Slot = NULL; - } - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, isToken ? &cktrue : &ckfalse, - sizeof(CK_BBOOL) ); attrs++; - - /* now import the key */ - { - switch (pubKey->keyType) { - case rsaKey: - keyType = CKK_RSA; - PK11_SETATTRS(attrs, CKA_WRAP, &cktrue, sizeof(CK_BBOOL) ); attrs++; - PK11_SETATTRS(attrs, CKA_ENCRYPT, &cktrue, - sizeof(CK_BBOOL) ); attrs++; - PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); attrs++; - signedattr = attrs; - PK11_SETATTRS(attrs, CKA_MODULUS, pubKey->u.rsa.modulus.data, - pubKey->u.rsa.modulus.len); attrs++; - PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, - pubKey->u.rsa.publicExponent.data, - pubKey->u.rsa.publicExponent.len); attrs++; - break; - case dsaKey: - keyType = CKK_DSA; - PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++; - signedattr = attrs; - PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dsa.params.prime.data, - pubKey->u.dsa.params.prime.len); attrs++; - PK11_SETATTRS(attrs,CKA_SUBPRIME,pubKey->u.dsa.params.subPrime.data, - pubKey->u.dsa.params.subPrime.len); attrs++; - PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dsa.params.base.data, - pubKey->u.dsa.params.base.len); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dsa.publicValue.data, - pubKey->u.dsa.publicValue.len); attrs++; - break; - case fortezzaKey: - keyType = CKK_DSA; - PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++; - signedattr = attrs; - PK11_SETATTRS(attrs, CKA_PRIME,pubKey->u.fortezza.params.prime.data, - pubKey->u.fortezza.params.prime.len); attrs++; - PK11_SETATTRS(attrs,CKA_SUBPRIME, - pubKey->u.fortezza.params.subPrime.data, - pubKey->u.fortezza.params.subPrime.len);attrs++; - PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.fortezza.params.base.data, - pubKey->u.fortezza.params.base.len); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.fortezza.DSSKey.data, - pubKey->u.fortezza.DSSKey.len); attrs++; - break; - case dhKey: - keyType = CKK_DH; - PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++; - signedattr = attrs; - PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dh.prime.data, - pubKey->u.dh.prime.len); attrs++; - PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dh.base.data, - pubKey->u.dh.base.len); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dh.publicValue.data, - pubKey->u.dh.publicValue.len); attrs++; - break; - /* what about fortezza??? */ - default: - PORT_SetError( SEC_ERROR_BAD_KEY ); - return CK_INVALID_HANDLE; - } - - templateCount = attrs - theTemplate; - signedcount = attrs - signedattr; - PORT_Assert(templateCount <= (sizeof(theTemplate)/sizeof(CK_ATTRIBUTE))); - for (attrs=signedattr; signedcount; attrs++, signedcount--) { - pk11_SignedToUnsigned(attrs); - } - rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate, - templateCount, isToken, &objectID); - if ( rv != SECSuccess) { - return CK_INVALID_HANDLE; - } - } - - pubKey->pkcs11ID = objectID; - pubKey->pkcs11Slot = PK11_ReferenceSlot(slot); - - return objectID; -} - - -/* - * return the slot associated with a symetric key - */ -PK11SlotInfo * -PK11_GetSlotFromKey(PK11SymKey *symKey) -{ - return PK11_ReferenceSlot(symKey->slot); -} - -PK11SymKey * -PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID, - void *wincx) -{ - CK_ATTRIBUTE findTemp[4]; - CK_ATTRIBUTE *attrs; - CK_BBOOL ckTrue = CK_TRUE; - CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY; - int tsize = 0; - CK_OBJECT_HANDLE key_id; - - attrs = findTemp; - PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; - if (keyID) { - PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len); attrs++; - } - tsize = attrs - findTemp; - PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); - - key_id = pk11_FindObjectByTemplate(slot,findTemp,tsize); - if (key_id == CK_INVALID_HANDLE) { - return NULL; - } - return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id, - PR_FALSE, wincx); -} - -PK11SymKey * -PK11_ListFixedKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) -{ - CK_ATTRIBUTE findTemp[4]; - CK_ATTRIBUTE *attrs; - CK_BBOOL ckTrue = CK_TRUE; - CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY; - int tsize = 0; - int objCount = 0; - CK_OBJECT_HANDLE *key_ids; - PK11SymKey *nextKey = NULL; - PK11SymKey *topKey = NULL; - int i,len; - - attrs = findTemp; - PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++; - PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++; - if (nickname) { - len = PORT_Strlen(nickname)-1; - PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++; - } - tsize = attrs - findTemp; - PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); - - key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount); - if (key_ids == NULL) { - return NULL; - } - - for (i=0; i < objCount ; i++) { - nextKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, - CKM_INVALID_MECHANISM, key_ids[i], PR_FALSE, wincx); - if (nextKey) { - nextKey->next = topKey; - topKey = nextKey; - } - } - PORT_Free(key_ids); - return topKey; -} - -void * -PK11_GetWindow(PK11SymKey *key) -{ - return key->cx; -} - - -/* - * extract a symetric key value. NOTE: if the key is sensitive, we will - * not be able to do this operation. This function is used to move - * keys from one token to another */ -SECStatus -PK11_ExtractKeyValue(PK11SymKey *symKey) -{ - - if (symKey->data.data != NULL) return SECSuccess; - - if (symKey->slot == NULL) { - PORT_SetError( SEC_ERROR_INVALID_KEY ); - return SECFailure; - } - - return PK11_ReadAttribute(symKey->slot,symKey->objectID,CKA_VALUE,NULL, - &symKey->data); -} - -SECStatus -PK11_DeleteTokenSymKey(PK11SymKey *symKey) -{ - if (!PK11_IsPermObject(symKey->slot, symKey->objectID)) { - return SECFailure; - } - PK11_DestroyTokenObject(symKey->slot,symKey->objectID); - symKey->objectID = CK_INVALID_HANDLE; - return SECSuccess; -} - -SECItem * -__PK11_GetKeyData(PK11SymKey *symKey) -{ - return &symKey->data; -} - -SECItem * -PK11_GetKeyData(PK11SymKey *symKey) -{ - return __PK11_GetKeyData(symKey); -} - -/* - * take an attribute and copy it into a secitem - */ -static CK_RV -pk11_Attr2SecItem(PRArenaPool *arena, CK_ATTRIBUTE *attr, SECItem *item) -{ - item->data = NULL; - - (void)SECITEM_AllocItem(arena, item, attr->ulValueLen); - if (item->data == NULL) { - return CKR_HOST_MEMORY; - } - PORT_Memcpy(item->data, attr->pValue, item->len); - return CKR_OK; -} - -/* - * extract a public key from a slot and id - */ -SECKEYPublicKey * -PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id) -{ - CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; - PRArenaPool *arena; - PRArenaPool *tmp_arena; - SECKEYPublicKey *pubKey; - int templateCount = 0; - CK_KEY_TYPE pk11KeyType; - CK_RV crv; - CK_ATTRIBUTE template[8]; - CK_ATTRIBUTE *attrs= template; - CK_ATTRIBUTE *modulus,*exponent,*base,*prime,*subprime,*value; - - /* if we didn't know the key type, get it */ - if (keyType== nullKey) { - - pk11KeyType = PK11_ReadULongAttribute(slot,id,CKA_KEY_TYPE); - if (pk11KeyType == CK_UNAVAILABLE_INFORMATION) { - return NULL; - } - switch (pk11KeyType) { - case CKK_RSA: - keyType = rsaKey; - break; - case CKK_DSA: - keyType = dsaKey; - break; - case CKK_DH: - keyType = dhKey; - break; - default: - PORT_SetError( SEC_ERROR_BAD_KEY ); - return NULL; - } - } - - - /* now we need to create space for the public key */ - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) return NULL; - tmp_arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE); - if (tmp_arena == NULL) { - PORT_FreeArena (arena, PR_FALSE); - return NULL; - } - - - pubKey = (SECKEYPublicKey *) - PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); - if (pubKey == NULL) { - PORT_FreeArena (arena, PR_FALSE); - PORT_FreeArena (tmp_arena, PR_FALSE); - return NULL; - } - - pubKey->arena = arena; - pubKey->keyType = keyType; - pubKey->pkcs11Slot = PK11_ReferenceSlot(slot); - pubKey->pkcs11ID = id; - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, - sizeof(keyClass)); attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &pk11KeyType, - sizeof(pk11KeyType) ); attrs++; - switch (pubKey->keyType) { - case rsaKey: - modulus = attrs; - PK11_SETATTRS(attrs, CKA_MODULUS, NULL, 0); attrs++; - exponent = attrs; - PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, NULL, 0); attrs++; - - templateCount = attrs - template; - PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE)); - crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount); - if (crv != CKR_OK) break; - - if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_RSA)) { - crv = CKR_OBJECT_HANDLE_INVALID; - break; - } - crv = pk11_Attr2SecItem(arena,modulus,&pubKey->u.rsa.modulus); - if (crv != CKR_OK) break; - crv = pk11_Attr2SecItem(arena,exponent,&pubKey->u.rsa.publicExponent); - if (crv != CKR_OK) break; - break; - case dsaKey: - prime = attrs; - PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++; - subprime = attrs; - PK11_SETATTRS(attrs, CKA_SUBPRIME, NULL, 0); attrs++; - base = attrs; - PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++; - value = attrs; - PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++; - templateCount = attrs - template; - PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE)); - crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount); - if (crv != CKR_OK) break; - - if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DSA)) { - crv = CKR_OBJECT_HANDLE_INVALID; - break; - } - crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dsa.params.prime); - if (crv != CKR_OK) break; - crv = pk11_Attr2SecItem(arena,subprime,&pubKey->u.dsa.params.subPrime); - if (crv != CKR_OK) break; - crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dsa.params.base); - if (crv != CKR_OK) break; - crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dsa.publicValue); - if (crv != CKR_OK) break; - break; - case dhKey: - prime = attrs; - PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++; - base = attrs; - PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++; - value =attrs; - PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++; - templateCount = attrs - template; - PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE)); - crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount); - if (crv != CKR_OK) break; - - if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DH)) { - crv = CKR_OBJECT_HANDLE_INVALID; - break; - } - crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dh.prime); - if (crv != CKR_OK) break; - crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dh.base); - if (crv != CKR_OK) break; - crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dh.publicValue); - if (crv != CKR_OK) break; - break; - case fortezzaKey: - case nullKey: - default: - crv = CKR_OBJECT_HANDLE_INVALID; - break; - } - - PORT_FreeArena(tmp_arena,PR_FALSE); - - if (crv != CKR_OK) { - PORT_FreeArena(arena,PR_FALSE); - PK11_FreeSlot(slot); - PORT_SetError( PK11_MapError(crv) ); - return NULL; - } - - return pubKey; -} - -/* - * Build a Private Key structure from raw PKCS #11 information. - */ -SECKEYPrivateKey * -PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType, - PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx) -{ - PRArenaPool *arena; - SECKEYPrivateKey *privKey; - - /* don't know? look it up */ - if (keyType == nullKey) { - CK_KEY_TYPE pk11Type = CKK_RSA; - - pk11Type = PK11_ReadULongAttribute(slot,privID,CKA_KEY_TYPE); - isTemp = (PRBool)!PK11_HasAttributeSet(slot,privID,CKA_TOKEN); - switch (pk11Type) { - case CKK_RSA: keyType = rsaKey; break; - case CKK_DSA: keyType = dsaKey; break; - case CKK_DH: keyType = dhKey; break; - case CKK_KEA: keyType = fortezzaKey; break; - default: - break; - } - } - - /* now we need to create space for the private key */ - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) return NULL; - - privKey = (SECKEYPrivateKey *) - PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey)); - if (privKey == NULL) { - PORT_FreeArena(arena, PR_FALSE); - return NULL; - } - - privKey->arena = arena; - privKey->keyType = keyType; - privKey->pkcs11Slot = PK11_ReferenceSlot(slot); - privKey->pkcs11ID = privID; - privKey->pkcs11IsTemp = isTemp; - privKey->wincx = wincx; - - return privKey; -} - -/* return the keylength if possible. '0' if not */ -unsigned int -PK11_GetKeyLength(PK11SymKey *key) -{ - if (key->size != 0) return key->size ; - if (key->data.data == NULL) { - PK11_ExtractKeyValue(key); - } - /* key is probably secret. Look up it's type and length */ - /* this is new PKCS #11 version 2.0 functionality. */ - if (key->size == 0) { - CK_ULONG keyLength; - - keyLength = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_VALUE_LEN); - /* doesn't have a length field, check the known PKCS #11 key types, - * which don't have this field */ - if (keyLength == CK_UNAVAILABLE_INFORMATION) { - CK_KEY_TYPE keyType; - keyType = PK11_ReadULongAttribute(key->slot,key->objectID,CKA_KEY_TYPE); - switch (keyType) { - case CKK_DES: key->size = 8; break; - case CKK_DES2: key->size = 16; break; - case CKK_DES3: key->size = 24; break; - case CKK_SKIPJACK: key->size = 10; break; - case CKK_BATON: key->size = 20; break; - case CKK_JUNIPER: key->size = 20; break; - case CKK_GENERIC_SECRET: - if (key->type == CKM_SSL3_PRE_MASTER_KEY_GEN) { - key->size=48; - } - break; - default: break; - } - } else { - key->size = (unsigned int)keyLength; - } - } - - return key->size; -} - -/* return the strength of a key. This is different from length in that - * 1) it returns the size in bits, and 2) it returns only the secret portions - * of the key minus any checksums or parity. - */ -unsigned int -PK11_GetKeyStrength(PK11SymKey *key, SECAlgorithmID *algid) -{ - int size=0; - CK_MECHANISM_TYPE mechanism= CKM_INVALID_MECHANISM; /* RC2 only */ - SECItem *param = NULL; /* RC2 only */ - CK_RC2_CBC_PARAMS *rc2_params = NULL; /* RC2 ONLY */ - unsigned int effectiveBits = 0; /* RC2 ONLY */ - - switch (PK11_GetKeyType(key->type,0)) { - case CKK_CDMF: - return 40; - case CKK_DES: - return 56; - case CKK_DES3: - case CKK_DES2: - size = PK11_GetKeyLength(key); - if (size == 16) { - /* double des */ - return 112; /* 16*7 */ - } - return 168; - /* - * RC2 has is different than other ciphers in that it allows the user - * to deprecating keysize while still requiring all the bits for the - * original key. The info - * on what the effective key strength is in the parameter for the key. - * In S/MIME this parameter is stored in the DER encoded algid. In Our - * other uses of RC2, effectiveBits == keyBits, so this code functions - * correctly without an algid. - */ - case CKK_RC2: - /* if no algid was provided, fall through to default */ - if (!algid) { - break; - } - /* verify that the algid is for RC2 */ - mechanism = PK11_AlgtagToMechanism(SECOID_GetAlgorithmTag(algid)); - if ((mechanism != CKM_RC2_CBC) && (mechanism != CKM_RC2_ECB)) { - break; - } - - /* now get effective bits from the algorithm ID. */ - param = PK11_ParamFromAlgid(algid); - /* if we couldn't get memory just use key length */ - if (param == NULL) { - break; - } - - rc2_params = (CK_RC2_CBC_PARAMS *) param->data; - /* paranoia... shouldn't happen */ - PORT_Assert(param->data != NULL); - if (param->data == NULL) { - SECITEM_FreeItem(param,PR_TRUE); - break; - } - effectiveBits = (unsigned int)rc2_params->ulEffectiveBits; - SECITEM_FreeItem(param,PR_TRUE); - param = NULL; rc2_params=NULL; /* paranoia */ - - /* we have effective bits, is and allocated memory is free, now - * we need to return the smaller of effective bits and keysize */ - size = PK11_GetKeyLength(key); - if ((unsigned int)size*8 > effectiveBits) { - return effectiveBits; - } - - return size*8; /* the actual key is smaller, the strength can't be - * greater than the actual key size */ - - default: - break; - } - return PK11_GetKeyLength(key) * 8; -} - -/* Make a Key type to an appropriate signing/verification mechanism */ -static CK_MECHANISM_TYPE -pk11_mapSignKeyType(KeyType keyType) -{ - switch (keyType) { - case rsaKey: - return CKM_RSA_PKCS; - case fortezzaKey: - case dsaKey: - return CKM_DSA; - case dhKey: - default: - break; - } - return CKM_INVALID_MECHANISM; -} - -static CK_MECHANISM_TYPE -pk11_mapWrapKeyType(KeyType keyType) -{ - switch (keyType) { - case rsaKey: - return CKM_RSA_PKCS; - /* Add fortezza?? */ - default: - break; - } - return CKM_INVALID_MECHANISM; -} - -/* - * Some non-compliant PKCS #11 vendors do not give us the modulus, so actually - * set up a signature to get the signaure length. - */ -static int -pk11_backupGetSignLength(SECKEYPrivateKey *key) -{ - PK11SlotInfo *slot = key->pkcs11Slot; - CK_MECHANISM mech = {0, NULL, 0 }; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_ULONG len; - CK_RV crv; - unsigned char h_data[20] = { 0 }; - unsigned char buf[20]; /* obviously to small */ - CK_ULONG smallLen = sizeof(buf); - - mech.mechanism = pk11_mapSignKeyType(key->keyType); - - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PORT_SetError( PK11_MapError(crv) ); - return -1; - } - len = 0; - crv = PK11_GETTAB(slot)->C_Sign(session,h_data,sizeof(h_data), - NULL, &len); - /* now call C_Sign with too small a buffer to clear the session state */ - (void) PK11_GETTAB(slot)-> - C_Sign(session,h_data,sizeof(h_data),buf,&smallLen); - - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return -1; - } - return len; -} -/* - * get the length of a signature object based on the key - */ -int -PK11_SignatureLen(SECKEYPrivateKey *key) -{ - int val; - - switch (key->keyType) { - case rsaKey: - val = PK11_GetPrivateModulusLen(key); - if (val == -1) { - return pk11_backupGetSignLength(key); - } - return (unsigned long) val; - - case fortezzaKey: - case dsaKey: - return 40; - - default: - break; - } - PORT_SetError( SEC_ERROR_INVALID_KEY ); - return 0; -} - -PK11SlotInfo * -PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key) -{ - PK11SlotInfo *slot = key->pkcs11Slot; - slot = PK11_ReferenceSlot(slot); - return slot; -} - -/* - * Get the modulus length for raw parsing - */ -int -PK11_GetPrivateModulusLen(SECKEYPrivateKey *key) -{ - CK_ATTRIBUTE theTemplate = { CKA_MODULUS, NULL, 0 }; - PK11SlotInfo *slot = key->pkcs11Slot; - CK_RV crv; - int length; - - switch (key->keyType) { - case rsaKey: - crv = PK11_GetAttributes(NULL, slot, key->pkcs11ID, &theTemplate, 1); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return -1; - } - length = theTemplate.ulValueLen; - if ( *(unsigned char *)theTemplate.pValue == 0) { - length--; - } - if (theTemplate.pValue != NULL) - PORT_Free(theTemplate.pValue); - return (int) length; - - case fortezzaKey: - case dsaKey: - case dhKey: - default: - break; - } - if (theTemplate.pValue != NULL) - PORT_Free(theTemplate.pValue); - PORT_SetError( SEC_ERROR_INVALID_KEY ); - return -1; -} - -/* - * copy a key (or any other object) on a token - */ -CK_OBJECT_HANDLE -PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject) -{ - CK_OBJECT_HANDLE destObject; - CK_RV crv; - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_CopyObject(slot->session,srcObject,NULL,0, - &destObject); - PK11_ExitSlotMonitor(slot); - if (crv == CKR_OK) return destObject; - PORT_SetError( PK11_MapError(crv) ); - return CK_INVALID_HANDLE; -} - - -PK11SymKey * -pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey); - -/* - * The next two utilities are to deal with the fact that a given operation - * may be a multi-slot affair. This creates a new key object that is copied - * into the new slot. - */ -PK11SymKey * -pk11_CopyToSlot(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey) -{ - SECStatus rv; - PK11SymKey *newKey = NULL; - - /* Extract the raw key data if possible */ - if (symKey->data.data == NULL) { - rv = PK11_ExtractKeyValue(symKey); - /* KEY is sensitive, we're try key exchanging it. */ - if (rv != SECSuccess) { - return pk11_KeyExchange(slot, type, operation, symKey); - } - } - newKey = PK11_ImportSymKey(slot, type, symKey->origin, operation, - &symKey->data, symKey->cx); - if (newKey == NULL) newKey = pk11_KeyExchange(slot,type,operation,symKey); - return newKey; -} - -/* - * Make sure the slot we are in the correct slot for the operation - */ -static PK11SymKey * -pk11_ForceSlot(PK11SymKey *symKey,CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation) -{ - PK11SlotInfo *slot = symKey->slot; - PK11SymKey *newKey = NULL; - - if ((slot== NULL) || !PK11_DoesMechanism(slot,type)) { - slot = PK11_GetBestSlot(type,symKey->cx); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - newKey = pk11_CopyToSlot(slot, type, operation, symKey); - PK11_FreeSlot(slot); - } - return newKey; -} - -/* - * Use the token to Generate a key. keySize must be 'zero' for fixed key - * length algorithms. NOTE: this means we can never generate a DES2 key - * from this interface! - */ -PK11SymKey * -PK11_TokenKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, - int keySize, SECItem *keyid, PRBool isToken, void *wincx) -{ - PK11SymKey *symKey; - CK_ATTRIBUTE genTemplate[5]; - CK_ATTRIBUTE *attrs = genTemplate; - int count = sizeof(genTemplate)/sizeof(genTemplate[0]); - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_RV crv; - PRBool weird = PR_FALSE; /* hack for fortezza */ - CK_BBOOL cktrue = CK_TRUE; - CK_ULONG ck_key_size; /* only used for variable-length keys */ - - if ((keySize == -1) && (type == CKM_SKIPJACK_CBC64)) { - weird = PR_TRUE; - keySize = 0; - } - - /* TNH: Isn't this redundant, since "handleKey" will set defaults? */ - PK11_SETATTRS(attrs, (!weird) - ? CKA_ENCRYPT : CKA_DECRYPT, &cktrue, sizeof(CK_BBOOL)); attrs++; - - if (keySize != 0) { - ck_key_size = keySize; /* Convert to PK11 type */ - - PK11_SETATTRS(attrs, CKA_VALUE_LEN, &ck_key_size, sizeof(ck_key_size)); - attrs++; - } - - /* Include key id value if provided */ - if (keyid) { - PK11_SETATTRS(attrs, CKA_ID, keyid->data, keyid->len); attrs++; - } - - if (isToken) { - PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++; - PK11_SETATTRS(attrs, CKA_PRIVATE, &cktrue, sizeof(cktrue)); attrs++; - } - - PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(cktrue)); attrs++; - - count = attrs - genTemplate; - PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); - - /* find a slot to generate the key into */ - /* Only do slot management if this is not a token key */ - if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) { - PK11SlotInfo *bestSlot; - - bestSlot = PK11_GetBestSlot(type,wincx); /* TNH: references the slot? */ - if (bestSlot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - - symKey = PK11_CreateSymKey(bestSlot,type,wincx); - - PK11_FreeSlot(bestSlot); - } else { - symKey = PK11_CreateSymKey(slot, type, wincx); - } - if (symKey == NULL) return NULL; - - symKey->size = keySize; - symKey->origin = (!weird) ? PK11_OriginGenerated : PK11_OriginFortezzaHack; - - /* Initialize the Key Gen Mechanism */ - mechanism.mechanism = PK11_GetKeyGen(type); - if (mechanism.mechanism == CKM_FAKE_RANDOM) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - - /* Set the parameters for the key gen if provided */ - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - if (param) { - mechanism.pParameter = param->data; - mechanism.ulParameterLen = param->len; - } - - /* Get session and perform locking */ - if (isToken) { - PK11_Authenticate(symKey->slot,PR_TRUE,wincx); - session = PK11_GetRWSession(symKey->slot); /* Should always be original slot */ - } else { - session = symKey->session; - pk11_EnterKeyMonitor(symKey); - } - - crv = PK11_GETTAB(symKey->slot)->C_GenerateKey(session, - &mechanism, genTemplate, count, &symKey->objectID); - - /* Release lock and session */ - if (isToken) { - PK11_RestoreROSession(symKey->slot, session); - } else { - pk11_ExitKeyMonitor(symKey); - } - - if (crv != CKR_OK) { - PK11_FreeSymKey(symKey); - PORT_SetError( PK11_MapError(crv) ); - return NULL; - } - - return symKey; -} - -PK11SymKey * -PK11_KeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, - int keySize, void *wincx) -{ - return PK11_TokenKeyGen(slot, type, param, keySize, 0, PR_FALSE, wincx); -} - -/* --- */ -PK11SymKey * -PK11_GenDES3TokenKey(PK11SlotInfo *slot, SECItem *keyid, void *cx) -{ - return PK11_TokenKeyGen(slot, CKM_DES3_CBC, 0, 0, keyid, PR_TRUE, cx); -} - -/* - * PKCS #11 pairwise consistency check utilized to validate key pair. - */ -static SECStatus -pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey, - SECKEYPrivateKey *privKey, CK_MECHANISM *mech, void* wincx ) -{ - /* Variables used for Encrypt/Decrypt functions. */ - unsigned char *known_message = (unsigned char *)"Known Crypto Message"; - CK_BBOOL isEncryptable = CK_FALSE; - CK_BBOOL canSignVerify = CK_FALSE; - CK_BBOOL isDerivable = CK_FALSE; - unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH]; - CK_ULONG bytes_decrypted; - PK11SlotInfo *slot; - CK_OBJECT_HANDLE id; - unsigned char *ciphertext; - unsigned char *text_compared; - CK_ULONG max_bytes_encrypted; - CK_ULONG bytes_encrypted; - CK_ULONG bytes_compared; - CK_RV crv; - - /* Variables used for Signature/Verification functions. */ - unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!"; - SECItem signature; - SECItem digest; /* always uses SHA-1 digest */ - int signature_length; - SECStatus rv; - - /**************************************************/ - /* Pairwise Consistency Check of Encrypt/Decrypt. */ - /**************************************************/ - - isEncryptable = PK11_HasAttributeSet( privKey->pkcs11Slot, - privKey->pkcs11ID, CKA_DECRYPT ); - - /* If the encryption attribute is set; attempt to encrypt */ - /* with the public key and decrypt with the private key. */ - if( isEncryptable ) { - /* Find a module to encrypt against */ - slot = PK11_GetBestSlot(pk11_mapWrapKeyType(privKey->keyType),wincx); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return SECFailure; - } - - id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE); - if (id == CK_INVALID_HANDLE) { - PK11_FreeSlot(slot); - return SECFailure; - } - - /* Compute max bytes encrypted from modulus length of private key. */ - max_bytes_encrypted = PK11_GetPrivateModulusLen( privKey ); - - - /* Prepare for encryption using the public key. */ - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB( slot )->C_EncryptInit( slot->session, - mech, id ); - if( crv != CKR_OK ) { - PK11_ExitSlotMonitor(slot); - PORT_SetError( PK11_MapError( crv ) ); - PK11_FreeSlot(slot); - return SECFailure; - } - - /* Allocate space for ciphertext. */ - ciphertext = (unsigned char *) PORT_Alloc( max_bytes_encrypted ); - if( ciphertext == NULL ) { - PK11_ExitSlotMonitor(slot); - PORT_SetError( SEC_ERROR_NO_MEMORY ); - PK11_FreeSlot(slot); - return SECFailure; - } - - /* Initialize bytes encrypted to max bytes encrypted. */ - bytes_encrypted = max_bytes_encrypted; - - /* Encrypt using the public key. */ - crv = PK11_GETTAB( slot )->C_Encrypt( slot->session, - known_message, - PAIRWISE_MESSAGE_LENGTH, - ciphertext, - &bytes_encrypted ); - PK11_ExitSlotMonitor(slot); - PK11_FreeSlot(slot); - if( crv != CKR_OK ) { - PORT_SetError( PK11_MapError( crv ) ); - PORT_Free( ciphertext ); - return SECFailure; - } - - /* Always use the smaller of these two values . . . */ - bytes_compared = ( bytes_encrypted > PAIRWISE_MESSAGE_LENGTH ) - ? PAIRWISE_MESSAGE_LENGTH - : bytes_encrypted; - - /* If there was a failure, the plaintext */ - /* goes at the end, therefore . . . */ - text_compared = ( bytes_encrypted > PAIRWISE_MESSAGE_LENGTH ) - ? (ciphertext + bytes_encrypted - - PAIRWISE_MESSAGE_LENGTH ) - : ciphertext; - - /* Check to ensure that ciphertext does */ - /* NOT EQUAL known input message text */ - /* per FIPS PUB 140-1 directive. */ - if( ( bytes_encrypted != max_bytes_encrypted ) || - ( PORT_Memcmp( text_compared, known_message, - bytes_compared ) == 0 ) ) { - /* Set error to Invalid PRIVATE Key. */ - PORT_SetError( SEC_ERROR_INVALID_KEY ); - PORT_Free( ciphertext ); - return SECFailure; - } - - slot = privKey->pkcs11Slot; - /* Prepare for decryption using the private key. */ - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB( slot )->C_DecryptInit( slot->session, - mech, - privKey->pkcs11ID ); - if( crv != CKR_OK ) { - PK11_ExitSlotMonitor(slot); - PORT_SetError( PK11_MapError(crv) ); - PORT_Free( ciphertext ); - return SECFailure; - } - - /* Initialize bytes decrypted to be the */ - /* expected PAIRWISE_MESSAGE_LENGTH. */ - bytes_decrypted = PAIRWISE_MESSAGE_LENGTH; - - /* Decrypt using the private key. */ - /* NOTE: No need to reset the */ - /* value of bytes_encrypted. */ - crv = PK11_GETTAB( slot )->C_Decrypt( slot->session, - ciphertext, - bytes_encrypted, - plaintext, - &bytes_decrypted ); - PK11_ExitSlotMonitor(slot); - - /* Finished with ciphertext; free it. */ - PORT_Free( ciphertext ); - - if( crv != CKR_OK ) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - - /* Check to ensure that the output plaintext */ - /* does EQUAL known input message text. */ - if( ( bytes_decrypted != PAIRWISE_MESSAGE_LENGTH ) || - ( PORT_Memcmp( plaintext, known_message, - PAIRWISE_MESSAGE_LENGTH ) != 0 ) ) { - /* Set error to Bad PUBLIC Key. */ - PORT_SetError( SEC_ERROR_BAD_KEY ); - return SECFailure; - } - } - - /**********************************************/ - /* Pairwise Consistency Check of Sign/Verify. */ - /**********************************************/ - - canSignVerify = PK11_HasAttributeSet ( privKey->pkcs11Slot, - privKey->pkcs11ID, CKA_SIGN); - - if (canSignVerify) - { - /* Initialize signature and digest data. */ - signature.data = NULL; - digest.data = NULL; - - /* Determine length of signature. */ - signature_length = PK11_SignatureLen( privKey ); - if( signature_length == 0 ) - goto failure; - - /* Allocate space for signature data. */ - signature.data = (unsigned char *) PORT_Alloc( signature_length ); - if( signature.data == NULL ) { - PORT_SetError( SEC_ERROR_NO_MEMORY ); - goto failure; - } - - /* Allocate space for known digest data. */ - digest.data = (unsigned char *) PORT_Alloc( PAIRWISE_DIGEST_LENGTH ); - if( digest.data == NULL ) { - PORT_SetError( SEC_ERROR_NO_MEMORY ); - goto failure; - } - - /* "Fill" signature type and length. */ - signature.type = PAIRWISE_SECITEM_TYPE; - signature.len = signature_length; - - /* "Fill" digest with known SHA-1 digest parameters. */ - digest.type = PAIRWISE_SECITEM_TYPE; - PORT_Memcpy( digest.data, known_digest, PAIRWISE_DIGEST_LENGTH ); - digest.len = PAIRWISE_DIGEST_LENGTH; - - /* Sign the known hash using the private key. */ - rv = PK11_Sign( privKey, &signature, &digest ); - if( rv != SECSuccess ) - goto failure; - - /* Verify the known hash using the public key. */ - rv = PK11_Verify( pubKey, &signature, &digest, wincx ); - if( rv != SECSuccess ) - goto failure; - - /* Free signature and digest data. */ - PORT_Free( signature.data ); - PORT_Free( digest.data ); - } - - - - /**********************************************/ - /* Pairwise Consistency Check for Derivation */ - /**********************************************/ - - isDerivable = PK11_HasAttributeSet ( privKey->pkcs11Slot, - privKey->pkcs11ID, CKA_DERIVE); - - if (isDerivable) - { - /* - * We are not doing consistency check for Diffie-Hellman Key - - * otherwise it would be here - */ - - } - - return SECSuccess; - -failure: - if( signature.data != NULL ) - PORT_Free( signature.data ); - if( digest.data != NULL ) - PORT_Free( digest.data ); - - return SECFailure; -} - - - -/* - * take a private key in one pkcs11 module and load it into another: - * NOTE: the source private key is a rare animal... it can't be sensitive. - * This is used to do a key gen using one pkcs11 module and storing the - * result into another. - */ -SECKEYPrivateKey * -pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey, - SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive) -{ - CK_ATTRIBUTE privTemplate[] = { - /* class must be first */ - { CKA_CLASS, NULL, 0 }, - { CKA_KEY_TYPE, NULL, 0 }, - /* these three must be next */ - { CKA_TOKEN, NULL, 0 }, - { CKA_PRIVATE, NULL, 0 }, - { CKA_SENSITIVE, NULL, 0 }, - { CKA_ID, NULL, 0 }, -#ifdef notdef - { CKA_LABEL, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, -#endif - /* RSA */ - { CKA_MODULUS, NULL, 0 }, - { CKA_PRIVATE_EXPONENT, NULL, 0 }, - { CKA_PUBLIC_EXPONENT, NULL, 0 }, - { CKA_PRIME_1, NULL, 0 }, - { CKA_PRIME_2, NULL, 0 }, - { CKA_EXPONENT_1, NULL, 0 }, - { CKA_EXPONENT_2, NULL, 0 }, - { CKA_COEFFICIENT, NULL, 0 }, - }; - CK_ATTRIBUTE *attrs = NULL, *ap; - int templateSize = sizeof(privTemplate)/sizeof(privTemplate[0]); - PRArenaPool *arena; - CK_OBJECT_HANDLE objectID; - int i, count = 0; - int extra_count = 0; - CK_RV crv; - SECStatus rv; - - for (i=0; i < templateSize; i++) { - if (privTemplate[i].type == CKA_MODULUS) { - attrs= &privTemplate[i]; - count = i; - break; - } - } - PORT_Assert(attrs != NULL); - if (attrs == NULL) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return NULL; - } - - ap = attrs; - - switch (privKey->keyType) { - case rsaKey: - count = templateSize; - extra_count = templateSize - (attrs - privTemplate); - break; - case dsaKey: - ap->type = CKA_PRIME; ap++; count++; extra_count++; - ap->type = CKA_SUBPRIME; ap++; count++; extra_count++; - ap->type = CKA_BASE; ap++; count++; extra_count++; - ap->type = CKA_VALUE; ap++; count++; extra_count++; - break; - case dhKey: - ap->type = CKA_PRIME; ap++; count++; extra_count++; - ap->type = CKA_BASE; ap++; count++; extra_count++; - ap->type = CKA_VALUE; ap++; count++; extra_count++; - break; - default: - count = 0; - extra_count = 0; - break; - } - - if (count == 0) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return NULL; - } - - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) return NULL; - /* - * read out the old attributes. - */ - crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID, - privTemplate,count); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - PORT_FreeArena(arena, PR_TRUE); - return NULL; - } - - /* Reset sensitive, token, and private */ - *(CK_BBOOL *)(privTemplate[2].pValue) = token ? CK_TRUE : CK_FALSE; - *(CK_BBOOL *)(privTemplate[3].pValue) = token ? CK_TRUE : CK_FALSE; - *(CK_BBOOL *)(privTemplate[4].pValue) = sensitive ? CK_TRUE : CK_FALSE; - - /* Not everyone can handle zero padded key values, give - * them the raw data as unsigned */ - for (ap=attrs; extra_count; ap++, extra_count--) { - pk11_SignedToUnsigned(ap); - } - - /* now Store the puppies */ - rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate, - count, token, &objectID); - PORT_FreeArena(arena, PR_TRUE); - if (rv != SECSuccess) { - return NULL; - } - - /* try loading the public key as a token object */ - if (pubKey) { - PK11_ImportPublicKey(slot, pubKey, PR_TRUE); - if (pubKey->pkcs11Slot) { - PK11_FreeSlot(pubKey->pkcs11Slot); - pubKey->pkcs11Slot = NULL; - pubKey->pkcs11ID = CK_INVALID_HANDLE; - } - } - - /* build new key structure */ - return PK11_MakePrivKey(slot, privKey->keyType, (PRBool)!token, - objectID, privKey->wincx); -} - -/* - * export this for PSM - */ -SECKEYPrivateKey * -PK11_LoadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey, - SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive) -{ - return pk11_loadPrivKey(slot,privKey,pubKey,token,sensitive); -} - - -/* - * Use the token to Generate a key. keySize must be 'zero' for fixed key - * length algorithms. NOTE: this means we can never generate a DES2 key - * from this interface! - */ -SECKEYPrivateKey * -PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type, - void *param, SECKEYPublicKey **pubKey, PRBool token, - PRBool sensitive, void *wincx) -{ - /* we have to use these native types because when we call PKCS 11 modules - * we have to make sure that we are using the correct sizes for all the - * parameters. */ - CK_BBOOL ckfalse = CK_FALSE; - CK_BBOOL cktrue = CK_TRUE; - CK_ULONG modulusBits; - CK_BYTE publicExponent[4]; - CK_ATTRIBUTE privTemplate[] = { - { CKA_SENSITIVE, NULL, 0}, - { CKA_TOKEN, NULL, 0}, - { CKA_PRIVATE, NULL, 0}, - { CKA_DERIVE, NULL, 0}, - { CKA_UNWRAP, NULL, 0}, - { CKA_SIGN, NULL, 0}, - { CKA_DECRYPT, NULL, 0}, - }; - CK_ATTRIBUTE rsaPubTemplate[] = { - { CKA_MODULUS_BITS, NULL, 0}, - { CKA_PUBLIC_EXPONENT, NULL, 0}, - { CKA_TOKEN, NULL, 0}, - { CKA_DERIVE, NULL, 0}, - { CKA_WRAP, NULL, 0}, - { CKA_VERIFY, NULL, 0}, - { CKA_VERIFY_RECOVER, NULL, 0}, - { CKA_ENCRYPT, NULL, 0}, - }; - CK_ATTRIBUTE dsaPubTemplate[] = { - { CKA_PRIME, NULL, 0 }, - { CKA_SUBPRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - { CKA_TOKEN, NULL, 0}, - { CKA_DERIVE, NULL, 0}, - { CKA_WRAP, NULL, 0}, - { CKA_VERIFY, NULL, 0}, - { CKA_VERIFY_RECOVER, NULL, 0}, - { CKA_ENCRYPT, NULL, 0}, - }; - CK_ATTRIBUTE dhPubTemplate[] = { - { CKA_PRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - { CKA_TOKEN, NULL, 0}, - { CKA_DERIVE, NULL, 0}, - { CKA_WRAP, NULL, 0}, - { CKA_VERIFY, NULL, 0}, - { CKA_VERIFY_RECOVER, NULL, 0}, - { CKA_ENCRYPT, NULL, 0}, - }; - - int dsaPubCount = sizeof(dsaPubTemplate)/sizeof(dsaPubTemplate[0]); - /*CK_ULONG key_size = 0;*/ - CK_ATTRIBUTE *pubTemplate; - int privCount = sizeof(privTemplate)/sizeof(privTemplate[0]); - int rsaPubCount = sizeof(rsaPubTemplate)/sizeof(rsaPubTemplate[0]); - int dhPubCount = sizeof(dhPubTemplate)/sizeof(dhPubTemplate[0]); - int pubCount = 0; - PK11RSAGenParams *rsaParams; - SECKEYPQGParams *dsaParams; - SECKEYDHParams * dhParams; - CK_MECHANISM mechanism; - CK_MECHANISM test_mech; - CK_SESSION_HANDLE session_handle; - CK_RV crv; - CK_OBJECT_HANDLE privID,pubID; - SECKEYPrivateKey *privKey; - KeyType keyType; - PRBool restore; - int peCount,i; - CK_ATTRIBUTE *attrs; - CK_ATTRIBUTE *privattrs; - SECItem *pubKeyIndex; - CK_ATTRIBUTE setTemplate; - SECStatus rv; - CK_MECHANISM_INFO mechanism_info; - CK_OBJECT_CLASS keyClass; - SECItem *cka_id; - PRBool haslock = PR_FALSE; - PRBool pubIsToken = PR_FALSE; - - PORT_Assert(slot != NULL); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE); - return NULL; - } - - /* if our slot really doesn't do this mechanism, Generate the key - * in our internal token and write it out */ - if (!PK11_DoesMechanism(slot,type)) { - PK11SlotInfo *int_slot = PK11_GetInternalSlot(); - - /* don't loop forever looking for a slot */ - if (slot == int_slot) { - PK11_FreeSlot(int_slot); - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return NULL; - } - - /* if there isn't a suitable slot, then we can't do the keygen */ - if (int_slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - - /* generate the temporary key to load */ - privKey = PK11_GenerateKeyPair(int_slot,type, param, pubKey, PR_FALSE, - PR_FALSE, wincx); - PK11_FreeSlot(int_slot); - - /* if successful, load the temp key into the new token */ - if (privKey != NULL) { - SECKEYPrivateKey *newPrivKey = pk11_loadPrivKey(slot,privKey, - *pubKey,token,sensitive); - SECKEY_DestroyPrivateKey(privKey); - if (newPrivKey == NULL) { - SECKEY_DestroyPublicKey(*pubKey); - *pubKey = NULL; - } - return newPrivKey; - } - return NULL; - } - - - mechanism.mechanism = type; - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - test_mech.pParameter = NULL; - test_mech.ulParameterLen = 0; - - /* set up the private key template */ - privattrs = privTemplate; - PK11_SETATTRS(privattrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); privattrs++; - PK11_SETATTRS(privattrs, CKA_TOKEN, token ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); privattrs++; - PK11_SETATTRS(privattrs, CKA_PRIVATE, sensitive ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); privattrs++; - - /* set up the mechanism specific info */ - switch (type) { - case CKM_RSA_PKCS_KEY_PAIR_GEN: - rsaParams = (PK11RSAGenParams *)param; - modulusBits = rsaParams->keySizeInBits; - peCount = 0; - - /* convert pe to a PKCS #11 string */ - for (i=0; i < 4; i++) { - if (peCount || (rsaParams->pe & - ((unsigned long)0xff000000L >> (i*8)))) { - publicExponent[peCount] = - (CK_BYTE)((rsaParams->pe >> (3-i)*8) & 0xff); - peCount++; - } - } - PORT_Assert(peCount != 0); - attrs = rsaPubTemplate; - PK11_SETATTRS(attrs, CKA_MODULUS_BITS, - &modulusBits, sizeof(modulusBits)); attrs++; - PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, - publicExponent, peCount);attrs++; - pubTemplate = rsaPubTemplate; - pubCount = rsaPubCount; - keyType = rsaKey; - test_mech.mechanism = CKM_RSA_PKCS; - break; - case CKM_DSA_KEY_PAIR_GEN: - dsaParams = (SECKEYPQGParams *)param; - attrs = dsaPubTemplate; - PK11_SETATTRS(attrs, CKA_PRIME, dsaParams->prime.data, - dsaParams->prime.len); attrs++; - PK11_SETATTRS(attrs, CKA_SUBPRIME, dsaParams->subPrime.data, - dsaParams->subPrime.len); attrs++; - PK11_SETATTRS(attrs, CKA_BASE, dsaParams->base.data, - dsaParams->base.len); attrs++; - pubTemplate = dsaPubTemplate; - pubCount = dsaPubCount; - keyType = dsaKey; - test_mech.mechanism = CKM_DSA; - break; - case CKM_DH_PKCS_KEY_PAIR_GEN: - dhParams = (SECKEYDHParams *)param; - attrs = dhPubTemplate; - PK11_SETATTRS(attrs, CKA_PRIME, dhParams->prime.data, - dhParams->prime.len); attrs++; - PK11_SETATTRS(attrs, CKA_BASE, dhParams->base.data, - dhParams->base.len); attrs++; - pubTemplate = dhPubTemplate; - pubCount = dhPubCount; - keyType = dhKey; - test_mech.mechanism = CKM_DH_PKCS_DERIVE; - break; - default: - PORT_SetError( SEC_ERROR_BAD_KEY ); - return NULL; - } - - /* now query the slot to find out how "good" a key we can generate */ - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, - test_mech.mechanism,&mechanism_info); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if ((crv != CKR_OK) || (mechanism_info.flags == 0)) { - /* must be old module... guess what it should be... */ - switch (test_mech.mechanism) { - case CKM_RSA_PKCS: - mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT | - CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);; - break; - case CKM_DSA: - mechanism_info.flags = CKF_SIGN | CKF_VERIFY; - break; - case CKM_DH_PKCS_DERIVE: - mechanism_info.flags = CKF_DERIVE; - break; - default: - break; - } - } - /* set the public key objects */ - PK11_SETATTRS(attrs, CKA_TOKEN, token ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_DERIVE, - mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_WRAP, - mechanism_info.flags & CKF_WRAP ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_VERIFY, - mechanism_info.flags & CKF_VERIFY ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_VERIFY_RECOVER, - mechanism_info.flags & CKF_VERIFY_RECOVER ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_ENCRYPT, - mechanism_info.flags & CKF_ENCRYPT? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); attrs++; - PK11_SETATTRS(privattrs, CKA_DERIVE, - mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); privattrs++; - PK11_SETATTRS(privattrs, CKA_UNWRAP, - mechanism_info.flags & CKF_UNWRAP ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); privattrs++; - PK11_SETATTRS(privattrs, CKA_SIGN, - mechanism_info.flags & CKF_SIGN ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); privattrs++; - PK11_SETATTRS(privattrs, CKA_DECRYPT, - mechanism_info.flags & CKF_DECRYPT ? &cktrue : &ckfalse, - sizeof(CK_BBOOL)); privattrs++; - - if (token) { - session_handle = PK11_GetRWSession(slot); - haslock = PK11_RWSessionHasLock(slot,session_handle); - restore = PR_TRUE; - } else { - PK11_EnterSlotMonitor(slot); /* gross!! */ - session_handle = slot->session; - restore = PR_FALSE; - haslock = PR_TRUE; - } - - crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism, - pubTemplate,pubCount,privTemplate,privCount,&pubID,&privID); - - - if (crv != CKR_OK) { - if (restore) { - PK11_RestoreROSession(slot,session_handle); - } else PK11_ExitSlotMonitor(slot); - PORT_SetError( PK11_MapError(crv) ); - return NULL; - } - /* This locking code is dangerous and needs to be more thought - * out... the real problem is that we're holding the mutex open this long - */ - if (haslock) { PK11_ExitSlotMonitor(slot); } - - /* swap around the ID's for older PKCS #11 modules */ - keyClass = PK11_ReadULongAttribute(slot,pubID,CKA_CLASS); - if (keyClass != CKO_PUBLIC_KEY) { - CK_OBJECT_HANDLE tmp = pubID; - pubID = privID; - privID = tmp; - } - - *pubKey = PK11_ExtractPublicKey(slot, keyType, pubID); - if (*pubKey == NULL) { - if (restore) { - /* we may have to restore the mutex so it get's exited properly - * in RestoreROSession */ - if (haslock) PK11_EnterSlotMonitor(slot); - PK11_RestoreROSession(slot,session_handle); - } - PK11_DestroyObject(slot,pubID); - PK11_DestroyObject(slot,privID); - return NULL; - } - - /* set the ID to the public key so we can find it again */ - pubKeyIndex = NULL; - switch (type) { - case CKM_RSA_PKCS_KEY_PAIR_GEN: - pubKeyIndex = &(*pubKey)->u.rsa.modulus; - break; - case CKM_DSA_KEY_PAIR_GEN: - pubKeyIndex = &(*pubKey)->u.dsa.publicValue; - break; - case CKM_DH_PKCS_KEY_PAIR_GEN: - pubKeyIndex = &(*pubKey)->u.dh.publicValue; - break; - } - PORT_Assert(pubKeyIndex != NULL); - - cka_id = PK11_MakeIDFromPubKey(pubKeyIndex); - pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN); - - PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len); - - if (haslock) { PK11_EnterSlotMonitor(slot); } - crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID, - &setTemplate, 1); - - if (crv == CKR_OK && pubIsToken) { - crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID, - &setTemplate, 1); - } - - - if (restore) { - PK11_RestoreROSession(slot,session_handle); - } else { - PK11_ExitSlotMonitor(slot); - } - SECITEM_FreeItem(cka_id,PR_TRUE); - - - if (crv != CKR_OK) { - PK11_DestroyObject(slot,pubID); - PK11_DestroyObject(slot,privID); - PORT_SetError( PK11_MapError(crv) ); - *pubKey = NULL; - return NULL; - } - - privKey = PK11_MakePrivKey(slot,keyType,(PRBool)!token,privID,wincx); - if (privKey == NULL) { - SECKEY_DestroyPublicKey(*pubKey); - PK11_DestroyObject(slot,privID); - *pubKey = NULL; - return NULL; /* due to pairwise consistency check */ - } - - /* Perform PKCS #11 pairwise consistency check. */ - rv = pk11_PairwiseConsistencyCheck( *pubKey, privKey, &test_mech, wincx ); - if( rv != SECSuccess ) { - SECKEY_DestroyPublicKey( *pubKey ); - SECKEY_DestroyPrivateKey( privKey ); - *pubKey = NULL; - privKey = NULL; - return NULL; - } - - return privKey; -} - -/* - * This function does a straight public key wrap (which only RSA can do). - * Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and - * Diffie-Hellman Ciphers. */ -SECStatus -PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey, - PK11SymKey *symKey, SECItem *wrappedKey) -{ - PK11SlotInfo *slot; - CK_ULONG len = wrappedKey->len; - PK11SymKey *newKey = NULL; - CK_OBJECT_HANDLE id; - CK_MECHANISM mechanism; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_RV crv; - - /* if this slot doesn't support the mechanism, go to a slot that does */ - newKey = pk11_ForceSlot(symKey,type,CKA_ENCRYPT); - if (newKey != NULL) { - symKey = newKey; - } - - if ((symKey == NULL) || (symKey->slot == NULL)) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return SECFailure; - } - - slot = symKey->slot; - mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType); - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - - id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE); - - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_WrapKey(session,&mechanism, - id,symKey->objectID,wrappedKey->data,&len); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - if (newKey) { - PK11_FreeSymKey(newKey); - } - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - wrappedKey->len = len; - return SECSuccess; -} - -/* - * this little function uses the Encrypt function to wrap a key, just in - * case we have problems with the wrap implementation for a token. - */ -static SECStatus -pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type, - SECItem *inKey, SECItem *outKey) -{ - PK11SlotInfo *slot; - CK_ULONG len; - SECItem *data; - CK_MECHANISM mech; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_RV crv; - - slot = wrappingKey->slot; - /* use NULL IV's for wrapping */ - mech.mechanism = type; - if (param) { - mech.pParameter = param->data; - mech.ulParameterLen = param->len; - } else { - mech.pParameter = NULL; - mech.ulParameterLen = 0; - } - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_EncryptInit(session,&mech, - wrappingKey->objectID); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - - /* keys are almost always aligned, but if we get this far, - * we've gone above and beyond anyway... */ - data = PK11_BlockData(inKey,PK11_GetBlockSize(type,param)); - if (data == NULL) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PORT_SetError(SEC_ERROR_NO_MEMORY); - return SECFailure; - } - len = outKey->len; - crv = PK11_GETTAB(slot)->C_Encrypt(session,data->data,data->len, - outKey->data, &len); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - SECITEM_FreeItem(data,PR_TRUE); - outKey->len = len; - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - return SECSuccess; -} - -/* - * This function does a symetric based wrap. - */ -SECStatus -PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param, - PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey) -{ - PK11SlotInfo *slot; - CK_ULONG len = wrappedKey->len; - PK11SymKey *newKey = NULL; - SECItem *param_save = NULL; - CK_MECHANISM mechanism; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_RV crv; - SECStatus rv; - - /* if this slot doesn't support the mechanism, go to a slot that does */ - /* Force symKey and wrappingKey into the same slot */ - if ((wrappingKey->slot == NULL) || (symKey->slot != wrappingKey->slot)) { - /* first try copying the wrapping Key to the symKey slot */ - if (symKey->slot && PK11_DoesMechanism(symKey->slot,type)) { - newKey = pk11_CopyToSlot(symKey->slot,type,CKA_WRAP,wrappingKey); - } - /* Nope, try it the other way */ - if (newKey == NULL) { - if (wrappingKey->slot) { - newKey = pk11_CopyToSlot(wrappingKey->slot, - symKey->type, CKA_ENCRYPT, symKey); - } - /* just not playing... one last thing, can we get symKey's data? - * If it's possible, we it should already be in the - * symKey->data.data pointer because pk11_CopyToSlot would have - * tried to put it there. */ - if (newKey == NULL) { - /* Can't get symKey's data: Game Over */ - if (symKey->data.data == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return SECFailure; - } - if (param == NULL) { - param_save = param = PK11_ParamFromIV(type,NULL); - } - rv = pk11_HandWrap(wrappingKey, param, type, - &symKey->data,wrappedKey); - if (param_save) SECITEM_FreeItem(param_save,PR_TRUE); - return rv; - } - /* we successfully moved the sym Key */ - symKey = newKey; - } else { - /* we successfully moved the wrapping Key */ - wrappingKey = newKey; - } - } - - /* at this point both keys are in the same token */ - slot = wrappingKey->slot; - mechanism.mechanism = type; - /* use NULL IV's for wrapping */ - if (param == NULL) { - param_save = param = PK11_ParamFromIV(type,NULL); - } - if (param) { - mechanism.pParameter = param->data; - mechanism.ulParameterLen = param->len; - } else { - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - } - - len = wrappedKey->len; - - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_WrapKey(session, &mechanism, - wrappingKey->objectID, symKey->objectID, - wrappedKey->data, &len); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - rv = SECSuccess; - if (crv != CKR_OK) { - /* can't wrap it? try hand wrapping it... */ - do { - if (symKey->data.data == NULL) { - rv = PK11_ExtractKeyValue(symKey); - if (rv != SECSuccess) break; - } - rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data, - wrappedKey); - } while (PR_FALSE); - } else { - wrappedKey->len = len; - } - if (newKey) PK11_FreeSymKey(newKey); - if (param_save) SECITEM_FreeItem(param_save,PR_TRUE); - return rv; -} - -/* - * This Generates a new key based on a symetricKey - */ -PK11SymKey * -PK11_Derive( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, - int keySize) -{ - return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, - keySize, NULL, 0); -} - - -PK11SymKey * -PK11_DeriveWithFlags( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, - SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, - int keySize, CK_FLAGS flags) -{ - CK_BBOOL ckTrue = CK_TRUE; - CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; - unsigned int templateCount; - - templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue); - return pk11_DeriveWithTemplate(baseKey, derive, param, target, operation, - keySize, keyTemplate, templateCount); -} - -static PRBool -pk11_FindAttrInTemplate(CK_ATTRIBUTE * attr, - unsigned int numAttrs, - CK_ATTRIBUTE_TYPE target) -{ - for (; numAttrs > 0; ++attr, --numAttrs) { - if (attr->type == target) - return PR_TRUE; - } - return PR_FALSE; -} - -static PK11SymKey * -pk11_DeriveWithTemplate( PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, - SECItem *param, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, - int keySize, CK_ATTRIBUTE *userAttr, unsigned int numAttrs) -{ - PK11SlotInfo * slot = baseKey->slot; - PK11SymKey * symKey; - PK11SymKey * newBaseKey = NULL; - CK_BBOOL cktrue = CK_TRUE; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_ULONG valueLen = 0; - CK_MECHANISM mechanism; - CK_RV crv; - CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; - CK_ATTRIBUTE * attrs = keyTemplate; - unsigned int templateCount; - - if (numAttrs > MAX_TEMPL_ATTRS) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - /* first copy caller attributes in. */ - for (templateCount = 0; templateCount < numAttrs; ++templateCount) { - *attrs++ = *userAttr++; - } - - /* We only add the following attributes to the template if the caller - ** didn't already supply them. - */ - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) { - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass); - attrs++; - } - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) { - keyType = PK11_GetKeyType(target, keySize); - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType ); - attrs++; - } - if (keySize > 0 && - !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) { - valueLen = (CK_ULONG)keySize; - PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen); - attrs++; - } - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { - PK11_SETATTRS(attrs, operation, &cktrue, sizeof cktrue); attrs++; - } - - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount <= MAX_TEMPL_ATTRS); - - /* move the key to a slot that can do the function */ - if (!PK11_DoesMechanism(slot,derive)) { - /* get a new base key & slot */ - PK11SlotInfo *newSlot = PK11_GetBestSlot(derive, baseKey->cx); - - if (newSlot == NULL) return NULL; - - newBaseKey = pk11_CopyToSlot (newSlot, derive, CKA_DERIVE, - baseKey); - PK11_FreeSlot(newSlot); - if (newBaseKey == NULL) return NULL; - baseKey = newBaseKey; - slot = baseKey->slot; - } - - - /* get our key Structure */ - symKey = PK11_CreateSymKey(slot,target,baseKey->cx); - if (symKey == NULL) { - return NULL; - } - - symKey->size = keySize; - - mechanism.mechanism = derive; - if (param) { - mechanism.pParameter = param->data; - mechanism.ulParameterLen = param->len; - } else { - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - } - symKey->origin=PK11_OriginDerive; - - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, - baseKey->objectID, keyTemplate, templateCount, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); - - if (newBaseKey) PK11_FreeSymKey(newBaseKey); - if (crv != CKR_OK) { - PK11_FreeSymKey(symKey); - return NULL; - } - return symKey; -} - -/* build a public KEA key from the public value */ -SECKEYPublicKey * -PK11_MakeKEAPubKey(unsigned char *keyData,int length) -{ - SECKEYPublicKey *pubk; - SECItem pkData; - SECStatus rv; - PRArenaPool *arena; - - pkData.data = keyData; - pkData.len = length; - - arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) - return NULL; - - pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey)); - if (pubk == NULL) { - PORT_FreeArena (arena, PR_FALSE); - return NULL; - } - - pubk->arena = arena; - pubk->pkcs11Slot = 0; - pubk->pkcs11ID = CK_INVALID_HANDLE; - pubk->keyType = fortezzaKey; - rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.KEAKey, &pkData); - if (rv != SECSuccess) { - PORT_FreeArena (arena, PR_FALSE); - return NULL; - } - return pubk; -} - - -/* - * This Generates a wrapping key based on a privateKey, publicKey, and two - * random numbers. For Mail usage RandomB should be NULL. In the Sender's - * case RandomA is generate, outherwize it is passed. - */ -static unsigned char *rb_email = NULL; - -PK11SymKey * -PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, - PRBool isSender, SECItem *randomA, SECItem *randomB, - CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize,void *wincx) -{ - PK11SlotInfo *slot = privKey->pkcs11Slot; - CK_MECHANISM mechanism; - PK11SymKey *symKey; - CK_RV crv; - - - if (rb_email == NULL) { - rb_email = PORT_ZAlloc(128); - if (rb_email == NULL) { - return NULL; - } - rb_email[127] = 1; - } - - /* get our key Structure */ - symKey = PK11_CreateSymKey(slot,target,wincx); - if (symKey == NULL) { - return NULL; - } - - symKey->origin = PK11_OriginDerive; - - switch (privKey->keyType) { - case rsaKey: - case nullKey: - PORT_SetError(SEC_ERROR_BAD_KEY); - break; - case dsaKey: - case keaKey: - case fortezzaKey: - { - CK_KEA_DERIVE_PARAMS param; - param.isSender = (CK_BBOOL) isSender; - param.ulRandomLen = randomA->len; - param.pRandomA = randomA->data; - param.pRandomB = rb_email; - if (randomB) - param.pRandomB = randomB->data; - if (pubKey->keyType == fortezzaKey) { - param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len; - param.pPublicData = pubKey->u.fortezza.KEAKey.data; - } else { - /* assert type == keaKey */ - /* XXX change to match key key types */ - param.ulPublicDataLen = pubKey->u.fortezza.KEAKey.len; - param.pPublicData = pubKey->u.fortezza.KEAKey.data; - } - - mechanism.mechanism = derive; - mechanism.pParameter = ¶m; - mechanism.ulParameterLen = sizeof(param); - - /* get a new symKey structure */ - pk11_EnterKeyMonitor(symKey); - crv=PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, - privKey->pkcs11ID, NULL, 0, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); - if (crv == CKR_OK) return symKey; - PORT_SetError( PK11_MapError(crv) ); - } - break; - case dhKey: - { - CK_BBOOL cktrue = CK_TRUE; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_ULONG key_size = 0; - CK_ATTRIBUTE keyTemplate[4]; - int templateCount; - CK_ATTRIBUTE *attrs = keyTemplate; - - if (pubKey->keyType != dhKey) { - PORT_SetError(SEC_ERROR_BAD_KEY); - break; - } - - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); - attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); - attrs++; - PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); - attrs++; - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); - - keyType = PK11_GetKeyType(target,keySize); - key_size = keySize; - symKey->size = keySize; - if (key_size == 0) templateCount--; - - mechanism.mechanism = derive; - - /* we can undefine these when we define diffie-helman keys */ - mechanism.pParameter = pubKey->u.dh.publicValue.data; - mechanism.ulParameterLen = pubKey->u.dh.publicValue.len; - - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, - privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); - if (crv == CKR_OK) return symKey; - PORT_SetError( PK11_MapError(crv) ); - } - break; - } - - PK11_FreeSymKey(symKey); - return NULL; -} - -/* - * this little function uses the Decrypt function to unwrap a key, just in - * case we are having problem with unwrap. NOTE: The key size may - * not be preserved properly for some algorithms! - */ -static PK11SymKey * -pk11_HandUnwrap(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, - CK_MECHANISM *mech, SECItem *inKey, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE *keyTemplate, unsigned int templateCount, - int key_size, void * wincx, CK_RV *crvp) -{ - CK_ULONG len; - SECItem outKey; - PK11SymKey *symKey; - CK_RV crv; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - - /* remove any VALUE_LEN parameters */ - if (keyTemplate[templateCount-1].type == CKA_VALUE_LEN) { - templateCount--; - } - - /* keys are almost always aligned, but if we get this far, - * we've gone above and beyond anyway... */ - outKey.data = (unsigned char*)PORT_Alloc(inKey->len); - if (outKey.data == NULL) { - PORT_SetError( SEC_ERROR_NO_MEMORY ); - if (crvp) *crvp = CKR_HOST_MEMORY; - return NULL; - } - len = inKey->len; - - /* use NULL IV's for wrapping */ - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_DecryptInit(session,mech,wrappingKey); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PORT_Free(outKey.data); - PORT_SetError( PK11_MapError(crv) ); - if (crvp) *crvp =crv; - return NULL; - } - crv = PK11_GETTAB(slot)->C_Decrypt(session,inKey->data,inKey->len, - outKey.data, &len); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - if (crv != CKR_OK) { - PORT_Free(outKey.data); - PORT_SetError( PK11_MapError(crv) ); - if (crvp) *crvp =crv; - return NULL; - } - - outKey.len = (key_size == 0) ? len : key_size; - outKey.type = siBuffer; - - if (PK11_DoesMechanism(slot,target)) { - symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap, - keyTemplate, templateCount, - &outKey, wincx); - } else { - slot = PK11_GetBestSlot(target,wincx); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - PORT_Free(outKey.data); - if (crvp) *crvp = CKR_DEVICE_ERROR; - return NULL; - } - symKey = pk11_ImportSymKeyWithTempl(slot, target, PK11_OriginUnwrap, - keyTemplate, templateCount, - &outKey, wincx); - PK11_FreeSlot(slot); - } - PORT_Free(outKey.data); - - if (crvp) *crvp = symKey? CKR_OK : CKR_DEVICE_ERROR; - return symKey; -} - -/* - * The wrap/unwrap function is pretty much the same for private and - * public keys. It's just getting the Object ID and slot right. This is - * the combined unwrap function. - */ -static PK11SymKey * -pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey, - CK_MECHANISM_TYPE wrapType, SECItem *param, SECItem *wrappedKey, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, - void *wincx, CK_ATTRIBUTE *userAttr, unsigned int numAttrs) -{ - PK11SymKey * symKey; - SECItem * param_free = NULL; - CK_BBOOL cktrue = CK_TRUE; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_ULONG valueLen = 0; - CK_MECHANISM mechanism; - CK_RV crv; - CK_MECHANISM_INFO mechanism_info; - CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; - CK_ATTRIBUTE * attrs = keyTemplate; - unsigned int templateCount; - - if (numAttrs > MAX_TEMPL_ATTRS) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - /* first copy caller attributes in. */ - for (templateCount = 0; templateCount < numAttrs; ++templateCount) { - *attrs++ = *userAttr++; - } - - /* We only add the following attributes to the template if the caller - ** didn't already supply them. - */ - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_CLASS)) { - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof keyClass); - attrs++; - } - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_KEY_TYPE)) { - keyType = PK11_GetKeyType(target, keySize); - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof keyType ); - attrs++; - } - if (!pk11_FindAttrInTemplate(keyTemplate, numAttrs, operation)) { - PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; - } - - /* - * must be last in case we need to use this template to import the key - */ - if (keySize > 0 && - !pk11_FindAttrInTemplate(keyTemplate, numAttrs, CKA_VALUE_LEN)) { - valueLen = (CK_ULONG)keySize; - PK11_SETATTRS(attrs, CKA_VALUE_LEN, &valueLen, sizeof valueLen); - attrs++; - } - - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); - - - /* find out if we can do wrap directly. Because the RSA case if *very* - * common, cache the results for it. */ - if ((wrapType == CKM_RSA_PKCS) && (slot->hasRSAInfo)) { - mechanism_info.flags = slot->RSAInfoFlags; - } else { - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,wrapType, - &mechanism_info); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - mechanism_info.flags = 0; - } - if (wrapType == CKM_RSA_PKCS) { - slot->RSAInfoFlags = mechanism_info.flags; - slot->hasRSAInfo = PR_TRUE; - } - } - - /* initialize the mechanism structure */ - mechanism.mechanism = wrapType; - /* use NULL IV's for wrapping */ - if (param == NULL) param = param_free = PK11_ParamFromIV(wrapType,NULL); - if (param) { - mechanism.pParameter = param->data; - mechanism.ulParameterLen = param->len; - } else { - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - } - - if ((mechanism_info.flags & CKF_DECRYPT) - && !PK11_DoesMechanism(slot,target)) { - symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, - target, keyTemplate, templateCount, keySize, - wincx, &crv); - if (symKey) { - if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); - return symKey; - } - /* - * if the RSA OP simply failed, don't try to unwrap again - * with this module. - */ - if (crv == CKR_DEVICE_ERROR){ - return NULL; - } - /* fall through, maybe they incorrectly set CKF_DECRYPT */ - } - - /* get our key Structure */ - symKey = PK11_CreateSymKey(slot,target,wincx); - if (symKey == NULL) { - if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); - return NULL; - } - - symKey->size = keySize; - symKey->origin = PK11_OriginUnwrap; - - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_UnwrapKey(symKey->session,&mechanism,wrappingKey, - wrappedKey->data, wrappedKey->len, keyTemplate, templateCount, - &symKey->objectID); - pk11_ExitKeyMonitor(symKey); - if (param_free) SECITEM_FreeItem(param_free,PR_TRUE); - if ((crv != CKR_OK) && (crv != CKR_DEVICE_ERROR)) { - /* try hand Unwrapping */ - PK11_FreeSymKey(symKey); - symKey = pk11_HandUnwrap(slot, wrappingKey, &mechanism, wrappedKey, - target, keyTemplate, templateCount, keySize, - wincx, NULL); - } - - return symKey; -} - -/* use a symetric key to unwrap another symetric key */ -PK11SymKey * -PK11_UnwrapSymKey( PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, - SECItem *param, SECItem *wrappedKey, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, - int keySize) -{ - return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, - wrapType, param, wrappedKey, target, operation, keySize, - wrappingKey->cx, NULL, 0); -} - -/* use a symetric key to unwrap another symetric key */ -PK11SymKey * -PK11_UnwrapSymKeyWithFlags(PK11SymKey *wrappingKey, CK_MECHANISM_TYPE wrapType, - SECItem *param, SECItem *wrappedKey, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, - int keySize, CK_FLAGS flags) -{ - CK_BBOOL ckTrue = CK_TRUE; - CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; - unsigned int templateCount; - - templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue); - return pk11_AnyUnwrapKey(wrappingKey->slot, wrappingKey->objectID, - wrapType, param, wrappedKey, target, operation, keySize, - wrappingKey->cx, keyTemplate, templateCount); -} - - -/* unwrap a symetric key with a private key. */ -PK11SymKey * -PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey, - CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize) -{ - CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); - - PK11_HandlePasswordCheck(wrappingKey->pkcs11Slot,wrappingKey->wincx); - - return pk11_AnyUnwrapKey(wrappingKey->pkcs11Slot, wrappingKey->pkcs11ID, - wrapType, NULL, wrappedKey, target, operation, keySize, - wrappingKey->wincx, NULL, 0); -} - -/* unwrap a symetric key with a private key. */ -PK11SymKey * -PK11_PubUnwrapSymKeyWithFlags(SECKEYPrivateKey *wrappingKey, - SECItem *wrappedKey, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags) -{ - CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType); - CK_BBOOL ckTrue = CK_TRUE; - CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS]; - unsigned int templateCount; - - templateCount = pk11_FlagsToAttributes(flags, keyTemplate, &ckTrue); - - PK11_HandlePasswordCheck(wrappingKey->pkcs11Slot,wrappingKey->wincx); - - return pk11_AnyUnwrapKey(wrappingKey->pkcs11Slot, wrappingKey->pkcs11ID, - wrapType, NULL, wrappedKey, target, operation, keySize, - wrappingKey->wincx, keyTemplate, templateCount); -} - -/* - * Recover the Signed data. We need this because our old verify can't - * figure out which hash algorithm to use until we decryptted this. - */ -SECStatus -PK11_VerifyRecover(SECKEYPublicKey *key, - SECItem *sig, SECItem *dsig, void *wincx) -{ - PK11SlotInfo *slot = key->pkcs11Slot; - CK_OBJECT_HANDLE id = key->pkcs11ID; - CK_MECHANISM mech = {0, NULL, 0 }; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_ULONG len; - CK_RV crv; - - mech.mechanism = pk11_mapSignKeyType(key->keyType); - - if (slot == NULL) { - slot = PK11_GetBestSlot(mech.mechanism,wincx); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return SECFailure; - } - id = PK11_ImportPublicKey(slot,key,PR_FALSE); - } else { - PK11_ReferenceSlot(slot); - } - - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_VerifyRecoverInit(session,&mech,id); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PORT_SetError( PK11_MapError(crv) ); - PK11_FreeSlot(slot); - return SECFailure; - } - len = dsig->len; - crv = PK11_GETTAB(slot)->C_VerifyRecover(session,sig->data, - sig->len, dsig->data, &len); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - dsig->len = len; - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - PK11_FreeSlot(slot); - return SECFailure; - } - PK11_FreeSlot(slot); - return SECSuccess; -} - -/* - * verify a signature from its hash. - */ -SECStatus -PK11_Verify(SECKEYPublicKey *key, SECItem *sig, SECItem *hash, void *wincx) -{ - PK11SlotInfo *slot = key->pkcs11Slot; - CK_OBJECT_HANDLE id = key->pkcs11ID; - CK_MECHANISM mech = {0, NULL, 0 }; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_RV crv; - - mech.mechanism = pk11_mapSignKeyType(key->keyType); - - if (slot == NULL) { - slot = PK11_GetBestSlot(mech.mechanism,wincx); - - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return SECFailure; - } - id = PK11_ImportPublicKey(slot,key,PR_FALSE); - - } else { - PK11_ReferenceSlot(slot); - } - - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_VerifyInit(session,&mech,id); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PK11_FreeSlot(slot); - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - crv = PK11_GETTAB(slot)->C_Verify(session,hash->data, - hash->len, sig->data, sig->len); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PK11_FreeSlot(slot); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - return SECSuccess; -} - -/* - * sign a hash. The algorithm is determined by the key. - */ -SECStatus -PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, SECItem *hash) -{ - PK11SlotInfo *slot = key->pkcs11Slot; - CK_MECHANISM mech = {0, NULL, 0 }; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_ULONG len; - CK_RV crv; - - mech.mechanism = pk11_mapSignKeyType(key->keyType); - - PK11_HandlePasswordCheck(slot, key->wincx); - - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,key->pkcs11ID); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - len = sig->len; - crv = PK11_GETTAB(slot)->C_Sign(session,hash->data, - hash->len, sig->data, &len); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - sig->len = len; - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - return SECSuccess; -} - -/* - * Now SSL 2.0 uses raw RSA stuff. These next to functions *must* use - * RSA keys, or they'll fail. We do the checks up front. If anyone comes - * up with a meaning for rawdecrypt for any other public key operation, - * then we need to move this check into some of PK11_PubDecrypt callers, - * (namely SSL 2.0). - */ -SECStatus -PK11_PubDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, - unsigned *outLen, unsigned int maxLen, unsigned char *enc, - unsigned encLen) -{ - PK11SlotInfo *slot = key->pkcs11Slot; - CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 }; - CK_ULONG out = maxLen; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_RV crv; - - if (key->keyType != rsaKey) { - PORT_SetError( SEC_ERROR_INVALID_KEY ); - return SECFailure; - } - - /* Why do we do a PK11_handle check here? for simple - * decryption? .. because the user may have asked for 'ask always' - * and this is a private key operation. In practice, thought, it's mute - * since only servers wind up using this function */ - PK11_HandlePasswordCheck(slot, key->wincx); - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_DecryptInit(session,&mech,key->pkcs11ID); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - crv = PK11_GETTAB(slot)->C_Decrypt(session,enc, encLen, - data, &out); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - *outLen = out; - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - return SECSuccess; -} - -/* The encrypt version of the above function */ -SECStatus -PK11_PubEncryptRaw(SECKEYPublicKey *key, unsigned char *enc, - unsigned char *data, unsigned dataLen, void *wincx) -{ - PK11SlotInfo *slot; - CK_MECHANISM mech = {CKM_RSA_X_509, NULL, 0 }; - CK_OBJECT_HANDLE id; - CK_ULONG out = dataLen; - PRBool owner = PR_TRUE; - CK_SESSION_HANDLE session; - CK_RV crv; - - if (key->keyType != rsaKey) { - PORT_SetError( SEC_ERROR_BAD_KEY ); - return SECFailure; - } - - slot = PK11_GetBestSlot(mech.mechanism, wincx); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return SECFailure; - } - - id = PK11_ImportPublicKey(slot,key,PR_FALSE); - - session = pk11_GetNewSession(slot,&owner); - if (!owner || !(slot->isThreadSafe)) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_EncryptInit(session,&mech,id); - if (crv != CKR_OK) { - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PK11_FreeSlot(slot); - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - crv = PK11_GETTAB(slot)->C_Encrypt(session,data,dataLen,enc,&out); - if (!owner || !(slot->isThreadSafe)) PK11_ExitSlotMonitor(slot); - pk11_CloseSession(slot,session,owner); - PK11_FreeSlot(slot); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - return SECSuccess; -} - - -/********************************************************************** - * - * Now Deal with Crypto Contexts - * - **********************************************************************/ - -/* - * the monitors... - */ -void -PK11_EnterContextMonitor(PK11Context *cx) { - /* if we own the session and our slot is ThreadSafe, only monitor - * the Context */ - if ((cx->ownSession) && (cx->slot->isThreadSafe)) { - /* Should this use monitors instead? */ - PZ_Lock(cx->sessionLock); - } else { - PK11_EnterSlotMonitor(cx->slot); - } -} - -void -PK11_ExitContextMonitor(PK11Context *cx) { - /* if we own the session and our slot is ThreadSafe, only monitor - * the Context */ - if ((cx->ownSession) && (cx->slot->isThreadSafe)) { - /* Should this use monitors instead? */ - PZ_Unlock(cx->sessionLock); - } else { - PK11_ExitSlotMonitor(cx->slot); - } -} - -/* - * Free up a Cipher Context - */ -void -PK11_DestroyContext(PK11Context *context, PRBool freeit) -{ - SECStatus rv = SECFailure; - if (context->ownSession && context->key && /* context owns session & key */ - context->key->session == context->session && /* sharing session */ - !context->key->sessionOwner) /* sanity check */ - { - /* session still valid, let the key free it as necessary */ - rv = PK11_Finalize(context); /* end any ongoing activity */ - if (rv == SECSuccess) { - context->key->sessionOwner = PR_TRUE; - } /* else couldn't finalize the session, close it */ - } - if (rv == SECFailure) { - pk11_CloseSession(context->slot,context->session,context->ownSession); - } - /* initialize the critical fields of the context */ - if (context->savedData != NULL ) PORT_Free(context->savedData); - if (context->key) PK11_FreeSymKey(context->key); - if (context->param) SECITEM_FreeItem(context->param, PR_TRUE); - if (context->sessionLock) PZ_DestroyLock(context->sessionLock); - PK11_FreeSlot(context->slot); - if (freeit) PORT_Free(context); -} - -/* - * save the current context. Allocate Space if necessary. - */ -static unsigned char * -pk11_saveContextHelper(PK11Context *context, unsigned char *buffer, - unsigned long *savedLength) -{ - CK_RV crv; - - /* If buffer is NULL, this will get the length */ - crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session, - (CK_BYTE_PTR)buffer, - savedLength); - if (!buffer || (crv == CKR_BUFFER_TOO_SMALL)) { - /* the given buffer wasn't big enough (or was NULL), but we - * have the length, so try again with a new buffer and the - * correct length - */ - unsigned long bufLen = *savedLength; - buffer = PORT_Alloc(bufLen); - if (buffer == NULL) { - return (unsigned char *)NULL; - } - crv = PK11_GETTAB(context->slot)->C_GetOperationState( - context->session, - (CK_BYTE_PTR)buffer, - savedLength); - if (crv != CKR_OK) { - PORT_ZFree(buffer, bufLen); - } - } - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return (unsigned char *)NULL; - } - return buffer; -} - -void * -pk11_saveContext(PK11Context *context, void *space, unsigned long *savedLength) -{ - return pk11_saveContextHelper(context, - (unsigned char *)space, savedLength); -} - -/* - * restore the current context - */ -SECStatus -pk11_restoreContext(PK11Context *context,void *space, unsigned long savedLength) -{ - CK_RV crv; - CK_OBJECT_HANDLE objectID = (context->key) ? context->key->objectID: - CK_INVALID_HANDLE; - - PORT_Assert(space != NULL); - if (space == NULL) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - crv = PK11_GETTAB(context->slot)->C_SetOperationState(context->session, - (CK_BYTE_PTR)space, savedLength, objectID, 0); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv)); - return SECFailure; - } - return SECSuccess; -} - -SECStatus pk11_Finalize(PK11Context *context); - -/* - * Context initialization. Used by all flavors of CreateContext - */ -static SECStatus -pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info) -{ - CK_RV crv; - PK11SymKey *symKey = context->key; - SECStatus rv = SECSuccess; - - switch (context->operation) { - case CKA_ENCRYPT: - crv=PK11_GETTAB(context->slot)->C_EncryptInit(context->session, - mech_info, symKey->objectID); - break; - case CKA_DECRYPT: - if (context->fortezzaHack) { - CK_ULONG count = 0;; - /* generate the IV for fortezza */ - crv=PK11_GETTAB(context->slot)->C_EncryptInit(context->session, - mech_info, symKey->objectID); - if (crv != CKR_OK) break; - PK11_GETTAB(context->slot)->C_EncryptFinal(context->session, - NULL, &count); - } - crv=PK11_GETTAB(context->slot)->C_DecryptInit(context->session, - mech_info, symKey->objectID); - break; - case CKA_SIGN: - crv=PK11_GETTAB(context->slot)->C_SignInit(context->session, - mech_info, symKey->objectID); - break; - case CKA_VERIFY: - crv=PK11_GETTAB(context->slot)->C_SignInit(context->session, - mech_info, symKey->objectID); - break; - case CKA_DIGEST: - crv=PK11_GETTAB(context->slot)->C_DigestInit(context->session, - mech_info); - break; - default: - crv = CKR_OPERATION_NOT_INITIALIZED; - break; - } - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - - /* - * handle session starvation case.. use our last session to multiplex - */ - if (!context->ownSession) { - context->savedData = pk11_saveContext(context,context->savedData, - &context->savedLength); - if (context->savedData == NULL) rv = SECFailure; - /* clear out out session for others to use */ - pk11_Finalize(context); - } - return rv; -} - - -/* - * Common Helper Function do come up with a new context. - */ -static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type, - PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, - SECItem *param) -{ - CK_MECHANISM mech_info; - PK11Context *context; - SECStatus rv; - - PORT_Assert(slot != NULL); - if (!slot) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - context = (PK11Context *) PORT_Alloc(sizeof(PK11Context)); - if (context == NULL) { - return NULL; - } - - /* now deal with the fortezza hack... the fortezza hack is an attempt - * to get around the issue of the card not allowing you to do a FORTEZZA - * LoadIV/Encrypt, which was added because such a combination could be - * use to circumvent the key escrow system. Unfortunately SSL needs to - * do this kind of operation, so in SSL we do a loadIV (to verify it), - * Then GenerateIV, and through away the first 8 bytes on either side - * of the connection.*/ - context->fortezzaHack = PR_FALSE; - if (type == CKM_SKIPJACK_CBC64) { - if (symKey->origin == PK11_OriginFortezzaHack) { - context->fortezzaHack = PR_TRUE; - } - } - - /* initialize the critical fields of the context */ - context->operation = operation; - context->key = symKey ? PK11_ReferenceSymKey(symKey) : NULL; - context->slot = PK11_ReferenceSlot(slot); - if (symKey && symKey->sessionOwner) { - /* The symkey owns a session. Adopt that session. */ - context->session = symKey->session; - context->ownSession = symKey->sessionOwner; - symKey->sessionOwner = PR_FALSE; - } else { - context->session = pk11_GetNewSession(slot, &context->ownSession); - } - context->cx = symKey ? symKey->cx : NULL; - /* get our session */ - context->savedData = NULL; - - /* save the parameters so that some digesting stuff can do multiple - * begins on a single context */ - context->type = type; - context->param = SECITEM_DupItem(param); - context->init = PR_FALSE; - context->sessionLock = PZ_NewLock(nssILockPK11cxt); - if ((context->param == NULL) || (context->sessionLock == NULL)) { - PK11_DestroyContext(context,PR_TRUE); - return NULL; - } - - mech_info.mechanism = type; - mech_info.pParameter = param->data; - mech_info.ulParameterLen = param->len; - PK11_EnterContextMonitor(context); - rv = pk11_context_init(context,&mech_info); - PK11_ExitContextMonitor(context); - - if (rv != SECSuccess) { - PK11_DestroyContext(context,PR_TRUE); - return NULL; - } - context->init = PR_TRUE; - return context; -} - - -/* - * put together the various PK11_Create_Context calls used by different - * parts of libsec. - */ -PK11Context * -__PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, - SECItem *param, void *wincx) -{ - PK11SymKey *symKey; - PK11Context *context; - - /* first get a slot */ - if (slot == NULL) { - slot = PK11_GetBestSlot(type,wincx); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - } else { - PK11_ReferenceSlot(slot); - } - - /* now import the key */ - symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx); - if (symKey == NULL) return NULL; - - context = PK11_CreateContextBySymKey(type, operation, symKey, param); - - PK11_FreeSymKey(symKey); - PK11_FreeSlot(slot); - - return context; -} - -PK11Context * -PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, - SECItem *param, void *wincx) -{ - return __PK11_CreateContextByRawKey(slot, type, origin, operation, - key, param, wincx); -} - - -/* - * Create a context from a key. We really should make sure we aren't using - * the same key in multiple session! - */ -PK11Context * -PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type,CK_ATTRIBUTE_TYPE operation, - PK11SymKey *symKey, SECItem *param) -{ - PK11SymKey *newKey; - PK11Context *context; - - /* if this slot doesn't support the mechanism, go to a slot that does */ - newKey = pk11_ForceSlot(symKey,type,operation); - if (newKey == NULL) { - PK11_ReferenceSymKey(symKey); - } else { - symKey = newKey; - } - - - /* Context Adopts the symKey.... */ - context = pk11_CreateNewContextInSlot(type, symKey->slot, operation, symKey, - param); - PK11_FreeSymKey(symKey); - return context; -} - -/* - * Digest contexts don't need keys, but the do need to find a slot. - * Macing should use PK11_CreateContextBySymKey. - */ -PK11Context * -PK11_CreateDigestContext(SECOidTag hashAlg) -{ - /* digesting has to work without authentication to the slot */ - CK_MECHANISM_TYPE type; - PK11SlotInfo *slot; - PK11Context *context; - SECItem param; - - type = PK11_AlgtagToMechanism(hashAlg); - slot = PK11_GetBestSlot(type, NULL); - if (slot == NULL) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - - /* maybe should really be PK11_GenerateNewParam?? */ - param.data = NULL; - param.len = 0; - param.type = 0; - - context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL, ¶m); - PK11_FreeSlot(slot); - return context; -} - -/* - * create a new context which is the clone of the state of old context. - */ -PK11Context * PK11_CloneContext(PK11Context *old) -{ - PK11Context *newcx; - PRBool needFree = PR_FALSE; - SECStatus rv = SECSuccess; - void *data; - unsigned long len; - - newcx = pk11_CreateNewContextInSlot(old->type, old->slot, old->operation, - old->key, old->param); - if (newcx == NULL) return NULL; - - /* now clone the save state. First we need to find the save state - * of the old session. If the old context owns it's session, - * the state needs to be saved, otherwise the state is in saveData. */ - if (old->ownSession) { - PK11_EnterContextMonitor(old); - data=pk11_saveContext(old,NULL,&len); - PK11_ExitContextMonitor(old); - needFree = PR_TRUE; - } else { - data = old->savedData; - len = old->savedLength; - } - - if (data == NULL) { - PK11_DestroyContext(newcx,PR_TRUE); - return NULL; - } - - /* now copy that state into our new context. Again we have different - * work if the new context owns it's own session. If it does, we - * restore the state gathered above. If it doesn't, we copy the - * saveData pointer... */ - if (newcx->ownSession) { - PK11_EnterContextMonitor(newcx); - rv = pk11_restoreContext(newcx,data,len); - PK11_ExitContextMonitor(newcx); - } else { - PORT_Assert(newcx->savedData != NULL); - if ((newcx->savedData == NULL) || (newcx->savedLength < len)) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - rv = SECFailure; - } else { - PORT_Memcpy(newcx->savedData,data,len); - newcx->savedLength = len; - } - } - - if (needFree) PORT_Free(data); - - if (rv != SECSuccess) { - PK11_DestroyContext(newcx,PR_TRUE); - return NULL; - } - return newcx; -} - -/* - * save the current context state into a variable. Required to make FORTEZZA - * work. - */ -SECStatus -PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength) -{ - unsigned char * data = NULL; - CK_ULONG length = saveLength; - - if (cx->ownSession) { - PK11_EnterContextMonitor(cx); - data = pk11_saveContextHelper(cx, save, &length); - PK11_ExitContextMonitor(cx); - if (data) *len = length; - } else if ((unsigned) saveLength >= cx->savedLength) { - data = (unsigned char*)cx->savedData; - if (cx->savedData) { - PORT_Memcpy(save,cx->savedData,cx->savedLength); - } - *len = cx->savedLength; - } - if (data != NULL) { - if (cx->ownSession) { - PORT_ZFree(data, length); - } - return SECSuccess; - } else { - return SECFailure; - } -} - -/* same as above, but may allocate the return buffer. */ -unsigned char * -PK11_SaveContextAlloc(PK11Context *cx, - unsigned char *preAllocBuf, unsigned int pabLen, - unsigned int *stateLen) -{ - unsigned char *stateBuf = NULL; - unsigned long length = (unsigned long)pabLen; - - if (cx->ownSession) { - PK11_EnterContextMonitor(cx); - stateBuf = pk11_saveContextHelper(cx, preAllocBuf, &length); - PK11_ExitContextMonitor(cx); - *stateLen = (stateBuf != NULL) ? length : 0; - } else { - if (pabLen < cx->savedLength) { - stateBuf = (unsigned char *)PORT_Alloc(cx->savedLength); - if (!stateBuf) { - return (unsigned char *)NULL; - } - } else { - stateBuf = preAllocBuf; - } - if (cx->savedData) { - PORT_Memcpy(stateBuf, cx->savedData, cx->savedLength); - } - *stateLen = cx->savedLength; - } - return stateBuf; -} - -/* - * restore the context state into a new running context. Also required for - * FORTEZZA . - */ -SECStatus -PK11_RestoreContext(PK11Context *cx,unsigned char *save,int len) -{ - SECStatus rv = SECSuccess; - if (cx->ownSession) { - PK11_EnterContextMonitor(cx); - pk11_Finalize(cx); - rv = pk11_restoreContext(cx,save,len); - PK11_ExitContextMonitor(cx); - } else { - PORT_Assert(cx->savedData != NULL); - if ((cx->savedData == NULL) || (cx->savedLength < (unsigned) len)) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - rv = SECFailure; - } else { - PORT_Memcpy(cx->savedData,save,len); - cx->savedLength = len; - } - } - return rv; -} - -/* - * This is to get FIPS compliance until we can convert - * libjar to use PK11_ hashing functions. It returns PR_FALSE - * if we can't get a PK11 Context. - */ -PRBool -PK11_HashOK(SECOidTag algID) { - PK11Context *cx; - - cx = PK11_CreateDigestContext(algID); - if (cx == NULL) return PR_FALSE; - PK11_DestroyContext(cx, PR_TRUE); - return PR_TRUE; -} - - - -/* - * start a new digesting or Mac'ing operation on this context - */ -SECStatus PK11_DigestBegin(PK11Context *cx) -{ - CK_MECHANISM mech_info; - SECStatus rv; - - if (cx->init == PR_TRUE) { - return SECSuccess; - } - - /* - * make sure the old context is clear first - */ - PK11_EnterContextMonitor(cx); - pk11_Finalize(cx); - - mech_info.mechanism = cx->type; - mech_info.pParameter = cx->param->data; - mech_info.ulParameterLen = cx->param->len; - rv = pk11_context_init(cx,&mech_info); - PK11_ExitContextMonitor(cx); - - if (rv != SECSuccess) { - return SECFailure; - } - cx->init = PR_TRUE; - return SECSuccess; -} - -SECStatus -PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, unsigned char *in, - int32 len) { - PK11Context *context; - unsigned int max_length; - unsigned int out_length; - SECStatus rv; - - context = PK11_CreateDigestContext(hashAlg); - if (context == NULL) return SECFailure; - - rv = PK11_DigestBegin(context); - if (rv != SECSuccess) { - PK11_DestroyContext(context, PR_TRUE); - return rv; - } - - rv = PK11_DigestOp(context, in, len); - if (rv != SECSuccess) { - PK11_DestroyContext(context, PR_TRUE); - return rv; - } - - /* we need the output length ... maybe this should be table driven...*/ - switch (hashAlg) { - case SEC_OID_SHA1: max_length = SHA1_LENGTH; break; - case SEC_OID_MD2: max_length = MD2_LENGTH; break; - case SEC_OID_MD5: max_length = MD5_LENGTH; break; - default: max_length = 16; break; - } - - rv = PK11_DigestFinal(context,out,&out_length,max_length); - PK11_DestroyContext(context, PR_TRUE); - return rv; -} - - -/* - * execute a bulk encryption operation - */ -SECStatus -PK11_CipherOp(PK11Context *context, unsigned char * out, int *outlen, - int maxout, unsigned char *in, int inlen) -{ - CK_RV crv = CKR_OK; - CK_ULONG length = maxout; - CK_ULONG offset =0; - SECStatus rv = SECSuccess; - unsigned char *saveOut = out; - unsigned char *allocOut = NULL; - - /* if we ran out of session, we need to restore our previously stored - * state. - */ - PK11_EnterContextMonitor(context); - if (!context->ownSession) { - rv = pk11_restoreContext(context,context->savedData, - context->savedLength); - if (rv != SECSuccess) { - PK11_ExitContextMonitor(context); - return rv; - } - } - - /* - * The fortezza hack is to send 8 extra bytes on the first encrypted and - * loose them on the first decrypt. - */ - if (context->fortezzaHack) { - unsigned char random[8]; - if (context->operation == CKA_ENCRYPT) { - PK11_ExitContextMonitor(context); - rv = PK11_GenerateRandom(random,sizeof(random)); - PK11_EnterContextMonitor(context); - - /* since we are offseting the output, we can't encrypt back into - * the same buffer... allocate a temporary buffer just for this - * call. */ - allocOut = out = (unsigned char*)PORT_Alloc(maxout); - if (out == NULL) { - PK11_ExitContextMonitor(context); - return SECFailure; - } - crv = PK11_GETTAB(context->slot)->C_EncryptUpdate(context->session, - random,sizeof(random),out,&length); - - out += length; - maxout -= length; - offset = length; - } else if (context->operation == CKA_DECRYPT) { - length = sizeof(random); - crv = PK11_GETTAB(context->slot)->C_DecryptUpdate(context->session, - in,sizeof(random),random,&length); - inlen -= length; - in += length; - context->fortezzaHack = PR_FALSE; - } - } - - switch (context->operation) { - case CKA_ENCRYPT: - length = maxout; - crv=PK11_GETTAB(context->slot)->C_EncryptUpdate(context->session, - in, inlen, out, &length); - length += offset; - break; - case CKA_DECRYPT: - length = maxout; - crv=PK11_GETTAB(context->slot)->C_DecryptUpdate(context->session, - in, inlen, out, &length); - break; - default: - crv = CKR_OPERATION_NOT_INITIALIZED; - break; - } - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - *outlen = 0; - rv = SECFailure; - } else { - *outlen = length; - } - - if (context->fortezzaHack) { - if (context->operation == CKA_ENCRYPT) { - PORT_Assert(allocOut); - PORT_Memcpy(saveOut, allocOut, length); - PORT_Free(allocOut); - } - context->fortezzaHack = PR_FALSE; - } - - /* - * handle session starvation case.. use our last session to multiplex - */ - if (!context->ownSession) { - context->savedData = pk11_saveContext(context,context->savedData, - &context->savedLength); - if (context->savedData == NULL) rv = SECFailure; - - /* clear out out session for others to use */ - pk11_Finalize(context); - } - PK11_ExitContextMonitor(context); - return rv; -} - -/* - * execute a digest/signature operation - */ -SECStatus -PK11_DigestOp(PK11Context *context, const unsigned char * in, unsigned inLen) -{ - CK_RV crv = CKR_OK; - SECStatus rv = SECSuccess; - - /* if we ran out of session, we need to restore our previously stored - * state. - */ - context->init = PR_FALSE; - PK11_EnterContextMonitor(context); - if (!context->ownSession) { - rv = pk11_restoreContext(context,context->savedData, - context->savedLength); - if (rv != SECSuccess) { - PK11_ExitContextMonitor(context); - return rv; - } - } - - switch (context->operation) { - /* also for MAC'ing */ - case CKA_SIGN: - crv=PK11_GETTAB(context->slot)->C_SignUpdate(context->session, - (unsigned char *)in, - inLen); - break; - case CKA_VERIFY: - crv=PK11_GETTAB(context->slot)->C_VerifyUpdate(context->session, - (unsigned char *)in, - inLen); - break; - case CKA_DIGEST: - crv=PK11_GETTAB(context->slot)->C_DigestUpdate(context->session, - (unsigned char *)in, - inLen); - break; - default: - crv = CKR_OPERATION_NOT_INITIALIZED; - break; - } - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - rv = SECFailure; - } - - /* - * handle session starvation case.. use our last session to multiplex - */ - if (!context->ownSession) { - context->savedData = pk11_saveContext(context,context->savedData, - &context->savedLength); - if (context->savedData == NULL) rv = SECFailure; - - /* clear out out session for others to use */ - pk11_Finalize(context); - } - PK11_ExitContextMonitor(context); - return rv; -} - -/* - * Digest a key if possible./ - */ -SECStatus -PK11_DigestKey(PK11Context *context, PK11SymKey *key) -{ - CK_RV crv = CKR_OK; - SECStatus rv = SECSuccess; - PK11SymKey *newKey = NULL; - - /* if we ran out of session, we need to restore our previously stored - * state. - */ - if (context->slot != key->slot) { - newKey = pk11_CopyToSlot(context->slot,CKM_SSL3_SHA1_MAC,CKA_SIGN,key); - } else { - newKey = PK11_ReferenceSymKey(key); - } - - context->init = PR_FALSE; - PK11_EnterContextMonitor(context); - if (!context->ownSession) { - rv = pk11_restoreContext(context,context->savedData, - context->savedLength); - if (rv != SECSuccess) { - PK11_ExitContextMonitor(context); - PK11_FreeSymKey(newKey); - return rv; - } - } - - - if (newKey == NULL) { - crv = CKR_KEY_TYPE_INCONSISTENT; - if (key->data.data) { - crv=PK11_GETTAB(context->slot)->C_DigestUpdate(context->session, - key->data.data,key->data.len); - } - } else { - crv=PK11_GETTAB(context->slot)->C_DigestKey(context->session, - newKey->objectID); - } - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - rv = SECFailure; - } - - /* - * handle session starvation case.. use our last session to multiplex - */ - if (!context->ownSession) { - context->savedData = pk11_saveContext(context,context->savedData, - &context->savedLength); - if (context->savedData == NULL) rv = SECFailure; - - /* clear out out session for others to use */ - pk11_Finalize(context); - } - PK11_ExitContextMonitor(context); - if (newKey) PK11_FreeSymKey(newKey); - return rv; -} - -/* - * externally callable version of the lowercase pk11_finalize(). - */ -SECStatus -PK11_Finalize(PK11Context *context) { - SECStatus rv; - - PK11_EnterContextMonitor(context); - rv = pk11_Finalize(context); - PK11_ExitContextMonitor(context); - return rv; -} - -/* - * clean up a cipher operation, so the session can be used by - * someone new. - */ -SECStatus -pk11_Finalize(PK11Context *context) -{ - CK_ULONG count = 0; - CK_RV crv; - unsigned char stackBuf[256]; - unsigned char *buffer = NULL; - - if (!context->ownSession) { - return SECSuccess; - } - -finalize: - switch (context->operation) { - case CKA_ENCRYPT: - crv=PK11_GETTAB(context->slot)->C_EncryptFinal(context->session, - buffer, &count); - break; - case CKA_DECRYPT: - crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session, - buffer, &count); - break; - case CKA_SIGN: - crv=PK11_GETTAB(context->slot)->C_SignFinal(context->session, - buffer, &count); - break; - case CKA_VERIFY: - crv=PK11_GETTAB(context->slot)->C_VerifyFinal(context->session, - buffer, count); - break; - case CKA_DIGEST: - crv=PK11_GETTAB(context->slot)->C_DigestFinal(context->session, - buffer, &count); - break; - default: - crv = CKR_OPERATION_NOT_INITIALIZED; - break; - } - - if (crv != CKR_OK) { - if (crv == CKR_OPERATION_NOT_INITIALIZED) { - /* if there's no operation, it is finalized */ - return SECSuccess; - } - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - - /* try to finalize the session with a buffer */ - if (buffer == NULL && count > 0) { - if (count < sizeof stackBuf) { - buffer = stackBuf; - goto finalize; - } else { - return SECFailure; - } - } - return SECSuccess; -} - -/* - * Return the final digested or signed data... - * this routine can either take pre initialized data, or allocate data - * either out of an arena or out of the standard heap. - */ -SECStatus -PK11_DigestFinal(PK11Context *context,unsigned char *data, - unsigned int *outLen, unsigned int length) -{ - CK_ULONG len; - CK_RV crv; - SECStatus rv; - - - /* if we ran out of session, we need to restore our previously stored - * state. - */ - PK11_EnterContextMonitor(context); - if (!context->ownSession) { - rv = pk11_restoreContext(context,context->savedData, - context->savedLength); - if (rv != SECSuccess) { - PK11_ExitContextMonitor(context); - return rv; - } - } - - len = length; - switch (context->operation) { - case CKA_SIGN: - crv=PK11_GETTAB(context->slot)->C_SignFinal(context->session, - data,&len); - break; - case CKA_VERIFY: - crv=PK11_GETTAB(context->slot)->C_VerifyFinal(context->session, - data,len); - break; - case CKA_DIGEST: - crv=PK11_GETTAB(context->slot)->C_DigestFinal(context->session, - data,&len); - break; - case CKA_ENCRYPT: - crv=PK11_GETTAB(context->slot)->C_EncryptFinal(context->session, - data, &len); - break; - case CKA_DECRYPT: - crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session, - data, &len); - break; - default: - crv = CKR_OPERATION_NOT_INITIALIZED; - break; - } - PK11_ExitContextMonitor(context); - - *outLen = (unsigned int) len; - context->init = PR_FALSE; /* allow Begin to start up again */ - - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - return SECSuccess; -} - -/**************************************************************************** - * - * Now Do The PBE Functions Here... - * - ****************************************************************************/ - -static void -pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params) -{ - if (pbe_params) { - if (pbe_params->pPassword) - PORT_ZFree(pbe_params->pPassword, PR_FALSE); - if (pbe_params->pSalt) - PORT_ZFree(pbe_params->pSalt, PR_FALSE); - PORT_ZFree(pbe_params, PR_TRUE); - } -} - -SECItem * -PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations) -{ - CK_PBE_PARAMS *pbe_params = NULL; - SECItem *paramRV = NULL; - pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)); - pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len); - if (pbe_params->pPassword != NULL) { - PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); - pbe_params->ulPasswordLen = pwd->len; - } else goto loser; - pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len); - if (pbe_params->pSalt != NULL) { - PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); - pbe_params->ulSaltLen = salt->len; - } else goto loser; - pbe_params->ulIteration = (CK_ULONG)iterations; - paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); - paramRV->data = (unsigned char *)pbe_params; - return paramRV; -loser: - pk11_destroy_ck_pbe_params(pbe_params); - return NULL; -} - -void -PK11_DestroyPBEParams(SECItem *params) -{ - pk11_destroy_ck_pbe_params((CK_PBE_PARAMS *)params->data); -} - -SECAlgorithmID * -PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt) -{ - SECAlgorithmID *algid = NULL; - algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, iteration); - return algid; -} - -PK11SymKey * -PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, - SECItem *pwitem, PRBool faulty3DES, void *wincx) -{ - /* pbe stuff */ - CK_PBE_PARAMS *pbe_params; - PK11SymKey *symKey; - - if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) { - type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC; - } - if(mech == NULL) { - return NULL; - } - - pbe_params = (CK_PBE_PARAMS *)mech->data; - pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwitem->len); - if(pbe_params->pPassword != NULL) { - PORT_Memcpy(pbe_params->pPassword, pwitem->data, pwitem->len); - pbe_params->ulPasswordLen = pwitem->len; - } else { - SECITEM_ZfreeItem(mech, PR_TRUE); - return NULL; - } - - symKey = PK11_KeyGen(slot, type, mech, 0, wincx); - - PORT_ZFree(pbe_params->pPassword, pwitem->len); - pbe_params->pPassword = NULL; - pbe_params->ulPasswordLen = 0; - return symKey; -} - -PK11SymKey * -PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem, - PRBool faulty3DES, void *wincx) -{ - /* pbe stuff */ - CK_MECHANISM_TYPE type; - SECItem *mech; - PK11SymKey *symKey; - - mech = PK11_ParamFromAlgid(algid); - type = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm)); - if(faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) { - type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC; - } - if(mech == NULL) { - return NULL; - } - symKey = PK11_RawPBEKeyGen(slot, type, mech, pwitem, faulty3DES, wincx); - - SECITEM_ZfreeItem(mech, PR_TRUE); - return symKey; -} - -SECItem * -PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem) -{ - /* pbe stuff */ - CK_MECHANISM_TYPE type; - SECItem *mech; - PK11SymKey *symKey; - PK11SlotInfo *slot = PK11_GetInternalSlot(); - int iv_len = 0; - CK_PBE_PARAMS_PTR pPBEparams; - SECItem src; - SECItem *iv; - - - mech = PK11_ParamFromAlgid(algid); - type = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm)); - if(mech == NULL) { - return NULL; - } - symKey = PK11_RawPBEKeyGen(slot, type, mech, pwitem, PR_FALSE, NULL); - PK11_FreeSlot(slot); - if (symKey == NULL) { - SECITEM_ZfreeItem(mech, PR_TRUE); - return NULL; - } - PK11_FreeSymKey(symKey); - pPBEparams = (CK_PBE_PARAMS_PTR)mech->data; - iv_len = PK11_GetIVLength(type); - - src.data = (unsigned char *)pPBEparams->pInitVector; - src.len = iv_len; - iv = SECITEM_DupItem(&src); - - SECITEM_ZfreeItem(mech, PR_TRUE); - return iv; -} - - -SECStatus -PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, - SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem, - SECItem *nickname, SECItem *publicValue, PRBool isPerm, - PRBool isPrivate, KeyType keyType, - unsigned int keyUsage, void *wincx) -{ - CK_MECHANISM_TYPE mechanism; - SECItem *pbe_param, crypto_param; - PK11SymKey *key = NULL; - SECStatus rv = SECSuccess; - CK_MECHANISM cryptoMech, pbeMech; - CK_RV crv; - SECKEYPrivateKey *privKey = NULL; - PRBool faulty3DES = PR_FALSE; - int usageCount = 0; - CK_KEY_TYPE key_type; - CK_ATTRIBUTE_TYPE *usage = NULL; - CK_ATTRIBUTE_TYPE rsaUsage[] = { - CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER }; - CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN }; - CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE }; - - if((epki == NULL) || (pwitem == NULL)) - return SECFailure; - - crypto_param.data = NULL; - - mechanism = PK11_AlgtagToMechanism(SECOID_FindOIDTag( - &epki->algorithm.algorithm)); - - switch (keyType) { - default: - case rsaKey: - key_type = CKK_RSA; - switch (keyUsage & (KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE)) { - case KU_KEY_ENCIPHERMENT: - usage = rsaUsage; - usageCount = 2; - break; - case KU_DIGITAL_SIGNATURE: - usage = &rsaUsage[2]; - usageCount = 2; - break; - case KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE: - case 0: /* default to everything */ - usage = rsaUsage; - usageCount = 4; - break; - } - break; - case dhKey: - key_type = CKK_DH; - usage = dhUsage; - usageCount = sizeof(dhUsage)/sizeof(dhUsage[0]); - break; - case dsaKey: - key_type = CKK_DSA; - usage = dsaUsage; - usageCount = sizeof(dsaUsage)/sizeof(dsaUsage[0]); - break; - } - -try_faulty_3des: - pbe_param = PK11_ParamFromAlgid(&epki->algorithm); - - key = PK11_RawPBEKeyGen(slot, mechanism, pbe_param, pwitem, - faulty3DES, wincx); - if((key == NULL) || (pbe_param == NULL)) { - rv = SECFailure; - goto done; - } - - pbeMech.mechanism = mechanism; - pbeMech.pParameter = pbe_param->data; - pbeMech.ulParameterLen = pbe_param->len; - - crv = PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, - pwitem, faulty3DES); - if(crv != CKR_OK) { - rv = SECFailure; - goto done; - } - - cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMech.mechanism); - crypto_param.data = (unsigned char*)cryptoMech.pParameter; - crypto_param.len = cryptoMech.ulParameterLen; - - PORT_Assert(usage != NULL); - PORT_Assert(usageCount != 0); - privKey = PK11_UnwrapPrivKey(slot, key, cryptoMech.mechanism, - &crypto_param, &epki->encryptedData, - nickname, publicValue, isPerm, isPrivate, - key_type, usage, usageCount, wincx); - if(privKey) { - SECKEY_DestroyPrivateKey(privKey); - privKey = NULL; - rv = SECSuccess; - goto done; - } - - /* if we are unable to import the key and the mechanism is - * CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, then it is possible that - * the encrypted blob was created with a buggy key generation method - * which is described in the PKCS 12 implementation notes. So we - * need to try importing via that method. - */ - if((mechanism == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC) && (!faulty3DES)) { - /* clean up after ourselves before redoing the key generation. */ - - PK11_FreeSymKey(key); - key = NULL; - - if(pbe_param) { - SECITEM_ZfreeItem(pbe_param, PR_TRUE); - pbe_param = NULL; - } - - if(crypto_param.data) { - SECITEM_ZfreeItem(&crypto_param, PR_FALSE); - crypto_param.data = NULL; - cryptoMech.pParameter = NULL; - crypto_param.len = cryptoMech.ulParameterLen = 0; - } - - faulty3DES = PR_TRUE; - goto try_faulty_3des; - } - - /* key import really did fail */ - rv = SECFailure; - -done: - if(pbe_param != NULL) { - SECITEM_ZfreeItem(pbe_param, PR_TRUE); - pbe_param = NULL; - } - - if(crypto_param.data != NULL) { - SECITEM_ZfreeItem(&crypto_param, PR_FALSE); - } - - if(key != NULL) { - PK11_FreeSymKey(key); - } - - return rv; -} - -SECKEYPrivateKeyInfo * -PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx) -{ - return NULL; -} - -static int -pk11_private_key_encrypt_buffer_length(SECKEYPrivateKey *key) - -{ - CK_ATTRIBUTE rsaTemplate = { CKA_MODULUS, NULL, 0 }; - CK_ATTRIBUTE dsaTemplate = { CKA_PRIME, NULL, 0 }; - CK_ATTRIBUTE_PTR pTemplate; - CK_RV crv; - int length; - - if(!key) { - return -1; - } - - switch (key->keyType) { - case rsaKey: - pTemplate = &rsaTemplate; - break; - case dsaKey: - case dhKey: - pTemplate = &dsaTemplate; - break; - case fortezzaKey: - default: - pTemplate = NULL; - } - - if(!pTemplate) { - return -1; - } - - crv = PK11_GetAttributes(NULL, key->pkcs11Slot, key->pkcs11ID, - pTemplate, 1); - if(crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return -1; - } - - length = pTemplate->ulValueLen; - length *= 10; - - if(pTemplate->pValue != NULL) { - PORT_Free(pTemplate->pValue); - } - - return length; -} - -SECKEYEncryptedPrivateKeyInfo * -PK11_ExportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, SECOidTag algTag, - SECItem *pwitem, CERTCertificate *cert, int iteration, void *wincx) -{ - SECKEYEncryptedPrivateKeyInfo *epki = NULL; - SECKEYPrivateKey *pk = NULL; - PRArenaPool *arena = NULL; - SECAlgorithmID *algid; - CK_MECHANISM_TYPE mechanism; - SECItem *pbe_param = NULL, crypto_param; - PK11SymKey *key = NULL; - SECStatus rv = SECSuccess; - CK_MECHANISM pbeMech, cryptoMech; - CK_ULONG encBufLenPtr; - CK_RV crv; - SECItem encryptedKey = {siBuffer,NULL,0}; - int encryptBufLen; - - if(!pwitem) - return NULL; - - crypto_param.data = NULL; - - arena = PORT_NewArena(2048); - epki = (SECKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(arena, - sizeof(SECKEYEncryptedPrivateKeyInfo)); - if(epki == NULL) { - rv = SECFailure; - goto loser; - } - epki->arena = arena; - - pk = PK11_FindKeyByAnyCert(cert, wincx); - if(pk == NULL) { - rv = SECFailure; - goto loser; - } - - /* if we didn't specify a slot, use the slot the private key was in */ - if (!slot) { - slot = pk->pkcs11Slot; - } - - algid = SEC_PKCS5CreateAlgorithmID(algTag, NULL, iteration); - if(algid == NULL) { - rv = SECFailure; - goto loser; - } - - mechanism = PK11_AlgtagToMechanism(SECOID_FindOIDTag(&algid->algorithm)); - pbe_param = PK11_ParamFromAlgid(algid); - pbeMech.mechanism = mechanism; - pbeMech.pParameter = pbe_param->data; - pbeMech.ulParameterLen = pbe_param->len; - - /* if we specified a different slot, and the private key slot can do the - * pbe key gen, generate the key in the private key slot so we don't have - * to move it later */ - if (slot != pk->pkcs11Slot) { - if (PK11_DoesMechanism(pk->pkcs11Slot,mechanism)) { - slot = pk->pkcs11Slot; - } - } - key = PK11_RawPBEKeyGen(slot, mechanism, pbe_param, pwitem, - PR_FALSE, wincx); - - if((key == NULL) || (pbe_param == NULL)) { - rv = SECFailure; - goto loser; - } - - crv = PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, - pwitem, PR_FALSE); - if(crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMech.mechanism); - crypto_param.data = (unsigned char *)cryptoMech.pParameter; - crypto_param.len = cryptoMech.ulParameterLen; - - - encryptBufLen = pk11_private_key_encrypt_buffer_length(pk); - if(encryptBufLen == -1) { - rv = SECFailure; - goto loser; - } - encryptedKey.len = (unsigned int)encryptBufLen; - encBufLenPtr = (CK_ULONG) encryptBufLen; - encryptedKey.data = (unsigned char *)PORT_ZAlloc(encryptedKey.len); - if(!encryptedKey.data) { - rv = SECFailure; - goto loser; - } - - /* If the key isn't in the private key slot, move it */ - if (key->slot != pk->pkcs11Slot) { - PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot, - key->type, CKA_WRAP, key); - if (newkey == NULL) { - rv= SECFailure; - goto loser; - } - - /* free the old key and use the new key */ - PK11_FreeSymKey(key); - key = newkey; - } - - /* we are extracting an encrypted privateKey structure. - * which needs to be freed along with the buffer into which it is - * returned. eventually, we should retrieve an encrypted key using - * pkcs8/pkcs5. - */ - PK11_EnterSlotMonitor(pk->pkcs11Slot); - crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, - &cryptoMech, key->objectID, pk->pkcs11ID, encryptedKey.data, - &encBufLenPtr); - PK11_ExitSlotMonitor(pk->pkcs11Slot); - encryptedKey.len = (unsigned int) encBufLenPtr; - if(crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - - if(!encryptedKey.len) { - rv = SECFailure; - goto loser; - } - - rv = SECITEM_CopyItem(arena, &epki->encryptedData, &encryptedKey); - if(rv != SECSuccess) { - goto loser; - } - - rv = SECOID_CopyAlgorithmID(arena, &epki->algorithm, algid); - -loser: - if(pbe_param != NULL) { - SECITEM_ZfreeItem(pbe_param, PR_TRUE); - pbe_param = NULL; - } - - if(crypto_param.data != NULL) { - SECITEM_ZfreeItem(&crypto_param, PR_FALSE); - crypto_param.data = NULL; - } - - if(key != NULL) { - PK11_FreeSymKey(key); - } - - if (pk != NULL) { - SECKEY_DestroyPrivateKey(pk); - } - - if(rv == SECFailure) { - if(arena != NULL) { - PORT_FreeArena(arena, PR_TRUE); - } - epki = NULL; - } - - return epki; -} - - -/* - * This is required to allow FORTEZZA_NULL and FORTEZZA_RC4 - * working. This function simply gets a valid IV for the keys. - */ -SECStatus -PK11_GenerateFortezzaIV(PK11SymKey *symKey,unsigned char *iv,int len) -{ - CK_MECHANISM mech_info; - CK_ULONG count = 0; - CK_RV crv; - SECStatus rv = SECFailure; - - mech_info.mechanism = CKM_SKIPJACK_CBC64; - mech_info.pParameter = iv; - mech_info.ulParameterLen = len; - - /* generate the IV for fortezza */ - PK11_EnterSlotMonitor(symKey->slot); - crv=PK11_GETTAB(symKey->slot)->C_EncryptInit(symKey->slot->session, - &mech_info, symKey->objectID); - if (crv == CKR_OK) { - PK11_GETTAB(symKey->slot)->C_EncryptFinal(symKey->slot->session, - NULL, &count); - rv = SECSuccess; - } - PK11_ExitSlotMonitor(symKey->slot); - return rv; -} - -SECKEYPrivateKey * -PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, - CK_MECHANISM_TYPE wrapType, SECItem *param, - SECItem *wrappedKey, SECItem *label, - SECItem *idValue, PRBool perm, PRBool sensitive, - CK_KEY_TYPE keyType, CK_ATTRIBUTE_TYPE *usage, int usageCount, - void *wincx) -{ - CK_BBOOL cktrue = CK_TRUE; - CK_BBOOL ckfalse = CK_FALSE; - CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; - CK_ATTRIBUTE keyTemplate[15] ; - int templateCount = 0; - CK_OBJECT_HANDLE privKeyID; - CK_MECHANISM mechanism; - CK_ATTRIBUTE *attrs = keyTemplate; - SECItem *param_free = NULL, *ck_id; - CK_RV crv; - CK_SESSION_HANDLE rwsession; - PK11SymKey *newKey = NULL; - int i; - - if(!slot || !wrappedKey || !idValue) { - /* SET AN ERROR!!! */ - return NULL; - } - - ck_id = PK11_MakeIDFromPubKey(idValue); - if(!ck_id) { - return NULL; - } - - PK11_SETATTRS(attrs, CKA_TOKEN, perm ? &cktrue : &ckfalse, - sizeof(cktrue)); attrs++; - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; - PK11_SETATTRS(attrs, CKA_PRIVATE, sensitive ? &cktrue : &ckfalse, - sizeof(cktrue)); attrs++; - PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse, - sizeof(cktrue)); attrs++; - PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; - PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); attrs++; - for (i=0; i < usageCount; i++) { - PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue)); attrs++; - } - - if (PK11_IsInternal(slot)) { - PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, idValue->data, - idValue->len); attrs++; - } - - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount <= (sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE)) ); - - mechanism.mechanism = wrapType; - if(!param) param = param_free= PK11_ParamFromIV(wrapType, NULL); - if(param) { - mechanism.pParameter = param->data; - mechanism.ulParameterLen = param->len; - } else { - mechanism.pParameter = NULL; - mechanism.ulParameterLen = 0; - } - - if (wrappingKey->slot != slot) { - newKey = pk11_CopyToSlot(slot,wrapType,CKA_WRAP,wrappingKey); - } else { - newKey = PK11_ReferenceSymKey(wrappingKey); - } - - if (newKey) { - if (perm) { - rwsession = PK11_GetRWSession(slot); - } else { - rwsession = slot->session; - } - crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism, - newKey->objectID, - wrappedKey->data, - wrappedKey->len, keyTemplate, - templateCount, &privKeyID); - - if (perm) PK11_RestoreROSession(slot, rwsession); - PK11_FreeSymKey(newKey); - } else { - crv = CKR_FUNCTION_NOT_SUPPORTED; - } - - if(ck_id) { - SECITEM_FreeItem(ck_id, PR_TRUE); - ck_id = NULL; - } - - if (crv != CKR_OK) { - /* we couldn't unwrap the key, use the internal module to do the - * unwrap, then load the new key into the token */ - PK11SlotInfo *int_slot = PK11_GetInternalSlot(); - - if (int_slot && (slot != int_slot)) { - SECKEYPrivateKey *privKey = PK11_UnwrapPrivKey(int_slot, - wrappingKey, wrapType, param, wrappedKey, label, - idValue, PR_FALSE, PR_FALSE, - keyType, usage, usageCount, wincx); - if (privKey) { - SECKEYPrivateKey *newPrivKey = pk11_loadPrivKey(slot,privKey, - NULL,perm,sensitive); - SECKEY_DestroyPrivateKey(privKey); - PK11_FreeSlot(int_slot); - return newPrivKey; - } - } - if (int_slot) PK11_FreeSlot(int_slot); - PORT_SetError( PK11_MapError(crv) ); - return NULL; - } - return PK11_MakePrivKey(slot, nullKey, PR_FALSE, privKeyID, wincx); -} - -#define ALLOC_BLOCK 10 - -/* - * Now we're going to wrap a SECKEYPrivateKey with a PK11SymKey - * The strategy is to get both keys to reside in the same slot, - * one that can perform the desired crypto mechanism and then - * call C_WrapKey after all the setup has taken place. - */ -SECStatus -PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, - SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType, - SECItem *param, SECItem *wrappedKey, void *wincx) -{ - PK11SlotInfo *privSlot = privKey->pkcs11Slot; /* The slot where - * the private key - * we are going to - * wrap lives. - */ - PK11SymKey *newSymKey = NULL; - SECKEYPrivateKey *newPrivKey = NULL; - SECItem *param_free = NULL; - CK_ULONG len = wrappedKey->len; - CK_MECHANISM mech; - CK_RV crv; - - if (!privSlot || !PK11_DoesMechanism(privSlot, wrapType)) { - /* Figure out a slot that does the mechanism and try to import - * the private key onto that slot. - */ - PK11SlotInfo *int_slot = PK11_GetInternalSlot(); - - privSlot = int_slot; /* The private key has a new home */ - newPrivKey = pk11_loadPrivKey(privSlot,privKey,NULL,PR_FALSE,PR_FALSE); - /* newPrivKey has allocated its own reference to the slot, so it's - * safe until we destroy newPrivkey. - */ - PK11_FreeSlot(int_slot); - if (newPrivKey == NULL) { - return SECFailure; - } - privKey = newPrivKey; - } - - if (privSlot != wrappingKey->slot) { - newSymKey = pk11_CopyToSlot (privSlot, wrapType, CKA_WRAP, - wrappingKey); - wrappingKey = newSymKey; - } - - if (wrappingKey == NULL) { - if (newPrivKey) { - SECKEY_DestroyPrivateKey(newPrivKey); - } - return SECFailure; - } - mech.mechanism = wrapType; - if (!param) { - param = param_free = PK11_ParamFromIV(wrapType, NULL); - } - if (param) { - mech.pParameter = param->data; - mech.ulParameterLen = param->len; - } else { - mech.pParameter = NULL; - mech.ulParameterLen = 0; - } - - PK11_EnterSlotMonitor(privSlot); - crv = PK11_GETTAB(privSlot)->C_WrapKey(privSlot->session, &mech, - wrappingKey->objectID, - privKey->pkcs11ID, - wrappedKey->data, &len); - PK11_ExitSlotMonitor(privSlot); - - if (newSymKey) { - PK11_FreeSymKey(newSymKey); - } - if (newPrivKey) { - SECKEY_DestroyPrivateKey(newPrivKey); - } - - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return SECFailure; - } - - wrappedKey->len = len; - return SECSuccess; -} - -void -PK11_SetFortezzaHack(PK11SymKey *symKey) { - symKey->origin = PK11_OriginFortezzaHack; -} - -SECItem* -PK11_DEREncodePublicKey(SECKEYPublicKey *pubk) -{ - CERTSubjectPublicKeyInfo *spki=NULL; - SECItem *spkiDER = NULL; - - if( pubk == NULL ) { - return NULL; - } - - /* get the subjectpublickeyinfo */ - spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); - if( spki == NULL ) { - goto finish; - } - - /* DER-encode the subjectpublickeyinfo */ - spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki, - CERT_SubjectPublicKeyInfoTemplate); - -finish: - return spkiDER; -} - -PK11SymKey* -PK11_CopySymKeyForSigning(PK11SymKey *originalKey, CK_MECHANISM_TYPE mech) -{ - return pk11_CopyToSlot(PK11_GetSlotFromKey(originalKey), mech, CKA_SIGN, - originalKey); -} - -char * -PK11_GetSymKeyNickname(PK11SymKey *symKey) -{ - return PK11_GetObjectNickname(symKey->slot,symKey->objectID); -} - -char * -PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey) -{ - return PK11_GetObjectNickname(privKey->pkcs11Slot,privKey->pkcs11ID); -} - -char * -PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey) -{ - return PK11_GetObjectNickname(pubKey->pkcs11Slot,pubKey->pkcs11ID); -} - -SECStatus -PK11_SetSymKeyNickname(PK11SymKey *symKey, const char *nickname) -{ - return PK11_SetObjectNickname(symKey->slot,symKey->objectID,nickname); -} - -SECStatus -PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, const char *nickname) -{ - return PK11_SetObjectNickname(privKey->pkcs11Slot, - privKey->pkcs11ID,nickname); -} - -SECStatus -PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname) -{ - return PK11_SetObjectNickname(pubKey->pkcs11Slot, - pubKey->pkcs11ID,nickname); -} - -SECKEYPQGParams * -PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey) -{ - CK_ATTRIBUTE pTemplate[] = { - { CKA_PRIME, NULL, 0 }, - { CKA_SUBPRIME, NULL, 0 }, - { CKA_BASE, NULL, 0 }, - }; - int pTemplateLen = sizeof(pTemplate)/sizeof(pTemplate[0]); - PRArenaPool *arena = NULL; - SECKEYPQGParams *params; - CK_RV crv; - - - arena = PORT_NewArena(2048); - if (arena == NULL) { - goto loser; - } - params=(SECKEYPQGParams *)PORT_ArenaZAlloc(arena,sizeof(SECKEYPQGParams)); - if (params == NULL) { - goto loser; - } - - crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID, - pTemplate, pTemplateLen); - if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - goto loser; - } - - params->arena = arena; - params->prime.data = pTemplate[0].pValue; - params->prime.len = pTemplate[0].ulValueLen; - params->subPrime.data = pTemplate[1].pValue; - params->subPrime.len = pTemplate[1].ulValueLen; - params->base.data = pTemplate[2].pValue; - params->base.len = pTemplate[2].ulValueLen; - - return params; - -loser: - if (arena != NULL) { - PORT_FreeArena(arena,PR_FALSE); - } - return NULL; -} - -PK11SymKey * -PK11_GetNextSymKey(PK11SymKey *symKey) -{ - return symKey ? symKey->next : NULL; -} diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c deleted file mode 100644 index 0a92f2105..000000000 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ /dev/null @@ -1,4609 +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): - * Dr Stephen Henson <stephen.henson@gemplus.com> - * - * 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. - */ -/* - * Deal with PKCS #11 Slots. - */ -#include "seccomon.h" -#include "secmod.h" -#include "nssilock.h" -#include "secmodi.h" -#include "pkcs11t.h" -#include "pk11func.h" -#include "cert.h" -#include "key.h" -#include "secitem.h" -#include "secder.h" -#include "secasn1.h" -#include "secoid.h" -#include "prtime.h" -#include "prlong.h" -#include "secerr.h" -/*#include "secpkcs5.h" */ - -#include "dev.h" -#include "dev3hack.h" -#include "pki3hack.h" -#include "pkim.h" - - -/************************************************************* - * local static and global data - *************************************************************/ - -/* - * This array helps parsing between names, mechanisms, and flags. - * to make the config files understand more entries, add them - * to this table. (NOTE: we need function to export this table and it's size) - */ -PK11DefaultArrayEntry PK11_DefaultArray[] = { - { "RSA", SECMOD_RSA_FLAG, CKM_RSA_PKCS }, - { "DSA", SECMOD_DSA_FLAG, CKM_DSA }, - { "DH", SECMOD_DH_FLAG, CKM_DH_PKCS_DERIVE }, - { "RC2", SECMOD_RC2_FLAG, CKM_RC2_CBC }, - { "RC4", SECMOD_RC4_FLAG, CKM_RC4 }, - { "DES", SECMOD_DES_FLAG, CKM_DES_CBC }, - { "AES", SECMOD_AES_FLAG, CKM_AES_CBC }, - { "RC5", SECMOD_RC5_FLAG, CKM_RC5_CBC }, - { "SHA-1", SECMOD_SHA1_FLAG, CKM_SHA_1 }, - { "MD5", SECMOD_MD5_FLAG, CKM_MD5 }, - { "MD2", SECMOD_MD2_FLAG, CKM_MD2 }, - { "SSL", SECMOD_SSL_FLAG, CKM_SSL3_PRE_MASTER_KEY_GEN }, - { "TLS", SECMOD_TLS_FLAG, CKM_TLS_MASTER_KEY_DERIVE }, - { "SKIPJACK", SECMOD_FORTEZZA_FLAG, CKM_SKIPJACK_CBC64 }, - { "Publicly-readable certs", SECMOD_FRIENDLY_FLAG, CKM_INVALID_MECHANISM }, - { "Random Num Generator", SECMOD_RANDOM_FLAG, CKM_FAKE_RANDOM }, -}; -int num_pk11_default_mechanisms = sizeof(PK11_DefaultArray) / sizeof(PK11_DefaultArray[0]); - -/* - * These slotlists are lists of modules which provide default support for - * a given algorithm or mechanism. - */ -static PK11SlotList pk11_aesSlotList, - pk11_desSlotList, - pk11_rc4SlotList, - pk11_rc2SlotList, - pk11_rc5SlotList, - pk11_sha1SlotList, - pk11_md5SlotList, - pk11_md2SlotList, - pk11_rsaSlotList, - pk11_dsaSlotList, - pk11_dhSlotList, - pk11_ideaSlotList, - pk11_sslSlotList, - pk11_tlsSlotList, - pk11_randomSlotList; - -/* - * Tables used for Extended mechanism mapping (currently not used) - */ -typedef struct { - CK_MECHANISM_TYPE keyGen; - CK_KEY_TYPE keyType; - CK_MECHANISM_TYPE type; - int blockSize; - int iv; -} pk11MechanismData; - -static pk11MechanismData pk11_default = - { CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET, CKM_FAKE_RANDOM, 8, 8 }; -static pk11MechanismData *pk11_MechanismTable = NULL; -static int pk11_MechTableSize = 0; -static int pk11_MechEntrySize = 0; - -/* - * list of mechanisms we're willing to wrap secret keys with. - * This list is ordered by preference. - */ -CK_MECHANISM_TYPE wrapMechanismList[] = { - CKM_DES3_ECB, - CKM_CAST5_ECB, - CKM_AES_ECB, - CKM_CAST5_ECB, - CKM_DES_ECB, - CKM_KEY_WRAP_LYNKS, - CKM_IDEA_ECB, - CKM_CAST3_ECB, - CKM_CAST_ECB, - CKM_RC5_ECB, - CKM_RC2_ECB, - CKM_CDMF_ECB, - CKM_SKIPJACK_WRAP, -}; - -int wrapMechanismCount = sizeof(wrapMechanismList)/sizeof(wrapMechanismList[0]); - -/* - * This structure keeps track of status that spans all the Slots. - * NOTE: This is a global data structure. It semantics expect thread crosstalk - * be very careful when you see it used. - * It's major purpose in life is to allow the user to log in one PER - * Tranaction, even if a transaction spans threads. The problem is the user - * may have to enter a password one just to be able to look at the - * personalities/certificates (s)he can use. Then if Auth every is one, they - * may have to enter the password again to use the card. See PK11_StartTransac - * and PK11_EndTransaction. - */ -static struct PK11GlobalStruct { - int transaction; - PRBool inTransaction; - char *(PR_CALLBACK *getPass)(PK11SlotInfo *,PRBool,void *); - PRBool (PR_CALLBACK *verifyPass)(PK11SlotInfo *,void *); - PRBool (PR_CALLBACK *isLoggedIn)(PK11SlotInfo *,void *); -} PK11_Global = { 1, PR_FALSE, NULL, NULL, NULL }; - -/************************************************************ - * Generic Slot List and Slot List element manipulations - ************************************************************/ - -/* - * allocate a new list - */ -PK11SlotList * -PK11_NewSlotList(void) -{ - PK11SlotList *list; - - list = (PK11SlotList *)PORT_Alloc(sizeof(PK11SlotList)); - if (list == NULL) return NULL; - list->head = NULL; - list->tail = NULL; -#ifdef PKCS11_USE_THREADS - list->lock = PZ_NewLock(nssILockList); - if (list->lock == NULL) { - PORT_Free(list); - return NULL; - } -#else - list->lock = NULL; -#endif - - return list; -} - -/* - * free a list element when all the references go away. - */ -static void -pk11_FreeListElement(PK11SlotList *list, PK11SlotListElement *le) -{ - PRBool freeit = PR_FALSE; - - PK11_USE_THREADS(PZ_Lock((PZLock *)(list->lock));) - if (le->refCount-- == 1) { - freeit = PR_TRUE; - } - PK11_USE_THREADS(PZ_Unlock((PZLock *)(list->lock));) - if (freeit) { - PK11_FreeSlot(le->slot); - PORT_Free(le); - } -} - -/* - * if we are freeing the list, we must be the only ones with a pointer - * to the list. - */ -void -PK11_FreeSlotList(PK11SlotList *list) -{ - PK11SlotListElement *le, *next ; - if (list == NULL) return; - - for (le = list->head ; le; le = next) { - next = le->next; - pk11_FreeListElement(list,le); - } - PK11_USE_THREADS(PZ_DestroyLock((PZLock *)(list->lock));) - PORT_Free(list); -} - -/* - * add a slot to a list - */ -SECStatus -PK11_AddSlotToList(PK11SlotList *list,PK11SlotInfo *slot) -{ - PK11SlotListElement *le; - - le = (PK11SlotListElement *) PORT_Alloc(sizeof(PK11SlotListElement)); - if (le == NULL) return SECFailure; - - le->slot = PK11_ReferenceSlot(slot); - le->prev = NULL; - le->refCount = 1; - PK11_USE_THREADS(PZ_Lock((PZLock *)(list->lock));) - if (list->head) list->head->prev = le; else list->tail = le; - le->next = list->head; - list->head = le; - PK11_USE_THREADS(PZ_Unlock((PZLock *)(list->lock));) - - return SECSuccess; -} - -/* - * remove a slot entry from the list - */ -SECStatus -PK11_DeleteSlotFromList(PK11SlotList *list,PK11SlotListElement *le) -{ - PK11_USE_THREADS(PZ_Lock((PZLock *)(list->lock));) - if (le->prev) le->prev->next = le->next; else list->head = le->next; - if (le->next) le->next->prev = le->prev; else list->tail = le->prev; - le->next = le->prev = NULL; - PK11_USE_THREADS(PZ_Unlock((PZLock *)(list->lock));) - pk11_FreeListElement(list,le); - return SECSuccess; -} - -/* - * Move a list to the end of the target list. NOTE: There is no locking - * here... This assumes BOTH lists are private copy lists. - */ -SECStatus -PK11_MoveListToList(PK11SlotList *target,PK11SlotList *src) -{ - if (src->head == NULL) return SECSuccess; - - if (target->tail == NULL) { - target->head = src->head; - } else { - target->tail->next = src->head; - } - src->head->prev = target->tail; - target->tail = src->tail; - src->head = src->tail = NULL; - return SECSuccess; -} - -/* - * get an element from the list with a reference. You must own the list. - */ -PK11SlotListElement * -PK11_GetFirstRef(PK11SlotList *list) -{ - PK11SlotListElement *le; - - le = list->head; - if (le != NULL) (le)->refCount++; - return le; -} - -/* - * get the next element from the list with a reference. You must own the list. - */ -PK11SlotListElement * -PK11_GetNextRef(PK11SlotList *list, PK11SlotListElement *le, PRBool restart) -{ - PK11SlotListElement *new_le; - new_le = le->next; - if (new_le) new_le->refCount++; - pk11_FreeListElement(list,le); - return new_le; -} - -/* - * get an element safely from the list. This just makes sure that if - * this element is not deleted while we deal with it. - */ -PK11SlotListElement * -PK11_GetFirstSafe(PK11SlotList *list) -{ - PK11SlotListElement *le; - - PK11_USE_THREADS(PZ_Lock((PZLock *)(list->lock));) - le = list->head; - if (le != NULL) (le)->refCount++; - PK11_USE_THREADS(PZ_Unlock((PZLock *)(list->lock));) - return le; -} - -/* - * NOTE: if this element gets deleted, we can no longer safely traverse using - * it's pointers. We can either terminate the loop, or restart from the - * beginning. This is controlled by the restart option. - */ -PK11SlotListElement * -PK11_GetNextSafe(PK11SlotList *list, PK11SlotListElement *le, PRBool restart) -{ - PK11SlotListElement *new_le; - PK11_USE_THREADS(PZ_Lock((PZLock *)(list->lock));) - new_le = le->next; - if (le->next == NULL) { - /* if the prev and next fields are NULL then either this element - * has been removed and we need to walk the list again (if restart - * is true) or this was the only element on the list */ - if ((le->prev == NULL) && restart && (list->head != le)) { - new_le = list->head; - } - } - if (new_le) new_le->refCount++; - PK11_USE_THREADS(PZ_Unlock((PZLock *)(list->lock));) - pk11_FreeListElement(list,le); - return new_le; -} - - -/* - * Find the element that holds this slot - */ -PK11SlotListElement * -PK11_FindSlotElement(PK11SlotList *list,PK11SlotInfo *slot) -{ - PK11SlotListElement *le; - - for (le = PK11_GetFirstSafe(list); le; - le = PK11_GetNextSafe(list,le,PR_TRUE)) { - if (le->slot == slot) return le; - } - return NULL; -} - -/************************************************************ - * Generic Slot Utilities - ************************************************************/ -/* - * Create a new slot structure - */ -PK11SlotInfo * -PK11_NewSlotInfo(void) -{ - PK11SlotInfo *slot; - - slot = (PK11SlotInfo *)PORT_Alloc(sizeof(PK11SlotInfo)); - if (slot == NULL) return slot; - -#ifdef PKCS11_USE_THREADS - slot->refLock = PZ_NewLock(nssILockSlot); - if (slot->refLock == NULL) { - PORT_Free(slot); - return slot; - } - slot->sessionLock = PZ_NewLock(nssILockSession); - if (slot->sessionLock == NULL) { - PZ_DestroyLock(slot->refLock); - PORT_Free(slot); - return slot; - } - slot->freeListLock = PZ_NewLock(nssILockFreelist); - if (slot->freeListLock == NULL) { - PZ_DestroyLock(slot->sessionLock); - PZ_DestroyLock(slot->refLock); - PORT_Free(slot); - return slot; - } -#else - slot->sessionLock = NULL; - slot->refLock = NULL; - slot->freeListLock = NULL; -#endif - slot->freeSymKeysHead = NULL; - slot->keyCount = 0; - slot->maxKeyCount = 0; - slot->functionList = NULL; - slot->needTest = PR_TRUE; - slot->isPerm = PR_FALSE; - slot->isHW = PR_FALSE; - slot->isInternal = PR_FALSE; - slot->isThreadSafe = PR_FALSE; - slot->disabled = PR_FALSE; - slot->series = 0; - slot->wrapKey = 0; - slot->wrapMechanism = CKM_INVALID_MECHANISM; - slot->refKeys[0] = CK_INVALID_HANDLE; - slot->reason = PK11_DIS_NONE; - slot->readOnly = PR_TRUE; - slot->needLogin = PR_FALSE; - slot->hasRandom = PR_FALSE; - slot->defRWSession = PR_FALSE; - slot->protectedAuthPath = PR_FALSE; - slot->flags = 0; - slot->session = CK_INVALID_SESSION; - slot->slotID = 0; - slot->defaultFlags = 0; - slot->refCount = 1; - slot->askpw = 0; - slot->timeout = 0; - slot->mechanismList = NULL; - slot->mechanismCount = 0; - slot->cert_array = NULL; - slot->cert_count = 0; - slot->slot_name[0] = 0; - slot->token_name[0] = 0; - PORT_Memset(slot->serial,' ',sizeof(slot->serial)); - slot->module = NULL; - slot->authTransact = 0; - slot->authTime = LL_ZERO; - slot->minPassword = 0; - slot->maxPassword = 0; - slot->hasRootCerts = PR_FALSE; - slot->nssToken = NULL; - return slot; -} - -/* create a new reference to a slot so it doesn't go away */ -PK11SlotInfo * -PK11_ReferenceSlot(PK11SlotInfo *slot) -{ - PK11_USE_THREADS(PZ_Lock(slot->refLock);) - slot->refCount++; - PK11_USE_THREADS(PZ_Unlock(slot->refLock);) - return slot; -} - -/* Destroy all info on a slot we have built up */ -void -PK11_DestroySlot(PK11SlotInfo *slot) -{ - /* first free up all the sessions on this slot */ - if (slot->functionList) { - PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID); - } - - /* free up the cached keys and sessions */ - PK11_CleanKeyList(slot); - - if (slot->mechanismList) { - PORT_Free(slot->mechanismList); - } - - /* finally Tell our parent module that we've gone away so it can unload */ - if (slot->module) { - SECMOD_SlotDestroyModule(slot->module,PR_TRUE); - } -#ifdef PKCS11_USE_THREADS - if (slot->refLock) { - PZ_DestroyLock(slot->refLock); - slot->refLock = NULL; - } - if (slot->sessionLock) { - PZ_DestroyLock(slot->sessionLock); - slot->sessionLock = NULL; - } - if (slot->freeListLock) { - PZ_DestroyLock(slot->freeListLock); - slot->freeListLock = NULL; - } -#endif - - /* ok, well not quit finally... now we free the memory */ - PORT_Free(slot); -} - - -/* We're all done with the slot, free it */ -void -PK11_FreeSlot(PK11SlotInfo *slot) -{ - PRBool freeit = PR_FALSE; - - PK11_USE_THREADS(PZ_Lock(slot->refLock);) - if (slot->refCount-- == 1) freeit = PR_TRUE; - PK11_USE_THREADS(PZ_Unlock(slot->refLock);) - - if (freeit) PK11_DestroySlot(slot); -} - -void -PK11_EnterSlotMonitor(PK11SlotInfo *slot) { - PZ_Lock(slot->sessionLock); -} - -void -PK11_ExitSlotMonitor(PK11SlotInfo *slot) { - PZ_Unlock(slot->sessionLock); -} - -/*********************************************************** - * Functions to find specific slots. - ***********************************************************/ -PRBool -SECMOD_HasRootCerts(void) -{ - SECMODModuleList *mlp; - SECMODModuleList *modules = SECMOD_GetDefaultModuleList(); - SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); - int i; - PK11SlotInfo *slot = NULL; - PRBool found = PR_FALSE; - - /* work through all the slots */ - SECMOD_GetReadLock(moduleLock); - for(mlp = modules; mlp != NULL; mlp = mlp->next) { - for (i=0; i < mlp->module->slotCount; i++) { - PK11SlotInfo *tmpSlot = mlp->module->slots[i]; - if (PK11_IsPresent(tmpSlot)) { - if (tmpSlot->hasRootCerts) { - found = PR_TRUE; - break; - } - } - } - if (found) break; - } - SECMOD_ReleaseReadLock(moduleLock); - - return found; -} - -/*********************************************************** - * Functions to find specific slots. - ***********************************************************/ -PK11SlotInfo * -PK11_FindSlotByName(char *name) -{ - SECMODModuleList *mlp; - SECMODModuleList *modules = SECMOD_GetDefaultModuleList(); - SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); - int i; - PK11SlotInfo *slot = NULL; - - if ((name == NULL) || (*name == 0)) { - return PK11_GetInternalKeySlot(); - } - - /* work through all the slots */ - SECMOD_GetReadLock(moduleLock); - for(mlp = modules; mlp != NULL; mlp = mlp->next) { - for (i=0; i < mlp->module->slotCount; i++) { - PK11SlotInfo *tmpSlot = mlp->module->slots[i]; - if (PK11_IsPresent(tmpSlot)) { - if (PORT_Strcmp(tmpSlot->token_name,name) == 0) { - slot = PK11_ReferenceSlot(tmpSlot); - break; - } - } - } - if (slot != NULL) break; - } - SECMOD_ReleaseReadLock(moduleLock); - - if (slot == NULL) { - PORT_SetError(SEC_ERROR_NO_TOKEN); - } - - return slot; -} - - -PK11SlotInfo * -PK11_FindSlotBySerial(char *serial) -{ - SECMODModuleList *mlp; - SECMODModuleList *modules = SECMOD_GetDefaultModuleList(); - SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); - int i; - PK11SlotInfo *slot = NULL; - - /* work through all the slots */ - SECMOD_GetReadLock(moduleLock); - for(mlp = modules; mlp != NULL; mlp = mlp->next) { - for (i=0; i < mlp->module->slotCount; i++) { - PK11SlotInfo *tmpSlot = mlp->module->slots[i]; - if (PK11_IsPresent(tmpSlot)) { - if (PORT_Memcmp(tmpSlot->serial,serial, - sizeof(tmpSlot->serial)) == 0) { - slot = PK11_ReferenceSlot(tmpSlot); - break; - } - } - } - if (slot != NULL) break; - } - SECMOD_ReleaseReadLock(moduleLock); - - if (slot == NULL) { - PORT_SetError(SEC_ERROR_NO_TOKEN); - } - - return slot; -} - - - - -/*********************************************************** - * Password Utilities - ***********************************************************/ -/* - * Check the user's password. Log into the card if it's correct. - * succeed if the user is already logged in. - */ -SECStatus -pk11_CheckPassword(PK11SlotInfo *slot,char *pw) -{ - int len = PORT_Strlen(pw); - CK_RV crv; - SECStatus rv; - int64 currtime = PR_Now(); - - if (slot->protectedAuthPath) { - len = 0; - pw = NULL; - } - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER, - (unsigned char *)pw,len); - slot->lastLoginCheck = 0; - PK11_ExitSlotMonitor(slot); - switch (crv) { - /* if we're already logged in, we're good to go */ - case CKR_OK: - slot->authTransact = PK11_Global.transaction; - case CKR_USER_ALREADY_LOGGED_IN: - slot->authTime = currtime; - rv = SECSuccess; - break; - case CKR_PIN_INCORRECT: - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - rv = SECWouldBlock; /* everything else is ok, only the pin is bad */ - break; - default: - PORT_SetError(PK11_MapError(crv)); - rv = SECFailure; /* some failure we can't fix by retrying */ - } - return rv; -} - -/* - * Check the user's password. Logout before hand to make sure that - * we are really checking the password. - */ -SECStatus -PK11_CheckUserPassword(PK11SlotInfo *slot,char *pw) -{ - int len = PORT_Strlen(pw); - CK_RV crv; - SECStatus rv; - int64 currtime = PR_Now(); - - if (slot->protectedAuthPath) { - len = 0; - pw = NULL; - } - - /* force a logout */ - PK11_EnterSlotMonitor(slot); - PK11_GETTAB(slot)->C_Logout(slot->session); - - crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER, - (unsigned char *)pw,len); - slot->lastLoginCheck = 0; - PK11_ExitSlotMonitor(slot); - switch (crv) { - /* if we're already logged in, we're good to go */ - case CKR_OK: - slot->authTransact = PK11_Global.transaction; - slot->authTime = currtime; - rv = SECSuccess; - break; - case CKR_PIN_INCORRECT: - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - rv = SECWouldBlock; /* everything else is ok, only the pin is bad */ - break; - default: - PORT_SetError(PK11_MapError(crv)); - rv = SECFailure; /* some failure we can't fix by retrying */ - } - return rv; -} - -SECStatus -PK11_Logout(PK11SlotInfo *slot) -{ - CK_RV crv; - - /* force a logout */ - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_Logout(slot->session); - slot->lastLoginCheck = 0; - PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - return SECSuccess; -} - -/* - * transaction stuff is for when we test for the need to do every - * time auth to see if we already did it for this slot/transaction - */ -void PK11_StartAuthTransaction(void) -{ -PK11_Global.transaction++; -PK11_Global.inTransaction = PR_TRUE; -} - -void PK11_EndAuthTransaction(void) -{ -PK11_Global.transaction++; -PK11_Global.inTransaction = PR_FALSE; -} - -/* - * before we do a private key op, we check to see if we - * need to reauthenticate. - */ -void -PK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx) -{ - int askpw = slot->askpw; - PRBool NeedAuth = PR_FALSE; - - if (!slot->needLogin) return; - - if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) { - PK11SlotInfo *def_slot = PK11_GetInternalKeySlot(); - - if (def_slot) { - askpw = def_slot->askpw; - PK11_FreeSlot(def_slot); - } - } - - /* timeouts are handled by isLoggedIn */ - if (!PK11_IsLoggedIn(slot,wincx)) { - NeedAuth = PR_TRUE; - } else if (askpw == -1) { - if (!PK11_Global.inTransaction || - (PK11_Global.transaction != slot->authTransact)) { - PK11_EnterSlotMonitor(slot); - PK11_GETTAB(slot)->C_Logout(slot->session); - slot->lastLoginCheck = 0; - PK11_ExitSlotMonitor(slot); - NeedAuth = PR_TRUE; - } - } - if (NeedAuth) PK11_DoPassword(slot,PR_TRUE,wincx); -} - -void -PK11_SlotDBUpdate(PK11SlotInfo *slot) -{ - SECMOD_UpdateModule(slot->module); -} - -/* - * set new askpw and timeout values - */ -void -PK11_SetSlotPWValues(PK11SlotInfo *slot,int askpw, int timeout) -{ - slot->askpw = askpw; - slot->timeout = timeout; - slot->defaultFlags |= PK11_OWN_PW_DEFAULTS; - PK11_SlotDBUpdate(slot); -} - -/* - * Get the askpw and timeout values for this slot - */ -void -PK11_GetSlotPWValues(PK11SlotInfo *slot,int *askpw, int *timeout) -{ - *askpw = slot->askpw; - *timeout = slot->timeout; - - if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) { - PK11SlotInfo *def_slot = PK11_GetInternalKeySlot(); - - if (def_slot) { - *askpw = def_slot->askpw; - *timeout = def_slot->timeout; - PK11_FreeSlot(def_slot); - } - } -} - -/* - * make sure a slot is authenticated... - */ -SECStatus -PK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx) { - if (slot->needLogin && !PK11_IsLoggedIn(slot,wincx)) { - return PK11_DoPassword(slot,loadCerts,wincx); - } - return SECSuccess; -} - -/* - * notification stub. If we ever get interested in any events that - * the pkcs11 functions may pass back to use, we can catch them here... - * currently pdata is a slotinfo structure. - */ -CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event, - CK_VOID_PTR pdata) -{ - return CKR_OK; -} - - -/* - * grab a new RW session - * !!! has a side effect of grabbing the Monitor if either the slot's default - * session is RW or the slot is not thread safe. Monitor is release in function - * below - */ -CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot) -{ - CK_SESSION_HANDLE rwsession; - CK_RV crv; - - if (!slot->isThreadSafe || slot->defRWSession) PK11_EnterSlotMonitor(slot); - if (slot->defRWSession) return slot->session; - - crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID, - CKF_RW_SESSION|CKF_SERIAL_SESSION, - slot, pk11_notify,&rwsession); - if (crv == CKR_SESSION_COUNT) { - PK11_GETTAB(slot)->C_CloseSession(slot->session); - slot->session = CK_INVALID_SESSION; - crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID, - CKF_RW_SESSION|CKF_SERIAL_SESSION, - slot,pk11_notify,&rwsession); - } - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - if (slot->session == CK_INVALID_SESSION) { - PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION, - slot,pk11_notify,&slot->session); - } - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - return CK_INVALID_SESSION; - } - - return rwsession; -} - -PRBool -PK11_RWSessionHasLock(PK11SlotInfo *slot,CK_SESSION_HANDLE session_handle) { - return (PRBool)(!slot->isThreadSafe || slot->defRWSession); -} - -/* - * close the rwsession and restore our readonly session - * !!! has a side effect of releasing the Monitor if either the slot's default - * session is RW or the slot is not thread safe. - */ -void -PK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession) -{ - if (slot->defRWSession) { - PK11_ExitSlotMonitor(slot); - return; - } - PK11_GETTAB(slot)->C_CloseSession(rwsession); - if (slot->session == CK_INVALID_SESSION) { - PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION, - slot,pk11_notify,&slot->session); - } - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); -} - -/* - * NOTE: this assumes that we are logged out of the card before hand - */ -SECStatus -PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw) -{ - CK_SESSION_HANDLE rwsession; - CK_RV crv; - SECStatus rv = SECFailure; - int len = PORT_Strlen(ssopw); - - /* get a rwsession */ - rwsession = PK11_GetRWSession(slot); - if (rwsession == CK_INVALID_SESSION) return rv; - - if (slot->protectedAuthPath) { - len = 0; - ssopw = NULL; - } - - /* check the password */ - crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO, - (unsigned char *)ssopw,len); - slot->lastLoginCheck = 0; - switch (crv) { - /* if we're already logged in, we're good to go */ - case CKR_OK: - rv = SECSuccess; - break; - case CKR_PIN_INCORRECT: - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - rv = SECWouldBlock; /* everything else is ok, only the pin is bad */ - break; - default: - PORT_SetError(PK11_MapError(crv)); - rv = SECFailure; /* some failure we can't fix by retrying */ - } - PK11_GETTAB(slot)->C_Logout(rwsession); - slot->lastLoginCheck = 0; - - /* release rwsession */ - PK11_RestoreROSession(slot,rwsession); - return rv; -} - -/* - * make sure the password conforms to your token's requirements. - */ -SECStatus -PK11_VerifyPW(PK11SlotInfo *slot,char *pw) -{ - int len = PORT_Strlen(pw); - - if ((slot->minPassword > len) || (slot->maxPassword < len)) { - PORT_SetError(SEC_ERROR_BAD_DATA); - return SECFailure; - } - return SECSuccess; -} - -/* - * initialize a user PIN Value - */ -SECStatus -PK11_InitPin(PK11SlotInfo *slot,char *ssopw, char *userpw) -{ - CK_SESSION_HANDLE rwsession = CK_INVALID_SESSION; - CK_RV crv; - SECStatus rv = SECFailure; - int len; - int ssolen; - - if (userpw == NULL) userpw = ""; - if (ssopw == NULL) ssopw = ""; - - len = PORT_Strlen(userpw); - ssolen = PORT_Strlen(ssopw); - - /* get a rwsession */ - rwsession = PK11_GetRWSession(slot); - if (rwsession == CK_INVALID_SESSION) goto done; - - if (slot->protectedAuthPath) { - len = 0; - ssolen = 0; - ssopw = NULL; - userpw = NULL; - } - - /* check the password */ - crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO, - (unsigned char *)ssopw,ssolen); - slot->lastLoginCheck = 0; - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - goto done; - } - - crv = PK11_GETTAB(slot)->C_InitPIN(rwsession,(unsigned char *)userpw,len); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - } else { - rv = SECSuccess; - } - -done: - PK11_GETTAB(slot)->C_Logout(rwsession); - slot->lastLoginCheck = 0; - PK11_RestoreROSession(slot,rwsession); - if (rv == SECSuccess) { - /* update our view of the world */ - PK11_InitToken(slot,PR_TRUE); - PK11_EnterSlotMonitor(slot); - PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER, - (unsigned char *)userpw,len); - slot->lastLoginCheck = 0; - PK11_ExitSlotMonitor(slot); - } - return rv; -} - -/* - * Change an existing user password - */ -SECStatus -PK11_ChangePW(PK11SlotInfo *slot,char *oldpw, char *newpw) -{ - CK_RV crv; - SECStatus rv = SECFailure; - int newLen; - int oldLen; - CK_SESSION_HANDLE rwsession; - - if (newpw == NULL) newpw = ""; - if (oldpw == NULL) oldpw = ""; - newLen = PORT_Strlen(newpw); - oldLen = PORT_Strlen(oldpw); - - /* get a rwsession */ - rwsession = PK11_GetRWSession(slot); - - crv = PK11_GETTAB(slot)->C_SetPIN(rwsession, - (unsigned char *)oldpw,oldLen,(unsigned char *)newpw,newLen); - if (crv == CKR_OK) { - rv = SECSuccess; - } else { - PORT_SetError(PK11_MapError(crv)); - } - - PK11_RestoreROSession(slot,rwsession); - - /* update our view of the world */ - PK11_InitToken(slot,PR_TRUE); - return rv; -} - -static char * -pk11_GetPassword(PK11SlotInfo *slot, PRBool retry, void * wincx) -{ - if (PK11_Global.getPass == NULL) return NULL; - return (*PK11_Global.getPass)(slot, retry, wincx); -} - -void -PK11_SetPasswordFunc(PK11PasswordFunc func) -{ - PK11_Global.getPass = func; -} - -void -PK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func) -{ - PK11_Global.verifyPass = func; -} - -void -PK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func) -{ - PK11_Global.isLoggedIn = func; -} - - -/* - * authenticate to a slot. This loops until we can't recover, the user - * gives up, or we succeed. If we're already logged in and this function - * is called we will still prompt for a password, but we will probably - * succeed no matter what the password was (depending on the implementation - * of the PKCS 11 module. - */ -SECStatus -PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx) -{ - SECStatus rv = SECFailure; - char * password; - PRBool attempt = PR_FALSE; - - if (PK11_NeedUserInit(slot)) { - PORT_SetError(SEC_ERROR_IO); - return SECFailure; - } - - - /* - * Central server type applications which control access to multiple - * slave applications to single crypto devices need to virtuallize the - * login state. This is done by a callback out of PK11_IsLoggedIn and - * here. If we are actually logged in, then we got here because the - * higher level code told us that the particular client application may - * still need to be logged in. If that is the case, we simply tell the - * server code that it should now verify the clients password and tell us - * the results. - */ - if (PK11_IsLoggedIn(slot,NULL) && - (PK11_Global.verifyPass != NULL)) { - if (!PK11_Global.verifyPass(slot,wincx)) { - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - return SECFailure; - } - return SECSuccess; - } - - /* get the password. This can drop out of the while loop - * for the following reasons: - * (1) the user refused to enter a password. - * (return error to caller) - * (2) the token user password is disabled [usually due to - * too many failed authentication attempts]. - * (return error to caller) - * (3) the password was successful. - */ - while ((password = pk11_GetPassword(slot, attempt, wincx)) != NULL) { - attempt = PR_TRUE; - rv = pk11_CheckPassword(slot,password); - PORT_Memset(password, 0, PORT_Strlen(password)); - PORT_Free(password); - if (rv != SECWouldBlock) break; - } - if (rv == SECSuccess) { - rv = pk11_CheckVerifyTest(slot); - if (!PK11_IsFriendly(slot)) { - nssTrustDomain_UpdateCachedTokenCerts(slot->nssToken->trustDomain, - slot->nssToken); - } - } else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD); - return rv; -} - -void PK11_LogoutAll(void) -{ - SECMODListLock *lock = SECMOD_GetDefaultModuleListLock(); - SECMODModuleList *modList = SECMOD_GetDefaultModuleList(); - SECMODModuleList *mlp = NULL; - int i; - - SECMOD_GetReadLock(lock); - /* find the number of entries */ - for (mlp = modList; mlp != NULL; mlp = mlp->next) { - for (i=0; i < mlp->module->slotCount; i++) { - PK11_Logout(mlp->module->slots[i]); - } - } - - SECMOD_ReleaseReadLock(lock); -} - -int -PK11_GetMinimumPwdLength(PK11SlotInfo *slot) -{ - return ((int)slot->minPassword); -} - -/************************************************************ - * Manage the built-In Slot Lists - ************************************************************/ - -/* Init the static built int slot list (should actually integrate - * with PK11_NewSlotList */ -static void -pk11_initSlotList(PK11SlotList *list) -{ -#ifdef PKCS11_USE_THREADS - list->lock = PZ_NewLock(nssILockList); -#else - list->lock = NULL; -#endif - list->head = NULL; -} - -static void -pk11_freeSlotList(PK11SlotList *list) -{ - PK11SlotListElement *le, *next ; - if (list == NULL) return; - - for (le = list->head ; le; le = next) { - next = le->next; - pk11_FreeListElement(list,le); - } -#ifdef PK11_USE_THREADS - if (list->lock) { - PZ_DestroyLock((PZLock *)(list->lock)); - } -#endif - list->lock = NULL; - list->head = NULL; -} - -/* initialize the system slotlists */ -SECStatus -PK11_InitSlotLists(void) -{ - pk11_initSlotList(&pk11_aesSlotList); - pk11_initSlotList(&pk11_desSlotList); - pk11_initSlotList(&pk11_rc4SlotList); - pk11_initSlotList(&pk11_rc2SlotList); - pk11_initSlotList(&pk11_rc5SlotList); - pk11_initSlotList(&pk11_md5SlotList); - pk11_initSlotList(&pk11_md2SlotList); - pk11_initSlotList(&pk11_sha1SlotList); - pk11_initSlotList(&pk11_rsaSlotList); - pk11_initSlotList(&pk11_dsaSlotList); - pk11_initSlotList(&pk11_dhSlotList); - pk11_initSlotList(&pk11_ideaSlotList); - pk11_initSlotList(&pk11_sslSlotList); - pk11_initSlotList(&pk11_tlsSlotList); - pk11_initSlotList(&pk11_randomSlotList); - return SECSuccess; -} - -void -PK11_DestroySlotLists(void) -{ - pk11_freeSlotList(&pk11_aesSlotList); - pk11_freeSlotList(&pk11_desSlotList); - pk11_freeSlotList(&pk11_rc4SlotList); - pk11_freeSlotList(&pk11_rc2SlotList); - pk11_freeSlotList(&pk11_rc5SlotList); - pk11_freeSlotList(&pk11_md5SlotList); - pk11_freeSlotList(&pk11_md2SlotList); - pk11_freeSlotList(&pk11_sha1SlotList); - pk11_freeSlotList(&pk11_rsaSlotList); - pk11_freeSlotList(&pk11_dsaSlotList); - pk11_freeSlotList(&pk11_dhSlotList); - pk11_freeSlotList(&pk11_ideaSlotList); - pk11_freeSlotList(&pk11_sslSlotList); - pk11_freeSlotList(&pk11_tlsSlotList); - pk11_freeSlotList(&pk11_randomSlotList); - return; -} - -/* return a system slot list based on mechanism */ -PK11SlotList * -PK11_GetSlotList(CK_MECHANISM_TYPE type) -{ -/* XXX a workaround for Bugzilla bug #55267 */ -#if defined(HPUX) && defined(__LP64__) - if (CKM_INVALID_MECHANISM == type) - return NULL; -#endif - switch (type) { - case CKM_AES_CBC: - case CKM_AES_ECB: - return &pk11_aesSlotList; - case CKM_DES_CBC: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_DES3_CBC: - return &pk11_desSlotList; - case CKM_RC4: - return &pk11_rc4SlotList; - case CKM_RC5_CBC: - return &pk11_rc5SlotList; - case CKM_SHA_1: - return &pk11_sha1SlotList; - case CKM_MD5: - return &pk11_md5SlotList; - case CKM_MD2: - return &pk11_md2SlotList; - case CKM_RC2_ECB: - case CKM_RC2_CBC: - return &pk11_rc2SlotList; - case CKM_RSA_PKCS: - case CKM_RSA_PKCS_KEY_PAIR_GEN: - case CKM_RSA_X_509: - return &pk11_rsaSlotList; - case CKM_DSA: - return &pk11_dsaSlotList; - case CKM_DH_PKCS_KEY_PAIR_GEN: - case CKM_DH_PKCS_DERIVE: - return &pk11_dhSlotList; - case CKM_SSL3_PRE_MASTER_KEY_GEN: - case CKM_SSL3_MASTER_KEY_DERIVE: - case CKM_SSL3_SHA1_MAC: - case CKM_SSL3_MD5_MAC: - return &pk11_sslSlotList; - case CKM_TLS_MASTER_KEY_DERIVE: - case CKM_TLS_KEY_AND_MAC_DERIVE: - return &pk11_tlsSlotList; - case CKM_IDEA_CBC: - case CKM_IDEA_ECB: - return &pk11_ideaSlotList; - case CKM_FAKE_RANDOM: - return &pk11_randomSlotList; - } - return NULL; -} - -/* - * load the static SlotInfo structures used to select a PKCS11 slot. - * preSlotInfo has a list of all the default flags for the slots on this - * module. - */ -void -PK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count) -{ - int i; - - for (i=0; i < count; i++) { - if (psi[i].slotID == slot->slotID) - break; - } - - if (i == count) return; - - slot->defaultFlags = psi[i].defaultFlags; - slot->askpw = psi[i].askpw; - slot->timeout = psi[i].timeout; - slot->hasRootCerts = psi[i].hasRootCerts; - - /* if the slot is already disabled, don't load them into the - * default slot lists. We get here so we can save the default - * list value. */ - if (slot->disabled) return; - - /* if the user has disabled us, don't load us in */ - if (slot->defaultFlags & PK11_DISABLE_FLAG) { - slot->disabled = PR_TRUE; - slot->reason = PK11_DIS_USER_SELECTED; - /* free up sessions and things?? */ - return; - } - - for (i=0; i < sizeof(PK11_DefaultArray)/sizeof(PK11_DefaultArray[0]); - i++) { - if (slot->defaultFlags & PK11_DefaultArray[i].flag) { - CK_MECHANISM_TYPE mechanism = PK11_DefaultArray[i].mechanism; - PK11SlotList *slotList = PK11_GetSlotList(mechanism); - - if (slotList) PK11_AddSlotToList(slotList,slot); - } - } - - return; -} - - -/* - * update a slot to its new attribute according to the slot list - * returns: SECSuccess if nothing to do or add/delete is successful - */ -SECStatus -PK11_UpdateSlotAttribute(PK11SlotInfo *slot, PK11DefaultArrayEntry *entry, - PRBool add) - /* add: PR_TRUE if want to turn on */ -{ - SECStatus result = SECSuccess; - PK11SlotList *slotList = PK11_GetSlotList(entry->mechanism); - - if (add) { /* trying to turn on a mechanism */ - - /* turn on the default flag in the slot */ - slot->defaultFlags |= entry->flag; - - /* add this slot to the list */ - if (slotList!=NULL) - result = PK11_AddSlotToList(slotList, slot); - - } else { /* trying to turn off */ - - /* turn OFF the flag in the slot */ - slot->defaultFlags &= ~entry->flag; - - if (slotList) { - /* find the element in the list & delete it */ - PK11SlotListElement *le = PK11_FindSlotElement(slotList, slot); - - /* remove the slot from the list */ - if (le) - result = PK11_DeleteSlotFromList(slotList, le); - } - } - return result; -} - -/* - * clear a slot off of all of it's default list - */ -void -PK11_ClearSlotList(PK11SlotInfo *slot) -{ - int i; - - if (slot->disabled) return; - if (slot->defaultFlags == 0) return; - - for (i=0; i < sizeof(PK11_DefaultArray)/sizeof(PK11_DefaultArray[0]); - i++) { - if (slot->defaultFlags & PK11_DefaultArray[i].flag) { - CK_MECHANISM_TYPE mechanism = PK11_DefaultArray[i].mechanism; - PK11SlotList *slotList = PK11_GetSlotList(mechanism); - PK11SlotListElement *le = NULL; - - if (slotList) le = PK11_FindSlotElement(slotList,slot); - - if (le) { - PK11_DeleteSlotFromList(slotList,le); - pk11_FreeListElement(slotList,le); - } - } - } -} - - -/****************************************************************** - * Slot initialization - ******************************************************************/ -/* - * turn a PKCS11 Static Label into a string - */ -char * -PK11_MakeString(PRArenaPool *arena,char *space, - char *staticString,int stringLen) -{ - int i; - char *newString; - for(i=(stringLen-1); i >= 0; i--) { - if (staticString[i] != ' ') break; - } - /* move i to point to the last space */ - i++; - if (arena) { - newString = (char*)PORT_ArenaAlloc(arena,i+1 /* space for NULL */); - } else if (space) { - newString = space; - } else { - newString = (char*)PORT_Alloc(i+1 /* space for NULL */); - } - if (newString == NULL) return NULL; - - if (i) PORT_Memcpy(newString,staticString, i); - newString[i] = 0; - - return newString; -} - -/* - * verify that slot implements Mechanism mech properly by checking against - * our internal implementation - */ -PRBool -PK11_VerifyMechanism(PK11SlotInfo *slot,PK11SlotInfo *intern, - CK_MECHANISM_TYPE mech, SECItem *data, SECItem *iv) -{ - PK11Context *test = NULL, *reference = NULL; - PK11SymKey *symKey = NULL, *testKey = NULL; - SECItem *param = NULL; - unsigned char encTest[8]; - unsigned char encRef[8]; - int outLenTest,outLenRef; - int key_size = 0; - PRBool verify = PR_FALSE; - SECStatus rv; - - if ((mech == CKM_RC2_CBC) || (mech == CKM_RC2_ECB) || (mech == CKM_RC4)) { - key_size = 16; - } - - /* initialize the mechanism parameter */ - param = PK11_ParamFromIV(mech,iv); - if (param == NULL) goto loser; - - /* load the keys and contexts */ - symKey = PK11_KeyGen(intern,mech,NULL, key_size, NULL); - if (symKey == NULL) goto loser; - - reference = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symKey, param); - if (reference == NULL) goto loser; - - testKey = pk11_CopyToSlot(slot, mech, CKA_ENCRYPT, symKey); - if (testKey == NULL) goto loser; - - test = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, testKey, param); - if (test == NULL) goto loser; - SECITEM_FreeItem(param,PR_TRUE); param = NULL; - - /* encrypt the test data */ - rv = PK11_CipherOp(test,encTest,&outLenTest,sizeof(encTest), - data->data,data->len); - if (rv != SECSuccess) goto loser; - rv = PK11_CipherOp(reference,encRef,&outLenRef,sizeof(encRef), - data->data,data->len); - if (rv != SECSuccess) goto loser; - - PK11_DestroyContext(reference,PR_TRUE); reference = NULL; - PK11_DestroyContext(test,PR_TRUE); test = NULL; - - if (outLenTest != outLenRef) goto loser; - if (PORT_Memcmp(encTest, encRef, outLenTest) != 0) goto loser; - - verify = PR_TRUE; - -loser: - if (test) PK11_DestroyContext(test,PR_TRUE); - if (symKey) PK11_FreeSymKey(symKey); - if (testKey) PK11_FreeSymKey(testKey); - if (reference) PK11_DestroyContext(reference,PR_TRUE); - if (param) SECITEM_FreeItem(param,PR_TRUE); - - return verify; -} - -/* - * this code verifies that the advertised mechanisms are what they - * seem to be. - */ -#define MAX_MECH_LIST_SIZE 30 /* we only know of about 30 odd mechanisms */ -PRBool -PK11_VerifySlotMechanisms(PK11SlotInfo *slot) -{ - CK_MECHANISM_TYPE mechListArray[MAX_MECH_LIST_SIZE]; - CK_MECHANISM_TYPE *mechList = mechListArray; - static SECItem data; - static SECItem iv; - static unsigned char dataV[8]; - static unsigned char ivV[8]; - static PRBool generated = PR_FALSE; - CK_ULONG count; - int i; - CK_RV crv; - - PRBool alloced = PR_FALSE; - PK11SlotInfo *intern = PK11_GetInternalSlot(); - - /* if we couldn't initialize an internal module, - * we can't check external ones */ - if (intern == NULL) return PR_FALSE; - - /* first get the count of mechanisms */ - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID,NULL,&count); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PK11_FreeSlot(intern); - return PR_FALSE; - } - - - /* don't blow up just because the card supports more mechanisms than - * we know about, just alloc space for them */ - if (count > MAX_MECH_LIST_SIZE) { - mechList = (CK_MECHANISM_TYPE *) - PORT_Alloc(count *sizeof(CK_MECHANISM_TYPE)); - alloced = PR_TRUE; - if (mechList == NULL) { - PK11_FreeSlot(intern); - return PR_FALSE; - } - } - /* get the list */ - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv =PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID, mechList, &count); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - if (alloced) PORT_Free(mechList); - PK11_FreeSlot(intern); - return PR_FALSE; - } - - if (!generated) { - data.data = dataV; - data.len = sizeof(dataV); - iv.data = ivV; - iv.len = sizeof(ivV); - /* ok, this is a cheat, we know our internal random number generater - * is thread safe */ - PK11_GETTAB(intern)->C_GenerateRandom(intern->session, - data.data, data.len); - PK11_GETTAB(intern)->C_GenerateRandom(intern->session, - iv.data, iv.len); - } - for (i=0; i < (int) count; i++) { - switch (mechList[i]) { - case CKM_DES_CBC: - case CKM_DES_ECB: - case CKM_RC4: - case CKM_RC2_CBC: - case CKM_RC2_ECB: - if (!PK11_VerifyMechanism(slot,intern,mechList[i],&data,&iv)){ - if (alloced) PORT_Free(mechList); - PK11_FreeSlot(intern); - return PR_FALSE; - } - } - } - if (alloced) PORT_Free(mechList); - PK11_FreeSlot(intern); - return PR_TRUE; -} - -/* - * See if we need to run the verify test, do so if necessary. If we fail, - * disable the slot. - */ -SECStatus -pk11_CheckVerifyTest(PK11SlotInfo *slot) -{ - PK11_EnterSlotMonitor(slot); - if (slot->needTest) { - slot->needTest = PR_FALSE; - PK11_ExitSlotMonitor(slot); - if (!PK11_VerifySlotMechanisms(slot)) { - (void)PK11_GETTAB(slot)->C_CloseSession(slot->session); - slot->session = CK_INVALID_SESSION; - PK11_ClearSlotList(slot); - slot->disabled = PR_TRUE; - slot->reason = PK11_DIS_TOKEN_VERIFY_FAILED; - slot->needTest = PR_TRUE; - PORT_SetError(SEC_ERROR_IO); - return SECFailure; - } - } else { - PK11_ExitSlotMonitor(slot); - } - return SECSuccess; -} - -/* - * Reads in the slots mechanism list for later use - */ -SECStatus -PK11_ReadMechanismList(PK11SlotInfo *slot) -{ - CK_ULONG count; - CK_RV crv; - - if (slot->mechanismList) { - PORT_Free(slot->mechanismList); - slot->mechanismList = NULL; - } - slot->mechanismCount = 0; - - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID,NULL,&count); - if (crv != CKR_OK) { - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - - slot->mechanismList = (CK_MECHANISM_TYPE *) - PORT_Alloc(count *sizeof(CK_MECHANISM_TYPE)); - if (slot->mechanismList == NULL) { - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - return SECFailure; - } - crv = PK11_GETTAB(slot)->C_GetMechanismList(slot->slotID, - slot->mechanismList, &count); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_Free(slot->mechanismList); - slot->mechanismList = NULL; - PORT_SetError(PK11_MapError(crv)); - return SECSuccess; - } - slot->mechanismCount = count; - return SECSuccess; -} - -/* - * initialize a new token - * unlike initialize slot, this can be called multiple times in the lifetime - * of NSS. It reads the information associated with a card or token, - * that is not going to change unless the card or token changes. - */ -SECStatus -PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) -{ - CK_TOKEN_INFO tokenInfo; - CK_RV crv; - char *tmp; - SECStatus rv; - - /* set the slot flags to the current token values */ - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID,&tokenInfo); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - - /* set the slot flags to the current token values */ - slot->series++; /* allow other objects to detect that the - * slot is different */ - slot->flags = tokenInfo.flags; - slot->needLogin = ((tokenInfo.flags & CKF_LOGIN_REQUIRED) ? - PR_TRUE : PR_FALSE); - slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ? - PR_TRUE : PR_FALSE); - slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); - slot->protectedAuthPath = - ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) - ? PR_TRUE : PR_FALSE); - slot->lastLoginCheck = 0; - slot->lastState = 0; - /* on some platforms Active Card incorrectly sets the - * CKF_PROTECTED_AUTHENTICATION_PATH bit when it doesn't mean to. */ - if (slot->isActiveCard) { - slot->protectedAuthPath = PR_FALSE; - } - tmp = PK11_MakeString(NULL,slot->token_name, - (char *)tokenInfo.label, sizeof(tokenInfo.label)); - slot->minPassword = tokenInfo.ulMinPinLen; - slot->maxPassword = tokenInfo.ulMaxPinLen; - PORT_Memcpy(slot->serial,tokenInfo.serialNumber,sizeof(slot->serial)); - - nssToken_UpdateName(slot->nssToken); - - slot->defRWSession = (PRBool)((!slot->readOnly) && - (tokenInfo.ulMaxSessionCount == 1)); - rv = PK11_ReadMechanismList(slot); - if (rv != SECSuccess) return rv; - - slot->hasRSAInfo = PR_FALSE; - slot->RSAInfoFlags = 0; - - /* initialize the maxKeyCount value */ - if (tokenInfo.ulMaxSessionCount == 0) { - slot->maxKeyCount = 800; /* should be #define or a config param */ - } else if (tokenInfo.ulMaxSessionCount < 20) { - /* don't have enough sessions to keep that many keys around */ - slot->maxKeyCount = 0; - } else { - slot->maxKeyCount = tokenInfo.ulMaxSessionCount/2; - } - - /* Make sure our session handle is valid */ - if (slot->session == CK_INVALID_SESSION) { - /* we know we don't have a valid session, go get one */ - CK_SESSION_HANDLE session; - - /* session should be Readonly, serial */ - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID, - (slot->defRWSession ? CKF_RW_SESSION : 0) | CKF_SERIAL_SESSION, - slot,pk11_notify,&session); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - slot->session = session; - } else { - /* The session we have may be defunct (the token associated with it) - * has been removed */ - CK_SESSION_INFO sessionInfo; - - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session,&sessionInfo); - if (crv == CKR_DEVICE_ERROR) { - PK11_GETTAB(slot)->C_CloseSession(slot->session); - crv = CKR_SESSION_CLOSED; - } - if ((crv==CKR_SESSION_CLOSED) || (crv==CKR_SESSION_HANDLE_INVALID)) { - crv =PK11_GETTAB(slot)->C_OpenSession(slot->slotID, - (slot->defRWSession ? CKF_RW_SESSION : 0) | CKF_SERIAL_SESSION, - slot,pk11_notify,&slot->session); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - slot->session = CK_INVALID_SESSION; - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - return SECFailure; - } - } - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - } - - nssToken_Refresh(slot->nssToken); - - if (!(slot->needLogin)) { - return pk11_CheckVerifyTest(slot); - } - - - if (!(slot->isInternal) && (slot->hasRandom)) { - /* if this slot has a random number generater, use it to add entropy - * to the internal slot. */ - PK11SlotInfo *int_slot = PK11_GetInternalSlot(); - - if (int_slot) { - unsigned char random_bytes[32]; - - /* if this slot can issue random numbers, get some entropy from - * that random number generater and give it to our internal token. - */ - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GenerateRandom - (slot->session,random_bytes, sizeof(random_bytes)); - PK11_ExitSlotMonitor(slot); - if (crv == CKR_OK) { - PK11_EnterSlotMonitor(int_slot); - PK11_GETTAB(int_slot)->C_SeedRandom(int_slot->session, - random_bytes, sizeof(random_bytes)); - PK11_ExitSlotMonitor(int_slot); - } - - /* Now return the favor and send entropy to the token's random - * number generater */ - PK11_EnterSlotMonitor(int_slot); - crv = PK11_GETTAB(int_slot)->C_GenerateRandom(int_slot->session, - random_bytes, sizeof(random_bytes)); - PK11_ExitSlotMonitor(int_slot); - if (crv == CKR_OK) { - PK11_EnterSlotMonitor(slot); - PK11_GETTAB(slot)->C_SeedRandom(slot->session, - random_bytes, sizeof(random_bytes)); - PK11_ExitSlotMonitor(slot); - } - PK11_FreeSlot(int_slot); - } - } - - - return SECSuccess; -} - -static PRBool -pk11_isRootSlot(PK11SlotInfo *slot) -{ - CK_ATTRIBUTE findTemp[1]; - CK_ATTRIBUTE *attrs; - CK_OBJECT_CLASS oclass = CKO_NETSCAPE_BUILTIN_ROOT_LIST; - int tsize; - CK_OBJECT_HANDLE handle; - - attrs = findTemp; - PK11_SETATTRS(attrs, CKA_CLASS, &oclass, sizeof(oclass)); attrs++; - tsize = attrs - findTemp; - PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE)); - - handle = pk11_FindObjectByTemplate(slot,findTemp,tsize); - if (handle == CK_INVALID_HANDLE) { - return PR_FALSE; - } - return PR_TRUE; -} - -/* - * Initialize the slot : - * This initialization code is called on each slot a module supports when - * it is loaded. It does the bringup initialization. The difference between - * this and InitToken is Init slot does those one time initialization stuff, - * usually associated with the reader, while InitToken may get called multiple - * times as tokens are removed and re-inserted. - */ -void -PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot) -{ - SECStatus rv; - char *tmp; - CK_SLOT_INFO slotInfo; - - slot->functionList = mod->functionList; - slot->isInternal = mod->internal; - slot->slotID = slotID; - slot->isThreadSafe = mod->isThreadSafe; - slot->hasRSAInfo = PR_FALSE; - - if (PK11_GETTAB(slot)->C_GetSlotInfo(slotID,&slotInfo) != CKR_OK) { - slot->disabled = PR_TRUE; - slot->reason = PK11_DIS_COULD_NOT_INIT_TOKEN; - return; - } - - /* test to make sure claimed mechanism work */ - slot->needTest = mod->internal ? PR_FALSE : PR_TRUE; - slot->module = mod; /* NOTE: we don't make a reference here because - * modules have references to their slots. This - * works because modules keep implicit references - * from their slots, and won't unload and disappear - * until all their slots have been freed */ - tmp = PK11_MakeString(NULL,slot->slot_name, - (char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription)); - slot->isHW = (PRBool)((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT); -#define ACTIVE_CARD "ActivCard SA" - slot->isActiveCard = (PRBool)(PORT_Strncmp((char *)slotInfo.manufacturerID, - ACTIVE_CARD, sizeof(ACTIVE_CARD)-1) == 0); - if ((slotInfo.flags & CKF_REMOVABLE_DEVICE) == 0) { - slot->isPerm = PR_TRUE; - /* permanment slots must have the token present always */ - if ((slotInfo.flags & CKF_TOKEN_PRESENT) == 0) { - slot->disabled = PR_TRUE; - slot->reason = PK11_DIS_TOKEN_NOT_PRESENT; - return; /* nothing else to do */ - } - } - /* if the token is present, initialize it */ - if ((slotInfo.flags & CKF_TOKEN_PRESENT) != 0) { - rv = PK11_InitToken(slot,PR_TRUE); - /* the only hard failures are on permanent devices, or function - * verify failures... function verify failures are already handled - * by tokenInit */ - if ((rv != SECSuccess) && (slot->isPerm) && (!slot->disabled)) { - slot->disabled = PR_TRUE; - slot->reason = PK11_DIS_COULD_NOT_INIT_TOKEN; - } - } - if (pk11_isRootSlot(slot)) { - if (!slot->hasRootCerts) { - slot->module->trustOrder = 100; - } - slot->hasRootCerts= PR_TRUE; - } -} - - - -/********************************************************************* - * Slot mapping utility functions. - *********************************************************************/ - -/* - * determine if the token is present. If the token is present, make sure - * we have a valid session handle. Also set the value of needLogin - * appropriately. - */ -static PRBool -pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts) -{ - CK_SLOT_INFO slotInfo; - CK_SESSION_INFO sessionInfo; - CK_RV crv; - - /* disabled slots are never present */ - if (slot->disabled) { - return PR_FALSE; - } - - /* permanent slots are always present */ - if (slot->isPerm && (slot->session != CK_INVALID_SESSION)) { - return PR_TRUE; - } - - if (slot->nssToken) { - return nssToken_IsPresent(slot->nssToken); - } - - /* removable slots have a flag that says they are present */ - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - if (PK11_GETTAB(slot)->C_GetSlotInfo(slot->slotID,&slotInfo) != CKR_OK) { - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - return PR_FALSE; - } - if ((slotInfo.flags & CKF_TOKEN_PRESENT) == 0) { - /* if the slot is no longer present, close the session */ - if (slot->session != CK_INVALID_SESSION) { - PK11_GETTAB(slot)->C_CloseSession(slot->session); - slot->session = CK_INVALID_SESSION; - /* force certs to be freed */ - } - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - return PR_FALSE; - } - - /* use the session Info to determine if the card has been removed and then - * re-inserted */ - if (slot->session != CK_INVALID_SESSION) { - crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session, &sessionInfo); - if (crv != CKR_OK) { - PK11_GETTAB(slot)->C_CloseSession(slot->session); - slot->session = CK_INVALID_SESSION; - } - } - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - - /* card has not been removed, current token info is correct */ - if (slot->session != CK_INVALID_SESSION) return PR_TRUE; - - /* initialize the token info state */ - if (PK11_InitToken(slot,loadCerts) != SECSuccess) { - return PR_FALSE; - } - - return PR_TRUE; -} - -/* - * old version of the routine - */ -PRBool -PK11_IsPresent(PK11SlotInfo *slot) { - return pk11_IsPresentCertLoad(slot,PR_TRUE); -} - -/* is the slot disabled? */ -PRBool -PK11_IsDisabled(PK11SlotInfo *slot) -{ - return slot->disabled; -} - -/* and why? */ -PK11DisableReasons -PK11_GetDisabledReason(PK11SlotInfo *slot) -{ - return slot->reason; -} - -/* returns PR_TRUE if successfully disable the slot */ -/* returns PR_FALSE otherwise */ -PRBool PK11_UserDisableSlot(PK11SlotInfo *slot) { - - slot->defaultFlags |= PK11_DISABLE_FLAG; - slot->disabled = PR_TRUE; - slot->reason = PK11_DIS_USER_SELECTED; - - return PR_TRUE; -} - -PRBool PK11_UserEnableSlot(PK11SlotInfo *slot) { - - slot->defaultFlags &= ~PK11_DISABLE_FLAG; - slot->disabled = PR_FALSE; - slot->reason = PK11_DIS_NONE; - return PR_TRUE; -} - -PRBool PK11_HasRootCerts(PK11SlotInfo *slot) { - return slot->hasRootCerts; -} - -/* Get the module this slot is attatched to */ -SECMODModule * -PK11_GetModule(PK11SlotInfo *slot) -{ - return slot->module; -} - -/* return the default flags of a slot */ -unsigned long -PK11_GetDefaultFlags(PK11SlotInfo *slot) -{ - return slot->defaultFlags; -} - -/* Does this slot have a protected pin path? */ -PRBool -PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot) -{ - return slot->protectedAuthPath; -} - -/* - * we can initialize the password if 1) The toke is not inited - * (need login == true and see need UserInit) or 2) the token has - * a NULL password. (slot->needLogin = false & need user Init = false). - */ -PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot) -{ - if (slot->needLogin && PK11_NeedUserInit(slot)) { - return PR_TRUE; - } - if (!slot->needLogin && !PK11_NeedUserInit(slot)) { - return PR_TRUE; - } - return PR_FALSE; -} - -PRBool PK11_NeedPWInit() -{ - PK11SlotInfo *slot = PK11_GetInternalKeySlot(); - PRBool ret = PK11_NeedPWInitForSlot(slot); - - PK11_FreeSlot(slot); - return ret; -} - -/* - * The following wrapper functions allow us to export an opaque slot - * function to the rest of libsec and the world... */ -PRBool -PK11_IsReadOnly(PK11SlotInfo *slot) -{ - return slot->readOnly; -} - -PRBool -PK11_IsHW(PK11SlotInfo *slot) -{ - return slot->isHW; -} - -PRBool -PK11_IsInternal(PK11SlotInfo *slot) -{ - return slot->isInternal; -} - -PRBool -PK11_NeedLogin(PK11SlotInfo *slot) -{ - return slot->needLogin; -} - -PRBool -PK11_IsFriendly(PK11SlotInfo *slot) -{ - /* internal slot always has public readable certs */ - return (PRBool)(slot->isInternal || - ((slot->defaultFlags & SECMOD_FRIENDLY_FLAG) == - SECMOD_FRIENDLY_FLAG)); -} - -char * -PK11_GetTokenName(PK11SlotInfo *slot) -{ - return slot->token_name; -} - -char * -PK11_GetSlotName(PK11SlotInfo *slot) -{ - return slot->slot_name; -} - -int -PK11_GetSlotSeries(PK11SlotInfo *slot) -{ - return slot->series; -} - -int -PK11_GetCurrentWrapIndex(PK11SlotInfo *slot) -{ - return slot->wrapKey; -} - -CK_SLOT_ID -PK11_GetSlotID(PK11SlotInfo *slot) -{ - return slot->slotID; -} - -SECMODModuleID -PK11_GetModuleID(PK11SlotInfo *slot) -{ - return slot->module->moduleID; -} - -static void -pk11_zeroTerminatedToBlankPadded(CK_CHAR *buffer, size_t buffer_size) -{ - CK_CHAR *walk = buffer; - CK_CHAR *end = buffer + buffer_size; - - /* find the NULL */ - while (walk < end && *walk != '\0') { - walk++; - } - - /* clear out the buffer */ - while (walk < end) { - *walk++ = ' '; - } -} - -/* return the slot info structure */ -SECStatus -PK11_GetSlotInfo(PK11SlotInfo *slot, CK_SLOT_INFO *info) -{ - CK_RV crv; - - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - /* - * some buggy drivers do not fill the buffer completely, - * erase the buffer first - */ - PORT_Memset(info->slotDescription,' ',sizeof(info->slotDescription)); - PORT_Memset(info->manufacturerID,' ',sizeof(info->manufacturerID)); - crv = PK11_GETTAB(slot)->C_GetSlotInfo(slot->slotID,info); - pk11_zeroTerminatedToBlankPadded(info->slotDescription, - sizeof(info->slotDescription)); - pk11_zeroTerminatedToBlankPadded(info->manufacturerID, - sizeof(info->manufacturerID)); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - return SECSuccess; -} - -/* return the token info structure */ -SECStatus -PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info) -{ - CK_RV crv; - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - /* - * some buggy drivers do not fill the buffer completely, - * erase the buffer first - */ - PORT_Memset(info->label,' ',sizeof(info->label)); - PORT_Memset(info->manufacturerID,' ',sizeof(info->manufacturerID)); - PORT_Memset(info->model,' ',sizeof(info->model)); - PORT_Memset(info->serialNumber,' ',sizeof(info->serialNumber)); - crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID,info); - pk11_zeroTerminatedToBlankPadded(info->label,sizeof(info->label)); - pk11_zeroTerminatedToBlankPadded(info->manufacturerID, - sizeof(info->manufacturerID)); - pk11_zeroTerminatedToBlankPadded(info->model,sizeof(info->model)); - pk11_zeroTerminatedToBlankPadded(info->serialNumber, - sizeof(info->serialNumber)); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - return SECSuccess; -} - -/* Find out if we need to initialize the user's pin */ -PRBool -PK11_NeedUserInit(PK11SlotInfo *slot) -{ - PRBool needUserInit = (PRBool) ((slot->flags & CKF_USER_PIN_INITIALIZED) - == 0); - - if (needUserInit) { - CK_TOKEN_INFO info; - SECStatus rv; - - /* see if token has been initialized off line */ - rv = PK11_GetTokenInfo(slot, &info); - if (rv == SECSuccess) { - slot->flags = info.flags; - } - } - return (PRBool)((slot->flags & CKF_USER_PIN_INITIALIZED) == 0); -} - -/* get the internal key slot. FIPS has only one slot for both key slots and - * default slots */ -PK11SlotInfo * -PK11_GetInternalKeySlot(void) -{ - SECMODModule *mod = SECMOD_GetInternalModule(); - PORT_Assert(mod != NULL); - if (!mod) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - return PK11_ReferenceSlot(mod->isFIPS ? mod->slots[0] : mod->slots[1]); -} - -/* get the internal default slot */ -PK11SlotInfo * -PK11_GetInternalSlot(void) -{ - SECMODModule * mod = SECMOD_GetInternalModule(); - PORT_Assert(mod != NULL); - if (!mod) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - return PK11_ReferenceSlot(mod->slots[0]); -} - -PRBool -pk11_InDelayPeriod(PRIntervalTime lastTime, PRIntervalTime delayTime, - PRIntervalTime *retTime) -{ - PRIntervalTime time; - - *retTime = time = PR_IntervalNow(); - return (PRBool) (lastTime) && (time > lastTime) && - ((time-lastTime) < delayTime); -} - -/* - * Determine if the token is logged in. We have to actually query the token, - * because it's state can change without intervention from us. - */ -PRBool -PK11_IsLoggedIn(PK11SlotInfo *slot,void *wincx) -{ - CK_SESSION_INFO sessionInfo; - int askpw = slot->askpw; - int timeout = slot->timeout; - CK_RV crv; - PRIntervalTime curTime; - static PRIntervalTime login_delay_time = 0; - - if (login_delay_time == 0) { - login_delay_time = PR_SecondsToInterval(1); - } - - /* If we don't have our own password default values, use the system - * ones */ - if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) { - PK11SlotInfo *def_slot = PK11_GetInternalKeySlot(); - - if (def_slot) { - askpw = def_slot->askpw; - timeout = def_slot->timeout; - PK11_FreeSlot(def_slot); - } - } - - if ((wincx != NULL) && (PK11_Global.isLoggedIn != NULL) && - (*PK11_Global.isLoggedIn)(slot, wincx) == PR_FALSE) { return PR_FALSE; } - - - /* forget the password if we've been inactive too long */ - if (askpw == 1) { - int64 currtime = PR_Now(); - int64 result; - int64 mult; - - LL_I2L(result, timeout); - LL_I2L(mult, 60*1000*1000); - LL_MUL(result,result,mult); - LL_ADD(result, result, slot->authTime); - if (LL_CMP(result, <, currtime) ) { - PK11_EnterSlotMonitor(slot); - PK11_GETTAB(slot)->C_Logout(slot->session); - slot->lastLoginCheck = 0; - PK11_ExitSlotMonitor(slot); - } else { - slot->authTime = currtime; - } - } - - PK11_EnterSlotMonitor(slot); - if (pk11_InDelayPeriod(slot->lastLoginCheck,login_delay_time, &curTime)) { - sessionInfo.state = slot->lastState; - crv = CKR_OK; - } else { - crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session,&sessionInfo); - if (crv == CKR_OK) { - slot->lastState = sessionInfo.state; - slot->lastLoginCheck = curTime; - } - } - PK11_ExitSlotMonitor(slot); - /* if we can't get session info, something is really wrong */ - if (crv != CKR_OK) { - slot->session = CK_INVALID_SESSION; - return PR_FALSE; - } - - switch (sessionInfo.state) { - case CKS_RW_PUBLIC_SESSION: - case CKS_RO_PUBLIC_SESSION: - default: - break; /* fail */ - case CKS_RW_USER_FUNCTIONS: - case CKS_RW_SO_FUNCTIONS: - case CKS_RO_USER_FUNCTIONS: - return PR_TRUE; - } - return PR_FALSE; -} - - -/* - * check if a given slot supports the requested mechanism - */ -PRBool -PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type) -{ - int i; - - /* CKM_FAKE_RANDOM is not a real PKCS mechanism. It's a marker to - * tell us we're looking form someone that has implemented get - * random bits */ - if (type == CKM_FAKE_RANDOM) { - return slot->hasRandom; - } - - for (i=0; i < (int) slot->mechanismCount; i++) { - if (slot->mechanismList[i] == type) return PR_TRUE; - } - return PR_FALSE; -} - -/* - * Return true if a token that can do the desired mechanism exists. - * This allows us to have hardware tokens that can do function XYZ magically - * allow SSL Ciphers to appear if they are plugged in. - */ -PRBool -PK11_TokenExists(CK_MECHANISM_TYPE type) -{ - SECMODModuleList *mlp; - SECMODModuleList *modules = SECMOD_GetDefaultModuleList(); - SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); - PK11SlotInfo *slot; - PRBool found = PR_FALSE; - int i; - - /* we only need to know if there is a token that does this mechanism. - * check the internal module first because it's fast, and supports - * almost everything. */ - slot = PK11_GetInternalSlot(); - if (slot) { - found = PK11_DoesMechanism(slot,type); - PK11_FreeSlot(slot); - } - if (found) return PR_TRUE; /* bypass getting module locks */ - - SECMOD_GetReadLock(moduleLock); - for(mlp = modules; mlp != NULL && (!found); mlp = mlp->next) { - for (i=0; i < mlp->module->slotCount; i++) { - slot = mlp->module->slots[i]; - if (PK11_IsPresent(slot)) { - if (PK11_DoesMechanism(slot,type)) { - found = PR_TRUE; - break; - } - } - } - } - SECMOD_ReleaseReadLock(moduleLock); - return found; -} - -/* - * get all the currently available tokens in a list. - * that can perform the given mechanism. If mechanism is CKM_INVALID_MECHANISM, - * get all the tokens. Make sure tokens that need authentication are put at - * the end of this list. - */ -PK11SlotList * -PK11_GetAllTokens(CK_MECHANISM_TYPE type, PRBool needRW, PRBool loadCerts, - void *wincx) -{ - PK11SlotList * list = PK11_NewSlotList(); - PK11SlotList * loginList = PK11_NewSlotList(); - PK11SlotList * friendlyList = PK11_NewSlotList(); - SECMODModuleList * mlp; - SECMODModuleList * modules = SECMOD_GetDefaultModuleList(); - SECMODListLock * moduleLock = SECMOD_GetDefaultModuleListLock(); - int i; -#if defined( XP_WIN32 ) - int j = 0; - PRInt32 waste[16]; -#endif - - if ((list == NULL) || (loginList == NULL) || (friendlyList == NULL)) { - if (list) PK11_FreeSlotList(list); - if (loginList) PK11_FreeSlotList(loginList); - if (friendlyList) PK11_FreeSlotList(friendlyList); - return NULL; - } - - SECMOD_GetReadLock(moduleLock); - for(mlp = modules; mlp != NULL; mlp = mlp->next) { - -#if defined( XP_WIN32 ) - /* This is works around some horrible cache/page thrashing problems - ** on Win32. Without this, this loop can take up to 6 seconds at - ** 100% CPU on a Pentium-Pro 200. The thing this changes is to - ** increase the size of the stack frame and modify it. - ** Moving the loop code itself seems to have no effect. - ** Dunno why this combination makes a difference, but it does. - */ - waste[ j & 0xf] = j++; -#endif - - for (i = 0; i < mlp->module->slotCount; i++) { - PK11SlotInfo *slot = mlp->module->slots[i]; - - if (pk11_IsPresentCertLoad(slot, loadCerts)) { - if (needRW && slot->readOnly) continue; - if ((type == CKM_INVALID_MECHANISM) - || PK11_DoesMechanism(slot, type)) { - if (slot->needLogin && !PK11_IsLoggedIn(slot, wincx)) { - if (PK11_IsFriendly(slot)) { - PK11_AddSlotToList(friendlyList, slot); - } else { - PK11_AddSlotToList(loginList, slot); - } - } else { - PK11_AddSlotToList(list, slot); - } - } - } - } - } - SECMOD_ReleaseReadLock(moduleLock); - - PK11_MoveListToList(list,friendlyList); - PK11_FreeSlotList(friendlyList); - PK11_MoveListToList(list,loginList); - PK11_FreeSlotList(loginList); - - return list; -} - -/* - * NOTE: This routine is working from a private List generated by - * PK11_GetAllTokens. That is why it does not need to lock. - */ -PK11SlotList * -PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type,PRBool needRW,void *wincx) -{ - PK11SlotList *list = PK11_GetAllTokens(type,needRW,PR_TRUE,wincx); - PK11SlotListElement *le, *next ; - SECStatus rv; - - if (list == NULL) return list; - - for (le = list->head ; le; le = next) { - next = le->next; /* save the pointer here in case we have to - * free the element later */ - rv = PK11_Authenticate(le->slot,PR_TRUE,wincx); - if (rv != SECSuccess) { - PK11_DeleteSlotFromList(list,le); - continue; - } - } - return list; -} - - -/* - * find the best slot which supports the given - * Mechanism. In normal cases this should grab the first slot on the list - * with no fuss. - */ -PK11SlotInfo * -PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int mech_count, void *wincx) -{ - PK11SlotList *list = NULL; - PK11SlotListElement *le ; - PK11SlotInfo *slot = NULL; - PRBool freeit = PR_FALSE; - PRBool listNeedLogin = PR_FALSE; - int i; - SECStatus rv; - - list = PK11_GetSlotList(type[0]); - - if ((list == NULL) || (list->head == NULL)) { - /* We need to look up all the tokens for the mechanism */ - list = PK11_GetAllTokens(type[0],PR_FALSE,PR_TRUE,wincx); - freeit = PR_TRUE; - } - - /* no one can do it! */ - if (list == NULL) { - PORT_SetError(SEC_ERROR_NO_TOKEN); - return NULL; - } - - PORT_SetError(0); - - - listNeedLogin = PR_FALSE; - for (i=0; i < mech_count; i++) { - if ((type[i] != CKM_FAKE_RANDOM) && (type[i] != CKM_SHA_1) && - (type[i] != CKM_MD5) && (type[i] != CKM_MD2)) { - listNeedLogin = PR_TRUE; - break; - } - } - - for (le = PK11_GetFirstSafe(list); le; - le = PK11_GetNextSafe(list,le,PR_TRUE)) { - if (PK11_IsPresent(le->slot)) { - PRBool doExit = PR_FALSE; - for (i=0; i < mech_count; i++) { - if (!PK11_DoesMechanism(le->slot,type[i])) { - doExit = PR_TRUE; - break; - } - } - if (doExit) continue; - - if (listNeedLogin && le->slot->needLogin) { - rv = PK11_Authenticate(le->slot,PR_TRUE,wincx); - if (rv != SECSuccess) continue; - } - slot = le->slot; - PK11_ReferenceSlot(slot); - pk11_FreeListElement(list,le); - if (freeit) { PK11_FreeSlotList(list); } - return slot; - } - } - if (freeit) { PK11_FreeSlotList(list); } - if (PORT_GetError() == 0) { - PORT_SetError(SEC_ERROR_NO_TOKEN); - } - return NULL; -} - -/* original get best slot now calls the multiple version with only one type */ -PK11SlotInfo * -PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx) -{ - return PK11_GetBestSlotMultiple(&type, 1, wincx); -} - -/* - * find the best key wrap mechanism for this slot. - */ -CK_MECHANISM_TYPE -PK11_GetBestWrapMechanism(PK11SlotInfo *slot) -{ - int i; - for (i=0; i < wrapMechanismCount; i++) { - if (PK11_DoesMechanism(slot,wrapMechanismList[i])) { - return wrapMechanismList[i]; - } - } - return CKM_INVALID_MECHANISM; -} - -int -PK11_GetBestKeyLength(PK11SlotInfo *slot,CK_MECHANISM_TYPE mechanism) -{ - CK_MECHANISM_INFO mechanism_info; - CK_RV crv; - - if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID, - mechanism,&mechanism_info); - if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) return 0; - - if (mechanism_info.ulMinKeySize == mechanism_info.ulMaxKeySize) - return 0; - return mechanism_info.ulMaxKeySize; -} - - -/********************************************************************* - * Mechanism Mapping functions - *********************************************************************/ - -/* - * lookup an entry in the mechanism table. If none found, return the - * default structure. - */ -static pk11MechanismData * -pk11_lookup(CK_MECHANISM_TYPE type) -{ - int i; - for (i=0; i < pk11_MechEntrySize; i++) { - if (pk11_MechanismTable[i].type == type) { - return (&pk11_MechanismTable[i]); - } - } - return &pk11_default; -} - -/* - * NOTE: This is not thread safe. Called at init time, and when loading - * a new Entry. It is reasonably safe as long as it is not re-entered - * (readers will always see a consistant table) - * - * This routine is called to add entries to the mechanism table, once there, - * they can not be removed. - */ -void -PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key, - CK_MECHANISM_TYPE keyGen, int ivLen, int blockSize) -{ - int tableSize = pk11_MechTableSize; - int size = pk11_MechEntrySize; - int entry = size++; - pk11MechanismData *old = pk11_MechanismTable; - pk11MechanismData *newt = pk11_MechanismTable; - - - if (size > tableSize) { - int oldTableSize = tableSize; - tableSize += 10; - newt = (pk11MechanismData *) - PORT_Alloc(tableSize*sizeof(pk11MechanismData)); - if (newt == NULL) return; - - if (old) PORT_Memcpy(newt,old,oldTableSize*sizeof(pk11MechanismData)); - } else old = NULL; - - newt[entry].type = type; - newt[entry].keyType = key; - newt[entry].keyGen = keyGen; - newt[entry].iv = ivLen; - newt[entry].blockSize = blockSize; - - pk11_MechanismTable = newt; - pk11_MechTableSize = tableSize; - pk11_MechEntrySize = size; - if (old) PORT_Free(old); -} - -/* - * Get the key type needed for the given mechanism - */ -CK_MECHANISM_TYPE -PK11_GetKeyType(CK_MECHANISM_TYPE type,unsigned long len) -{ - switch (type) { - case CKM_AES_ECB: - case CKM_AES_CBC: - case CKM_AES_MAC: - case CKM_AES_MAC_GENERAL: - case CKM_AES_CBC_PAD: - case CKM_AES_KEY_GEN: - return CKK_AES; - case CKM_DES_ECB: - case CKM_DES_CBC: - case CKM_DES_MAC: - case CKM_DES_MAC_GENERAL: - case CKM_DES_CBC_PAD: - case CKM_DES_KEY_GEN: - case CKM_KEY_WRAP_LYNKS: - case CKM_PBE_MD2_DES_CBC: - case CKM_PBE_MD5_DES_CBC: - return CKK_DES; - case CKM_DES3_ECB: - case CKM_DES3_CBC: - case CKM_DES3_MAC: - case CKM_DES3_MAC_GENERAL: - case CKM_DES3_CBC_PAD: - return (len == 128) ? CKK_DES2 : CKK_DES3; - case CKM_DES2_KEY_GEN: - case CKM_PBE_SHA1_DES2_EDE_CBC: - return CKK_DES2; - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_DES3_KEY_GEN: - return CKK_DES3; - case CKM_CDMF_ECB: - case CKM_CDMF_CBC: - case CKM_CDMF_MAC: - case CKM_CDMF_MAC_GENERAL: - case CKM_CDMF_CBC_PAD: - case CKM_CDMF_KEY_GEN: - return CKK_CDMF; - case CKM_RC2_ECB: - case CKM_RC2_CBC: - case CKM_RC2_MAC: - case CKM_RC2_MAC_GENERAL: - case CKM_RC2_CBC_PAD: - case CKM_RC2_KEY_GEN: - case CKM_PBE_SHA1_RC2_128_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - return CKK_RC2; - case CKM_RC4: - case CKM_RC4_KEY_GEN: - return CKK_RC4; - case CKM_RC5_ECB: - case CKM_RC5_CBC: - case CKM_RC5_MAC: - case CKM_RC5_MAC_GENERAL: - case CKM_RC5_CBC_PAD: - case CKM_RC5_KEY_GEN: - return CKK_RC5; - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_SKIPJACK_KEY_GEN: - case CKM_SKIPJACK_WRAP: - case CKM_SKIPJACK_PRIVATE_WRAP: - return CKK_SKIPJACK; - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_BATON_WRAP: - case CKM_BATON_KEY_GEN: - return CKK_BATON; - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - case CKM_JUNIPER_WRAP: - case CKM_JUNIPER_KEY_GEN: - return CKK_JUNIPER; - case CKM_IDEA_CBC: - case CKM_IDEA_ECB: - case CKM_IDEA_MAC: - case CKM_IDEA_MAC_GENERAL: - case CKM_IDEA_CBC_PAD: - case CKM_IDEA_KEY_GEN: - return CKK_IDEA; - case CKM_CAST_ECB: - case CKM_CAST_CBC: - case CKM_CAST_MAC: - case CKM_CAST_MAC_GENERAL: - case CKM_CAST_CBC_PAD: - case CKM_CAST_KEY_GEN: - case CKM_PBE_MD5_CAST_CBC: - return CKK_CAST; - case CKM_CAST3_ECB: - case CKM_CAST3_CBC: - case CKM_CAST3_MAC: - case CKM_CAST3_MAC_GENERAL: - case CKM_CAST3_CBC_PAD: - case CKM_CAST3_KEY_GEN: - case CKM_PBE_MD5_CAST3_CBC: - return CKK_CAST3; - case CKM_CAST5_ECB: - case CKM_CAST5_CBC: - case CKM_CAST5_MAC: - case CKM_CAST5_MAC_GENERAL: - case CKM_CAST5_CBC_PAD: - case CKM_CAST5_KEY_GEN: - case CKM_PBE_MD5_CAST5_CBC: - return CKK_CAST5; - case CKM_RSA_PKCS: - case CKM_RSA_9796: - case CKM_RSA_X_509: - case CKM_MD2_RSA_PKCS: - case CKM_MD5_RSA_PKCS: - case CKM_SHA1_RSA_PKCS: - case CKM_KEY_WRAP_SET_OAEP: - case CKM_RSA_PKCS_KEY_PAIR_GEN: - return CKK_RSA; - case CKM_DSA: - case CKM_DSA_SHA1: - case CKM_DSA_KEY_PAIR_GEN: - return CKK_DSA; - case CKM_DH_PKCS_DERIVE: - case CKM_DH_PKCS_KEY_PAIR_GEN: - return CKK_DH; - case CKM_KEA_KEY_DERIVE: - case CKM_KEA_KEY_PAIR_GEN: - return CKK_KEA; - case CKM_ECDSA_KEY_PAIR_GEN: - case CKM_ECDSA: - case CKM_ECDSA_SHA1: - return CKK_ECDSA; - case CKM_SSL3_PRE_MASTER_KEY_GEN: - case CKM_GENERIC_SECRET_KEY_GEN: - case CKM_SSL3_MASTER_KEY_DERIVE: - case CKM_SSL3_MASTER_KEY_DERIVE_DH: - case CKM_SSL3_KEY_AND_MAC_DERIVE: - case CKM_SSL3_SHA1_MAC: - case CKM_SSL3_MD5_MAC: - case CKM_TLS_MASTER_KEY_DERIVE: - case CKM_TLS_MASTER_KEY_DERIVE_DH: - case CKM_TLS_KEY_AND_MAC_DERIVE: - case CKM_SHA_1_HMAC: - case CKM_SHA_1_HMAC_GENERAL: - case CKM_MD2_HMAC: - case CKM_MD2_HMAC_GENERAL: - case CKM_MD5_HMAC: - case CKM_MD5_HMAC_GENERAL: - case CKM_TLS_PRF_GENERAL: - return CKK_GENERIC_SECRET; - default: - return pk11_lookup(type)->keyType; - } -} - -/* - * Get the Key Gen Mechanism needed for the given - * crypto mechanism - */ -CK_MECHANISM_TYPE -PK11_GetKeyGen(CK_MECHANISM_TYPE type) -{ - switch (type) { - case CKM_AES_ECB: - case CKM_AES_CBC: - case CKM_AES_MAC: - case CKM_AES_MAC_GENERAL: - case CKM_AES_CBC_PAD: - case CKM_AES_KEY_GEN: - return CKM_AES_KEY_GEN; - case CKM_DES_ECB: - case CKM_DES_CBC: - case CKM_DES_MAC: - case CKM_DES_MAC_GENERAL: - case CKM_KEY_WRAP_LYNKS: - case CKM_DES_CBC_PAD: - case CKM_DES_KEY_GEN: - return CKM_DES_KEY_GEN; - case CKM_DES3_ECB: - case CKM_DES3_CBC: - case CKM_DES3_MAC: - case CKM_DES3_MAC_GENERAL: - case CKM_DES3_CBC_PAD: - case CKM_DES3_KEY_GEN: - return CKM_DES3_KEY_GEN; - case CKM_CDMF_ECB: - case CKM_CDMF_CBC: - case CKM_CDMF_MAC: - case CKM_CDMF_MAC_GENERAL: - case CKM_CDMF_CBC_PAD: - case CKM_CDMF_KEY_GEN: - return CKM_CDMF_KEY_GEN; - case CKM_RC2_ECB: - case CKM_RC2_CBC: - case CKM_RC2_MAC: - case CKM_RC2_MAC_GENERAL: - case CKM_RC2_CBC_PAD: - case CKM_RC2_KEY_GEN: - return CKM_RC2_KEY_GEN; - case CKM_RC4: - case CKM_RC4_KEY_GEN: - return CKM_RC4_KEY_GEN; - case CKM_RC5_ECB: - case CKM_RC5_CBC: - case CKM_RC5_MAC: - case CKM_RC5_MAC_GENERAL: - case CKM_RC5_CBC_PAD: - case CKM_RC5_KEY_GEN: - return CKM_RC5_KEY_GEN; - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_SKIPJACK_WRAP: - case CKM_SKIPJACK_KEY_GEN: - return CKM_SKIPJACK_KEY_GEN; - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_BATON_WRAP: - case CKM_BATON_KEY_GEN: - return CKM_BATON_KEY_GEN; - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - case CKM_JUNIPER_WRAP: - case CKM_JUNIPER_KEY_GEN: - return CKM_JUNIPER_KEY_GEN; - case CKM_IDEA_CBC: - case CKM_IDEA_ECB: - case CKM_IDEA_MAC: - case CKM_IDEA_MAC_GENERAL: - case CKM_IDEA_CBC_PAD: - case CKM_IDEA_KEY_GEN: - return CKM_IDEA_KEY_GEN; - case CKM_CAST_ECB: - case CKM_CAST_CBC: - case CKM_CAST_MAC: - case CKM_CAST_MAC_GENERAL: - case CKM_CAST_CBC_PAD: - case CKM_CAST_KEY_GEN: - return CKM_CAST_KEY_GEN; - case CKM_CAST3_ECB: - case CKM_CAST3_CBC: - case CKM_CAST3_MAC: - case CKM_CAST3_MAC_GENERAL: - case CKM_CAST3_CBC_PAD: - case CKM_CAST3_KEY_GEN: - return CKM_CAST3_KEY_GEN; - case CKM_CAST5_ECB: - case CKM_CAST5_CBC: - case CKM_CAST5_MAC: - case CKM_CAST5_MAC_GENERAL: - case CKM_CAST5_CBC_PAD: - case CKM_CAST5_KEY_GEN: - return CKM_CAST5_KEY_GEN; - case CKM_RSA_PKCS: - case CKM_RSA_9796: - case CKM_RSA_X_509: - case CKM_MD2_RSA_PKCS: - case CKM_MD5_RSA_PKCS: - case CKM_SHA1_RSA_PKCS: - case CKM_KEY_WRAP_SET_OAEP: - case CKM_RSA_PKCS_KEY_PAIR_GEN: - return CKM_RSA_PKCS_KEY_PAIR_GEN; - case CKM_DSA: - case CKM_DSA_SHA1: - case CKM_DSA_KEY_PAIR_GEN: - return CKM_DSA_KEY_PAIR_GEN; - case CKM_DH_PKCS_DERIVE: - case CKM_DH_PKCS_KEY_PAIR_GEN: - return CKM_DH_PKCS_KEY_PAIR_GEN; - case CKM_KEA_KEY_DERIVE: - case CKM_KEA_KEY_PAIR_GEN: - return CKM_KEA_KEY_PAIR_GEN; - case CKM_ECDSA: - case CKM_ECDSA_KEY_PAIR_GEN: - return CKM_ECDSA_KEY_PAIR_GEN; - case CKM_SSL3_PRE_MASTER_KEY_GEN: - case CKM_SSL3_MASTER_KEY_DERIVE: - case CKM_SSL3_KEY_AND_MAC_DERIVE: - case CKM_SSL3_SHA1_MAC: - case CKM_SSL3_MD5_MAC: - case CKM_TLS_MASTER_KEY_DERIVE: - case CKM_TLS_KEY_AND_MAC_DERIVE: - return CKM_SSL3_PRE_MASTER_KEY_GEN; - case CKM_SHA_1_HMAC: - case CKM_SHA_1_HMAC_GENERAL: - case CKM_MD2_HMAC: - case CKM_MD2_HMAC_GENERAL: - case CKM_MD5_HMAC: - case CKM_MD5_HMAC_GENERAL: - case CKM_TLS_PRF_GENERAL: - case CKM_GENERIC_SECRET_KEY_GEN: - return CKM_GENERIC_SECRET_KEY_GEN; - case CKM_PBE_MD2_DES_CBC: - case CKM_PBE_MD5_DES_CBC: - case CKM_PBA_SHA1_WITH_SHA1_HMAC: - case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN: - case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN: - case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN: - case CKM_NETSCAPE_PBE_SHA1_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: - case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - case CKM_PBE_SHA1_RC2_128_CBC: - case CKM_PBE_SHA1_RC4_40: - case CKM_PBE_SHA1_RC4_128: - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_PBE_SHA1_DES2_EDE_CBC: - return type; - default: - return pk11_lookup(type)->keyGen; - } -} - -/* - * get the mechanism block size - */ -int -PK11_GetBlockSize(CK_MECHANISM_TYPE type,SECItem *params) -{ - CK_RC5_PARAMS *rc5_params; - CK_RC5_CBC_PARAMS *rc5_cbc_params; - switch (type) { - case CKM_RC5_ECB: - if ((params) && (params->data)) { - rc5_params = (CK_RC5_PARAMS *) params->data; - return (rc5_params->ulWordsize)*2; - } - return 8; - case CKM_RC5_CBC: - case CKM_RC5_CBC_PAD: - if ((params) && (params->data)) { - rc5_cbc_params = (CK_RC5_CBC_PARAMS *) params->data; - return (rc5_cbc_params->ulWordsize)*2; - } - return 8; - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_RC2_ECB: - case CKM_IDEA_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST5_ECB: - case CKM_RC2_CBC: - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_DES_CBC: - case CKM_DES3_CBC: - case CKM_IDEA_CBC: - case CKM_CAST_CBC: - case CKM_CAST3_CBC: - case CKM_CAST5_CBC: - case CKM_DES_CBC_PAD: - case CKM_DES3_CBC_PAD: - case CKM_RC2_CBC_PAD: - case CKM_IDEA_CBC_PAD: - case CKM_CAST_CBC_PAD: - case CKM_CAST3_CBC_PAD: - case CKM_CAST5_CBC_PAD: - case CKM_PBE_MD2_DES_CBC: - case CKM_PBE_MD5_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - case CKM_PBE_SHA1_RC2_128_CBC: - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_PBE_SHA1_DES2_EDE_CBC: - return 8; - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - return 4; - case CKM_AES_ECB: - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - case CKM_BATON_ECB128: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - return 16; - case CKM_BATON_ECB96: - return 12; - case CKM_RC4: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: - case CKM_PBE_SHA1_RC4_40: - case CKM_PBE_SHA1_RC4_128: - return 0; - case CKM_RSA_PKCS: - case CKM_RSA_9796: - case CKM_RSA_X_509: - /*actually it's the modulus length of the key!*/ - return -1; /* failure */ - default: - return pk11_lookup(type)->blockSize; - } -} - -/* - * get the iv length - */ -int -PK11_GetIVLength(CK_MECHANISM_TYPE type) -{ - switch (type) { - case CKM_AES_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_RC2_ECB: - case CKM_IDEA_ECB: - case CKM_SKIPJACK_WRAP: - case CKM_BATON_WRAP: - case CKM_RC5_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST5_ECB: - return 0; - case CKM_RC2_CBC: - case CKM_DES_CBC: - case CKM_DES3_CBC: - case CKM_IDEA_CBC: - case CKM_PBE_MD2_DES_CBC: - case CKM_PBE_MD5_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - case CKM_PBE_SHA1_RC2_128_CBC: - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_PBE_SHA1_DES2_EDE_CBC: - case CKM_RC5_CBC: - case CKM_CAST_CBC: - case CKM_CAST3_CBC: - case CKM_CAST5_CBC: - case CKM_RC2_CBC_PAD: - case CKM_DES_CBC_PAD: - case CKM_DES3_CBC_PAD: - case CKM_IDEA_CBC_PAD: - case CKM_RC5_CBC_PAD: - case CKM_CAST_CBC_PAD: - case CKM_CAST3_CBC_PAD: - case CKM_CAST5_CBC_PAD: - return 8; - case CKM_AES_CBC: - case CKM_AES_CBC_PAD: - return 16; - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - return 24; - case CKM_RC4: - case CKM_RSA_PKCS: - case CKM_RSA_9796: - case CKM_RSA_X_509: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: - case CKM_PBE_SHA1_RC4_40: - case CKM_PBE_SHA1_RC4_128: - return 0; - default: - return pk11_lookup(type)->iv; - } -} - - -/* These next two utilities are here to help facilitate future - * Dynamic Encrypt/Decrypt symetric key mechanisms, and to allow functions - * like SSL and S-MIME to automatically add them. - */ -SECItem * -PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) -{ - CK_RC2_CBC_PARAMS *rc2_params = NULL; - CK_RC2_PARAMS *rc2_ecb_params = NULL; - CK_RC5_PARAMS *rc5_params = NULL; - CK_RC5_CBC_PARAMS *rc5_cbc_params = NULL; - SECItem *param; - - param = (SECItem *)PORT_Alloc(sizeof(SECItem)); - if (param == NULL) return NULL; - param->data = NULL; - param->len = 0; - param->type = 0; - switch (type) { - case CKM_AES_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - case CKM_RSA_9796: - case CKM_IDEA_ECB: - case CKM_CDMF_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST5_ECB: - case CKM_RC4: - break; - case CKM_RC2_ECB: - rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); - if (rc2_ecb_params == NULL) break; - /* Maybe we should pass the key size in too to get this value? */ - *rc2_ecb_params = 128; - param->data = (unsigned char *) rc2_ecb_params; - param->len = sizeof(CK_RC2_PARAMS); - break; - case CKM_RC2_CBC: - case CKM_RC2_CBC_PAD: - rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); - if (rc2_params == NULL) break; - /* Maybe we should pass the key size in too to get this value? */ - rc2_params->ulEffectiveBits = 128; - if (iv && iv->data) - PORT_Memcpy(rc2_params->iv,iv->data,sizeof(rc2_params->iv)); - param->data = (unsigned char *) rc2_params; - param->len = sizeof(CK_RC2_CBC_PARAMS); - break; - case CKM_RC5_CBC: - case CKM_RC5_CBC_PAD: - rc5_cbc_params = (CK_RC5_CBC_PARAMS *) - PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0)); - if (rc5_cbc_params == NULL) break; - if (iv && iv->data) { - rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) - + sizeof(CK_RC5_CBC_PARAMS); - PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len); - rc5_cbc_params->ulIvLen = iv->len; - rc5_cbc_params->ulWordsize = iv->len/2; - } else { - rc5_cbc_params->ulWordsize = 4; - rc5_cbc_params->pIv = NULL; - rc5_cbc_params->ulIvLen = iv->len; - } - rc5_cbc_params->ulRounds = 16; - param->data = (unsigned char *) rc5_cbc_params; - param->len = sizeof(CK_RC5_CBC_PARAMS); - break; - case CKM_RC5_ECB: - rc5_params = (CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS)); - if (rc5_params == NULL) break; - if (iv && iv->data && iv->len) { - rc5_params->ulWordsize = iv->len/2; - } else { - rc5_params->ulWordsize = 4; - } - rc5_params->ulRounds = 16; - param->data = (unsigned char *) rc5_params; - param->len = sizeof(CK_RC5_PARAMS); - break; - case CKM_AES_CBC: - case CKM_DES_CBC: - case CKM_DES3_CBC: - case CKM_IDEA_CBC: - case CKM_CDMF_CBC: - case CKM_CAST_CBC: - case CKM_CAST3_CBC: - case CKM_CAST5_CBC: - case CKM_AES_CBC_PAD: - case CKM_DES_CBC_PAD: - case CKM_DES3_CBC_PAD: - case CKM_IDEA_CBC_PAD: - case CKM_CDMF_CBC_PAD: - case CKM_CAST_CBC_PAD: - case CKM_CAST3_CBC_PAD: - case CKM_CAST5_CBC_PAD: - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - if ((iv == NULL) || (iv->data == NULL)) break; - param->data = (unsigned char*)PORT_Alloc(iv->len); - if (param->data != NULL) { - PORT_Memcpy(param->data,iv->data,iv->len); - param->len = iv->len; - } - break; - /* unknown mechanism, pass IV in if it's there */ - default: - if (pk11_lookup(type)->iv == 0) { - break; - } - if ((iv == NULL) || (iv->data == NULL)) { - break; - } - param->data = (unsigned char*)PORT_Alloc(iv->len); - if (param->data != NULL) { - PORT_Memcpy(param->data,iv->data,iv->len); - param->len = iv->len; - } - break; - } - return param; -} - -unsigned char * -PK11_IVFromParam(CK_MECHANISM_TYPE type,SECItem *param,int *len) -{ - CK_RC2_CBC_PARAMS *rc2_params; - CK_RC5_CBC_PARAMS *rc5_cbc_params; - - *len = 0; - switch (type) { - case CKM_AES_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - case CKM_RSA_9796: - case CKM_IDEA_ECB: - case CKM_CDMF_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST5_ECB: - case CKM_RC4: - return NULL; - case CKM_RC2_ECB: - return NULL; - case CKM_RC2_CBC: - case CKM_RC2_CBC_PAD: - rc2_params = (CK_RC2_CBC_PARAMS *)param->data; - *len = sizeof(rc2_params->iv); - return &rc2_params->iv[0]; - case CKM_RC5_CBC: - case CKM_RC5_CBC_PAD: - rc5_cbc_params = (CK_RC5_CBC_PARAMS *) param->data; - *len = rc5_cbc_params->ulIvLen; - return rc5_cbc_params->pIv; - case CKM_AES_CBC: - case CKM_DES_CBC: - case CKM_DES3_CBC: - case CKM_IDEA_CBC: - case CKM_CDMF_CBC: - case CKM_CAST_CBC: - case CKM_CAST3_CBC: - case CKM_CAST5_CBC: - case CKM_DES_CBC_PAD: - case CKM_DES3_CBC_PAD: - case CKM_IDEA_CBC_PAD: - case CKM_CDMF_CBC_PAD: - case CKM_CAST_CBC_PAD: - case CKM_CAST3_CBC_PAD: - case CKM_CAST5_CBC_PAD: - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - break; - /* unknown mechanism, pass IV in if it's there */ - default: - break; - } - if (param->data) { - *len = param->len; - } - return param->data; -} - -typedef struct sec_rc5cbcParameterStr { - SECItem version; - SECItem rounds; - SECItem blockSizeInBits; - SECItem iv; -} sec_rc5cbcParameter; - -static const SEC_ASN1Template sec_rc5ecb_parameter_template[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(sec_rc5cbcParameter) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc5cbcParameter,version) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc5cbcParameter,rounds) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc5cbcParameter,blockSizeInBits) }, - { 0 } -}; - -static const SEC_ASN1Template sec_rc5cbc_parameter_template[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(sec_rc5cbcParameter) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc5cbcParameter,version) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc5cbcParameter,rounds) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc5cbcParameter,blockSizeInBits) }, - { SEC_ASN1_OCTET_STRING, - offsetof(sec_rc5cbcParameter,iv) }, - { 0 } -}; - -typedef struct sec_rc2cbcParameterStr { - SECItem rc2ParameterVersion; - SECItem iv; -} sec_rc2cbcParameter; - -static const SEC_ASN1Template sec_rc2cbc_parameter_template[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(sec_rc2cbcParameter) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc2cbcParameter,rc2ParameterVersion) }, - { SEC_ASN1_OCTET_STRING, - offsetof(sec_rc2cbcParameter,iv) }, - { 0 } -}; - -static const SEC_ASN1Template sec_rc2ecb_parameter_template[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(sec_rc2cbcParameter) }, - { SEC_ASN1_INTEGER, - offsetof(sec_rc2cbcParameter,rc2ParameterVersion) }, - { 0 } -}; - -/* S/MIME picked id values to represent differnt keysizes */ -/* I do have a formula, but it ain't pretty, and it only works because you - * can always match three points to a parabola:) */ -static unsigned char rc2_map(SECItem *version) -{ - long x; - - x = DER_GetInteger(version); - - switch (x) { - case 58: return 128; - case 120: return 64; - case 160: return 40; - } - return 128; -} - -static unsigned long rc2_unmap(unsigned long x) -{ - switch (x) { - case 128: return 58; - case 64: return 120; - case 40: return 160; - } - return 58; -} - - - -/* Generate a mechaism param from a type, and iv. */ -SECItem * -PK11_ParamFromAlgid(SECAlgorithmID *algid) -{ - CK_RC2_CBC_PARAMS *rc2_params = NULL; - CK_RC2_PARAMS *rc2_ecb_params = NULL; - CK_RC5_CBC_PARAMS *rc5_params_cbc; - CK_RC5_PARAMS *rc5_params_ecb; - SECItem iv; - sec_rc2cbcParameter rc2; - sec_rc5cbcParameter rc5; - SECItem *mech; - CK_MECHANISM_TYPE type; - SECOidTag algtag; - SECStatus rv; - - algtag = SECOID_GetAlgorithmTag(algid); - type = PK11_AlgtagToMechanism(algtag); - - mech = (SECItem *) PORT_Alloc(sizeof(SECItem)); - if (mech == NULL) return NULL; - mech->type = siBuffer; - - - /* handle the complicated cases */ - switch (type) { - case CKM_RC2_ECB: - rv = SEC_ASN1DecodeItem(NULL, &rc2 ,sec_rc2ecb_parameter_template, - &(algid->parameters)); - if (rv != SECSuccess) { - PORT_Free(mech); - return NULL; - } - rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); - if (rc2_ecb_params == NULL) { - PORT_Free(rc2.rc2ParameterVersion.data); - PORT_Free(mech); - return NULL; - } - *rc2_ecb_params = rc2_map(&rc2.rc2ParameterVersion); - PORT_Free(rc2.rc2ParameterVersion.data); - mech->data = (unsigned char *) rc2_ecb_params; - mech->len = sizeof(CK_RC2_PARAMS); - return mech; - case CKM_RC2_CBC: - case CKM_RC2_CBC_PAD: - rv = SEC_ASN1DecodeItem(NULL, &rc2 ,sec_rc2cbc_parameter_template, - &(algid->parameters)); - if (rv != SECSuccess) { - PORT_Free(mech); - return NULL; - } - rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); - if (rc2_params == NULL) { - PORT_Free(rc2.iv.data); - PORT_Free(rc2.rc2ParameterVersion.data); - PORT_Free(mech); - return NULL; - } - rc2_params->ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion); - PORT_Free(rc2.rc2ParameterVersion.data); - PORT_Memcpy(rc2_params->iv,rc2.iv.data,sizeof(rc2_params->iv)); - PORT_Free(rc2.iv.data); - mech->data = (unsigned char *) rc2_params; - mech->len = sizeof(CK_RC2_CBC_PARAMS); - return mech; - case CKM_RC5_ECB: - rv = SEC_ASN1DecodeItem(NULL, &rc5 ,sec_rc5ecb_parameter_template, - &(algid->parameters)); - if (rv != SECSuccess) { - PORT_Free(mech); - return NULL; - } - rc5_params_ecb=(CK_RC5_PARAMS *)PORT_Alloc(sizeof(CK_RC5_PARAMS)); - PORT_Free(rc5.version.data); - if (rc5_params_ecb == NULL) { - PORT_Free(rc5.rounds.data); - PORT_Free(rc5.blockSizeInBits.data); - PORT_Free(mech); - return NULL; - } - rc5_params_ecb->ulRounds = DER_GetInteger(&rc5.rounds); - rc5_params_ecb->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8; - PORT_Free(rc5.rounds.data); - PORT_Free(rc5.blockSizeInBits.data); - mech->data = (unsigned char *) rc5_params_ecb; - mech->len = sizeof(CK_RC5_PARAMS); - return mech; - case CKM_RC5_CBC: - case CKM_RC5_CBC_PAD: - rv = SEC_ASN1DecodeItem(NULL, &rc5 ,sec_rc5cbc_parameter_template, - &(algid->parameters)); - if (rv != SECSuccess) { - PORT_Free(mech); - return NULL; - } - rc5_params_cbc = (CK_RC5_CBC_PARAMS *) - PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + rc5.iv.len); - PORT_Free(rc5.version.data); - if (rc2_params == NULL) { - PORT_Free(rc5.iv.data); - PORT_Free(rc5.rounds.data); - PORT_Free(rc5.blockSizeInBits.data); - PORT_Free(mech); - return NULL; - } - rc5_params_cbc->ulRounds = DER_GetInteger(&rc5.rounds); - rc5_params_cbc->ulWordsize = DER_GetInteger(&rc5.blockSizeInBits)/8; - PORT_Free(rc5.rounds.data); - PORT_Free(rc5.blockSizeInBits.data); - rc5_params_cbc->pIv = ((CK_BYTE_PTR)rc5_params_cbc) - + sizeof(CK_RC5_CBC_PARAMS); - PORT_Memcpy(rc5_params_cbc->pIv,rc5.iv.data,rc5.iv.len); - rc5_params_cbc->ulIvLen = rc5.iv.len; - PORT_Free(rc5.iv.data); - mech->data = (unsigned char *) rc5_params_cbc; - mech->len = sizeof(CK_RC5_CBC_PARAMS); - return mech; - case CKM_PBE_MD2_DES_CBC: - case CKM_PBE_MD5_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: - case CKM_PBE_SHA1_DES2_EDE_CBC: - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - case CKM_PBE_SHA1_RC2_128_CBC: - case CKM_PBE_SHA1_RC4_40: - case CKM_PBE_SHA1_RC4_128: - rv = pbe_PK11AlgidToParam(algid,mech); - if (rv != SECSuccess) { - PORT_Free(mech); - return NULL; - } - return mech; - default: - /* must be a simple case */ - break; - } - - /* simple cases are simpley Octect encoded IV's */ - rv = SEC_ASN1DecodeItem(NULL, &iv, SEC_OctetStringTemplate, - &(algid->parameters)); - if (rv != SECSuccess) { - iv.data = NULL; - iv.len = 0; - } - - rv = SECSuccess; - switch (type) { - case CKM_RC4: - case CKM_AES_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_IDEA_ECB: - case CKM_CDMF_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST5_ECB: - mech->data = NULL; - mech->len = 0; - break; - default: - if (pk11_lookup(type)->iv == 0) { - mech->data = NULL; - mech->len = 0; - break; - } - case CKM_AES_CBC: - case CKM_DES_CBC: - case CKM_DES3_CBC: - case CKM_IDEA_CBC: - case CKM_CDMF_CBC: - case CKM_CAST_CBC: - case CKM_CAST3_CBC: - case CKM_CAST5_CBC: - case CKM_AES_CBC_PAD: - case CKM_DES_CBC_PAD: - case CKM_DES3_CBC_PAD: - case CKM_IDEA_CBC_PAD: - case CKM_CDMF_CBC_PAD: - case CKM_CAST_CBC_PAD: - case CKM_CAST3_CBC_PAD: - case CKM_CAST5_CBC_PAD: - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - if (iv.data == NULL) { - rv = SECFailure; - break; - } - mech->data = (unsigned char*)PORT_Alloc(iv.len); - if (mech->data == NULL) { - rv = SECFailure; - break; - } - PORT_Memcpy(mech->data,iv.data,iv.len); - mech->len = iv.len; - break; - } - if (iv.data) PORT_Free(iv.data); - if (rv != SECSuccess) { - SECITEM_FreeItem(mech,PR_TRUE); - return NULL; - } - return mech; -} - -SECStatus -PK11_SeedRandom(PK11SlotInfo *slot, unsigned char *data, int len) { - CK_RV crv; - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_SeedRandom(slot->session,data, (CK_ULONG)len); - PK11_ExitSlotMonitor(slot); - return (crv != CKR_OK) ? SECFailure : SECSuccess; -} - -/* Attempts to update the Best Slot for "FAKE RANDOM" generation. -** If that's not the internal slot, then it also attempts to update the -** internal slot. -** The return value indicates if the INTERNAL slot was updated OK. -*/ -SECStatus -PK11_RandomUpdate(void *data, size_t bytes) -{ - PK11SlotInfo *slot; - PRBool bestIsInternal; - SECStatus status; - - slot = PK11_GetBestSlot(CKM_FAKE_RANDOM, NULL); - if (slot == NULL) { - slot = PK11_GetInternalSlot(); - if (!slot) - return SECFailure; - } - - bestIsInternal = PK11_IsInternal(slot); - status = PK11_SeedRandom(slot, data, bytes); - PK11_FreeSlot(slot); - - if (!bestIsInternal) { - /* do internal slot, too. */ - slot = PK11_GetInternalSlot(); /* can't fail */ - status = PK11_SeedRandom(slot, data, bytes); - PK11_FreeSlot(slot); - } - return status; -} - - -SECStatus -PK11_GenerateRandom(unsigned char *data,int len) { - PK11SlotInfo *slot; - CK_RV crv; - - slot = PK11_GetBestSlot(CKM_FAKE_RANDOM,NULL); - if (slot == NULL) return SECFailure; - - if (!slot->isInternal) PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GenerateRandom(slot->session,data, - (CK_ULONG)len); - if (!slot->isInternal) PK11_ExitSlotMonitor(slot); - PK11_FreeSlot(slot); - return (crv != CKR_OK) ? SECFailure : SECSuccess; -} - -/* - * Generate an IV for the given mechanism - */ -static SECStatus -pk11_GenIV(CK_MECHANISM_TYPE type, SECItem *iv) { - int iv_size = PK11_GetIVLength(type); - SECStatus rv; - - iv->len = iv_size; - if (iv_size == 0) { - iv->data = NULL; - return SECSuccess; - } - - iv->data = (unsigned char *) PORT_Alloc(iv_size); - if (iv->data == NULL) { - iv->len = 0; - return SECFailure; - } - - rv = PK11_GenerateRandom(iv->data,iv->len); - if (rv != SECSuccess) { - PORT_Free(iv->data); - iv->data = NULL; iv->len = 0; - return SECFailure; - } - return SECSuccess; -} - - -/* - * create a new paramter block from the passed in MECHANISM and the - * key. Use Netscape's S/MIME Rules for the New param block. - */ -SECItem * -PK11_GenerateNewParam(CK_MECHANISM_TYPE type, PK11SymKey *key) { - CK_RC2_CBC_PARAMS *rc2_params; - CK_RC2_PARAMS *rc2_ecb_params; - SECItem *mech; - SECItem iv; - SECStatus rv; - - - mech = (SECItem *) PORT_Alloc(sizeof(SECItem)); - if (mech == NULL) return NULL; - - rv = SECSuccess; - mech->type = siBuffer; - switch (type) { - case CKM_RC4: - case CKM_AES_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_IDEA_ECB: - case CKM_CDMF_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST5_ECB: - mech->data = NULL; - mech->len = 0; - break; - case CKM_RC2_ECB: - rc2_ecb_params = (CK_RC2_PARAMS *)PORT_Alloc(sizeof(CK_RC2_PARAMS)); - if (rc2_ecb_params == NULL) { - rv = SECFailure; - break; - } - /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5, - * or RC4 key. Of course that wouldn't happen here doing RC2:).*/ - *rc2_ecb_params = PK11_GetKeyLength(key)*8; - mech->data = (unsigned char *) rc2_ecb_params; - mech->len = sizeof(CK_RC2_PARAMS); - break; - case CKM_RC2_CBC: - case CKM_RC2_CBC_PAD: - rv = pk11_GenIV(type,&iv); - if (rv != SECSuccess) { - break; - } - rc2_params = (CK_RC2_CBC_PARAMS *)PORT_Alloc(sizeof(CK_RC2_CBC_PARAMS)); - if (rc2_params == NULL) { - PORT_Free(iv.data); - rv = SECFailure; - break; - } - /* NOTE PK11_GetKeyLength can return -1 if the key isn't and RC2, RC5, - * or RC4 key. Of course that wouldn't happen here doing RC2:).*/ - rc2_params->ulEffectiveBits = PK11_GetKeyLength(key)*8; - if (iv.data) - PORT_Memcpy(rc2_params->iv,iv.data,sizeof(rc2_params->iv)); - mech->data = (unsigned char *) rc2_params; - mech->len = sizeof(CK_RC2_CBC_PARAMS); - PORT_Free(iv.data); - break; - case CKM_RC5_ECB: - PORT_Free(mech); - return PK11_ParamFromIV(type,NULL); - case CKM_RC5_CBC: - case CKM_RC5_CBC_PAD: - rv = pk11_GenIV(type,&iv); - if (rv != SECSuccess) { - break; - } - PORT_Free(mech); - return PK11_ParamFromIV(type,&iv); - default: - if (pk11_lookup(type)->iv == 0) { - mech->data = NULL; - mech->len = 0; - break; - } - case CKM_AES_CBC: - case CKM_DES_CBC: - case CKM_DES3_CBC: - case CKM_IDEA_CBC: - case CKM_CDMF_CBC: - case CKM_CAST_CBC: - case CKM_CAST3_CBC: - case CKM_CAST5_CBC: - case CKM_DES_CBC_PAD: - case CKM_DES3_CBC_PAD: - case CKM_IDEA_CBC_PAD: - case CKM_CDMF_CBC_PAD: - case CKM_CAST_CBC_PAD: - case CKM_CAST3_CBC_PAD: - case CKM_CAST5_CBC_PAD: - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - rv = pk11_GenIV(type,&iv); - if (rv != SECSuccess) { - break; - } - mech->data = (unsigned char*)PORT_Alloc(iv.len); - if (mech->data == NULL) { - PORT_Free(iv.data); - rv = SECFailure; - break; - } - PORT_Memcpy(mech->data,iv.data,iv.len); - mech->len = iv.len; - PORT_Free(iv.data); - break; - } - if (rv != SECSuccess) { - SECITEM_FreeItem(mech,PR_TRUE); - return NULL; - } - return mech; - -} - -#define RC5_V10 0x10 - -/* turn a PKCS #11 parameter into a DER Encoded Algorithm ID */ -SECStatus -PK11_ParamToAlgid(SECOidTag algTag, SECItem *param, - PRArenaPool *arena, SECAlgorithmID *algid) { - CK_RC2_CBC_PARAMS *rc2_params; - sec_rc2cbcParameter rc2; - CK_RC5_CBC_PARAMS *rc5_params; - sec_rc5cbcParameter rc5; - CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(algTag); - SECItem *newParams = NULL; - SECStatus rv = SECFailure; - unsigned long rc2version; - - rv = SECSuccess; - switch (type) { - case CKM_RC4: - case CKM_AES_ECB: - case CKM_DES_ECB: - case CKM_DES3_ECB: - case CKM_IDEA_ECB: - case CKM_CDMF_ECB: - case CKM_CAST_ECB: - case CKM_CAST3_ECB: - case CKM_CAST5_ECB: - newParams = NULL; - rv = SECSuccess; - break; - case CKM_RC2_ECB: - break; - case CKM_RC2_CBC: - case CKM_RC2_CBC_PAD: - rc2_params = (CK_RC2_CBC_PARAMS *)param->data; - rc2version = rc2_unmap(rc2_params->ulEffectiveBits); - if (SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion), - rc2version) == NULL) - break; - rc2.iv.data = rc2_params->iv; - rc2.iv.len = sizeof(rc2_params->iv); - newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc2, - sec_rc2cbc_parameter_template); - PORT_Free(rc2.rc2ParameterVersion.data); - if (newParams == NULL) - break; - rv = SECSuccess; - break; - - case CKM_RC5_ECB: /* well not really... */ - break; - case CKM_RC5_CBC: - case CKM_RC5_CBC_PAD: - rc5_params = (CK_RC5_CBC_PARAMS *)param->data; - if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.version, RC5_V10) == NULL) - break; - if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.blockSizeInBits, - rc5_params->ulWordsize*8) == NULL) { - PORT_Free(rc5.version.data); - break; - } - if (SEC_ASN1EncodeUnsignedInteger (NULL, &rc5.rounds, - rc5_params->ulWordsize*8) == NULL) { - PORT_Free(rc5.blockSizeInBits.data); - PORT_Free(rc5.version.data); - break; - } - rc5.iv.data = rc5_params->pIv; - rc5.iv.len = rc5_params->ulIvLen; - newParams = SEC_ASN1EncodeItem (NULL, NULL, &rc5, - sec_rc5cbc_parameter_template); - PORT_Free(rc5.version.data); - PORT_Free(rc5.blockSizeInBits.data); - PORT_Free(rc5.rounds.data); - if (newParams == NULL) - break; - rv = SECSuccess; - break; - case CKM_PBE_MD2_DES_CBC: - case CKM_PBE_MD5_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_PBE_SHA1_DES2_EDE_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - case CKM_PBE_SHA1_RC2_128_CBC: - case CKM_PBE_SHA1_RC4_40: - case CKM_PBE_SHA1_RC4_128: - return PBE_PK11ParamToAlgid(algTag, param, arena, algid); - default: - if (pk11_lookup(type)->iv == 0) { - rv = SECSuccess; - newParams = NULL; - break; - } - case CKM_AES_CBC: - case CKM_DES_CBC: - case CKM_DES3_CBC: - case CKM_IDEA_CBC: - case CKM_CDMF_CBC: - case CKM_CAST_CBC: - case CKM_CAST3_CBC: - case CKM_CAST5_CBC: - case CKM_DES_CBC_PAD: - case CKM_DES3_CBC_PAD: - case CKM_IDEA_CBC_PAD: - case CKM_CDMF_CBC_PAD: - case CKM_CAST_CBC_PAD: - case CKM_CAST3_CBC_PAD: - case CKM_CAST5_CBC_PAD: - case CKM_SKIPJACK_CBC64: - case CKM_SKIPJACK_ECB64: - case CKM_SKIPJACK_OFB64: - case CKM_SKIPJACK_CFB64: - case CKM_SKIPJACK_CFB32: - case CKM_SKIPJACK_CFB16: - case CKM_SKIPJACK_CFB8: - case CKM_BATON_ECB128: - case CKM_BATON_ECB96: - case CKM_BATON_CBC128: - case CKM_BATON_COUNTER: - case CKM_BATON_SHUFFLE: - case CKM_JUNIPER_ECB128: - case CKM_JUNIPER_CBC128: - case CKM_JUNIPER_COUNTER: - case CKM_JUNIPER_SHUFFLE: - newParams = SEC_ASN1EncodeItem(NULL,NULL,param, - SEC_OctetStringTemplate); - rv = SECSuccess; - break; - } - - if (rv != SECSuccess) { - if (newParams) SECITEM_FreeItem(newParams,PR_TRUE); - return rv; - } - - rv = SECOID_SetAlgorithmID(arena, algid, algTag, newParams); - SECITEM_FreeItem(newParams,PR_TRUE); - return rv; -} - -/* turn an OID algorithm tag into a PKCS #11 mechanism. This allows us to - * map OID's directly into the PKCS #11 mechanism we want to call. We find - * this mapping in our standard OID table */ -CK_MECHANISM_TYPE -PK11_AlgtagToMechanism(SECOidTag algTag) { - SECOidData *oid = SECOID_FindOIDByTag(algTag); - - if (oid) return (CK_MECHANISM_TYPE) oid->mechanism; - return CKM_INVALID_MECHANISM; -} - -/* turn a mechanism into an oid. */ -SECOidTag -PK11_MechanismToAlgtag(CK_MECHANISM_TYPE type) { - SECOidData *oid = SECOID_FindOIDByMechanism((unsigned long)type); - - if (oid) return oid->offset; - return SEC_OID_UNKNOWN; -} - -/* Determine appropriate blocking mechanism, used when wrapping private keys - * which require PKCS padding. If the mechanism does not map to a padding - * mechanism, we simply return the mechanism. - */ -CK_MECHANISM_TYPE -PK11_GetPadMechanism(CK_MECHANISM_TYPE type) { - switch(type) { - case CKM_AES_CBC: - return CKM_AES_CBC_PAD; - case CKM_DES_CBC: - return CKM_DES_CBC_PAD; - case CKM_DES3_CBC: - return CKM_DES3_CBC_PAD; - case CKM_RC2_CBC: - return CKM_RC2_CBC_PAD; - case CKM_CDMF_CBC: - return CKM_CDMF_CBC_PAD; - case CKM_CAST_CBC: - return CKM_CAST_CBC_PAD; - case CKM_CAST3_CBC: - return CKM_CAST3_CBC_PAD; - case CKM_CAST5_CBC: - return CKM_CAST5_CBC_PAD; - case CKM_RC5_CBC: - return CKM_RC5_CBC_PAD; - case CKM_IDEA_CBC: - return CKM_IDEA_CBC_PAD; - default: - break; - } - - return type; -} - -/* - * Build a block big enough to hold the data - */ -SECItem * -PK11_BlockData(SECItem *data,unsigned long size) { - SECItem *newData; - - newData = (SECItem *)PORT_Alloc(sizeof(SECItem)); - if (newData == NULL) return NULL; - - newData->len = (data->len + (size-1))/size; - newData->len *= size; - - newData->data = (unsigned char *) PORT_ZAlloc(newData->len); - if (newData->data == NULL) { - PORT_Free(newData); - return NULL; - } - PORT_Memset(newData->data,newData->len-data->len,newData->len); - PORT_Memcpy(newData->data,data->data,data->len); - return newData; -} - - -SECStatus -PK11_DestroyObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) { - CK_RV crv; - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_DestroyObject(slot->session,object); - PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - return SECFailure; - } - return SECSuccess; -} - -SECStatus -PK11_DestroyTokenObject(PK11SlotInfo *slot,CK_OBJECT_HANDLE object) { - CK_RV crv; - SECStatus rv = SECSuccess; - CK_SESSION_HANDLE rwsession; - - - rwsession = PK11_GetRWSession(slot); - - crv = PK11_GETTAB(slot)->C_DestroyObject(rwsession,object); - if (crv != CKR_OK) { - rv = SECFailure; - PORT_SetError(PK11_MapError(crv)); - } - PK11_RestoreROSession(slot,rwsession); - return rv; -} - -/* - * Read in a single attribute into a SECItem. Allocate space for it with - * PORT_Alloc unless an arena is supplied. In the latter case use the arena - * to allocate the space. - */ -SECStatus -PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type, PRArenaPool *arena, SECItem *result) { - CK_ATTRIBUTE attr = { 0, NULL, 0 }; - CK_RV crv; - - attr.type = type; - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1); - if (crv != CKR_OK) { - PK11_ExitSlotMonitor(slot); - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - if (arena) { - attr.pValue = PORT_ArenaAlloc(arena,attr.ulValueLen); - } else { - attr.pValue = PORT_Alloc(attr.ulValueLen); - } - if (attr.pValue == NULL) return SECFailure; - crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1); - PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - if (!arena) PORT_Free(attr.pValue); - return SECFailure; - } - - result->data = (unsigned char*)attr.pValue; - result->len = attr.ulValueLen; - - return SECSuccess; -} - -/* - * Read in a single attribute into As a Ulong. - */ -CK_ULONG -PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type) { - CK_ATTRIBUTE attr; - CK_ULONG value = CK_UNAVAILABLE_INFORMATION; - CK_RV crv; - - PK11_SETATTRS(&attr,type,&value,sizeof(value)); - - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,id,&attr,1); - PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - } - return value; -} - -/* - * check to see if a bool has been set. - */ -CK_BBOOL -PK11_HasAttributeSet( PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE_TYPE type ) -{ - CK_BBOOL ckvalue = CK_FALSE; - CK_ATTRIBUTE theTemplate; - CK_RV crv; - - /* Prepare to retrieve the attribute. */ - PK11_SETATTRS( &theTemplate, type, &ckvalue, sizeof( CK_BBOOL ) ); - - /* Retrieve attribute value. */ - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB( slot )->C_GetAttributeValue( slot->session, id, - &theTemplate, 1 ); - PK11_ExitSlotMonitor(slot); - if( crv != CKR_OK ) { - PORT_SetError( PK11_MapError( crv ) ); - return CK_FALSE; - } - - return ckvalue; -} - -/* - * returns a full list of attributes. Allocate space for them. If an arena is - * provided, allocate space out of the arena. - */ -CK_RV -PK11_GetAttributes(PRArenaPool *arena,PK11SlotInfo *slot, - CK_OBJECT_HANDLE obj,CK_ATTRIBUTE *attr, int count) -{ - int i; - /* make pedantic happy... note that it's only used arena != NULL */ - void *mark = NULL; - CK_RV crv; - - /* - * first get all the lengths of the parameters. - */ - PK11_EnterSlotMonitor(slot); - crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,obj,attr,count); - if (crv != CKR_OK) { - PK11_ExitSlotMonitor(slot); - return crv; - } - - if (arena) { - mark = PORT_ArenaMark(arena); - if (mark == NULL) return CKR_HOST_MEMORY; - } - - /* - * now allocate space to store the results. - */ - for (i=0; i < count; i++) { - if (arena) { - attr[i].pValue = PORT_ArenaAlloc(arena,attr[i].ulValueLen); - if (attr[i].pValue == NULL) { - /* arena failures, just release the mark */ - PORT_ArenaRelease(arena,mark); - PK11_ExitSlotMonitor(slot); - return CKR_HOST_MEMORY; - } - } else { - attr[i].pValue = PORT_Alloc(attr[i].ulValueLen); - if (attr[i].pValue == NULL) { - /* Separate malloc failures, loop to release what we have - * so far */ - int j; - for (j= 0; j < i; j++) { - PORT_Free(attr[j].pValue); - /* don't give the caller pointers to freed memory */ - attr[j].pValue = NULL; - } - PK11_ExitSlotMonitor(slot); - return CKR_HOST_MEMORY; - } - } - } - - /* - * finally get the results. - */ - crv = PK11_GETTAB(slot)->C_GetAttributeValue(slot->session,obj,attr,count); - PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - if (arena) { - PORT_ArenaRelease(arena,mark); - } else { - for (i= 0; i < count; i++) { - PORT_Free(attr[i].pValue); - /* don't give the caller pointers to freed memory */ - attr[i].pValue = NULL; - } - } - } else if (arena && mark) { - PORT_ArenaUnmark(arena,mark); - } - return crv; -} - -/* - * Reset the token to it's initial state. For the internal module, this will - * Purge your keydb, and reset your cert db certs to USER_INIT. - */ -SECStatus -PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd) -{ - unsigned char tokenName[32]; - int tokenNameLen; - CK_RV crv; - - /* reconstruct the token name */ - tokenNameLen = PORT_Strlen(slot->token_name); - if (tokenNameLen > sizeof(tokenName)) { - tokenNameLen = sizeof(tokenName); - } - - PORT_Memcpy(tokenName,slot->token_name,tokenNameLen); - if (tokenNameLen < sizeof(tokenName)) { - PORT_Memset(&tokenName[tokenNameLen],' ', - sizeof(tokenName)-tokenNameLen); - } - - /* initialize the token */ - PK11_EnterSlotMonitor(slot); - - /* first shutdown the token. Existing sessions will get closed here */ - PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID); - slot->session = CK_INVALID_SESSION; - - /* now re-init the token */ - crv = PK11_GETTAB(slot)->C_InitToken(slot->slotID, - (unsigned char *)sso_pwd, sso_pwd ? PORT_Strlen(sso_pwd): 0, tokenName); - - /* finally bring the token back up */ - PK11_InitToken(slot,PR_TRUE); - PK11_ExitSlotMonitor(slot); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - return SECSuccess; -} - -static PRBool -pk11_isAllZero(unsigned char *data,int len) { - while (len--) { - if (*data++) { - return PR_FALSE; - } - } - return PR_TRUE; -} - -CK_RV -PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism, - CK_MECHANISM_PTR pCryptoMechanism, - SECItem *pbe_pwd, PRBool faulty3DES) -{ - int iv_len = 0; - CK_PBE_PARAMS_PTR pPBEparams; - CK_RC2_CBC_PARAMS_PTR rc2_params; - CK_ULONG rc2_key_len; - - if((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) { - return CKR_HOST_MEMORY; - } - - pPBEparams = (CK_PBE_PARAMS_PTR)pPBEMechanism->pParameter; - iv_len = PK11_GetIVLength(pPBEMechanism->mechanism); - - if (iv_len) { - if (pk11_isAllZero(pPBEparams->pInitVector,iv_len)) { - SECItem param; - PK11SymKey *symKey; - PK11SlotInfo *intSlot = PK11_GetInternalSlot(); - - if (intSlot == NULL) { - return CKR_DEVICE_ERROR; - } - - param.data = pPBEMechanism->pParameter; - param.len = pPBEMechanism->ulParameterLen; - - symKey = PK11_RawPBEKeyGen(intSlot, - pPBEMechanism->mechanism, ¶m, pbe_pwd, faulty3DES, NULL); - PK11_FreeSlot(intSlot); - if (symKey== NULL) { - return CKR_DEVICE_ERROR; /* sigh */ - } - PK11_FreeSymKey(symKey); - } - } - - switch(pPBEMechanism->mechanism) { - case CKM_PBE_MD2_DES_CBC: - case CKM_PBE_MD5_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_DES_CBC: - pCryptoMechanism->mechanism = CKM_DES_CBC; - goto have_crypto_mechanism; - case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: - case CKM_PBE_SHA1_DES3_EDE_CBC: - case CKM_PBE_SHA1_DES2_EDE_CBC: - pCryptoMechanism->mechanism = CKM_DES3_CBC; -have_crypto_mechanism: - pCryptoMechanism->pParameter = PORT_Alloc(iv_len); - pCryptoMechanism->ulParameterLen = (CK_ULONG)iv_len; - if(pCryptoMechanism->pParameter == NULL) { - return CKR_HOST_MEMORY; - } - PORT_Memcpy((unsigned char *)(pCryptoMechanism->pParameter), - (unsigned char *)(pPBEparams->pInitVector), - iv_len); - break; - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4: - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4: - case CKM_PBE_SHA1_RC4_40: - case CKM_PBE_SHA1_RC4_128: - pCryptoMechanism->mechanism = CKM_RC4; - pCryptoMechanism->ulParameterLen = 0; - pCryptoMechanism->pParameter = CK_NULL_PTR; - break; - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - rc2_key_len = 40; - goto have_key_len; - case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC: - rc2_key_len = 128; -have_key_len: - pCryptoMechanism->mechanism = CKM_RC2_CBC; - pCryptoMechanism->ulParameterLen = (CK_ULONG) - sizeof(CK_RC2_CBC_PARAMS); - pCryptoMechanism->pParameter = (CK_RC2_CBC_PARAMS_PTR) - PORT_ZAlloc(sizeof(CK_RC2_CBC_PARAMS)); - if(pCryptoMechanism->pParameter == NULL) { - return CKR_HOST_MEMORY; - } - rc2_params = (CK_RC2_CBC_PARAMS_PTR)pCryptoMechanism->pParameter; - PORT_Memcpy((unsigned char *)rc2_params->iv, - (unsigned char *)pPBEparams->pInitVector, - iv_len); - rc2_params->ulEffectiveBits = rc2_key_len; - break; - default: - return CKR_MECHANISM_INVALID; - } - - return CKR_OK; -} - -PRBool -PK11_IsPermObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle) -{ - return (PRBool) PK11_HasAttributeSet(slot, handle, CKA_TOKEN); -} - -char * -PK11_GetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id) -{ - char *nickname = NULL; - SECItem result; - SECStatus rv; - - rv = PK11_ReadAttribute(slot,id,CKA_LABEL,NULL,&result); - if (rv != SECSuccess) { - return NULL; - } - - nickname = PORT_ZAlloc(result.len); - if (nickname == NULL) { - PORT_Free(result.data); - return NULL; - } - PORT_Memcpy(nickname, result.data, result.len); - PORT_Free(result.data); - return nickname; -} - -SECStatus -PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, - const char *nickname) -{ - int len = PORT_Strlen(nickname); - CK_ATTRIBUTE setTemplate; - CK_RV crv; - CK_SESSION_HANDLE rwsession; - - if (len < 0) { - return SECFailure; - } - - PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *) nickname, len); - rwsession = PK11_GetRWSession(slot); - crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession, id, - &setTemplate, 1); - PK11_RestoreROSession(slot, rwsession); - if (crv != CKR_OK) { - PORT_SetError(PK11_MapError(crv)); - return SECFailure; - } - return SECSuccess; -} diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c deleted file mode 100644 index d620bb8e0..000000000 --- a/security/nss/lib/pk11wrap/pk11util.c +++ /dev/null @@ -1,712 +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. - */ -/* - * Initialize the PCKS 11 subsystem - */ -#include "seccomon.h" -#include "secmod.h" -#include "nssilock.h" -#include "secmodi.h" -#include "pk11func.h" -#include "pki3hack.h" -#include "secerr.h" - -/* these are for displaying error messages */ - -static SECMODModuleList *modules = NULL; -static SECMODModuleList *modulesDB = NULL; -static SECMODModuleList *modulesUnload = NULL; -static SECMODModule *internalModule = NULL; -static SECMODModule *defaultDBModule = NULL; -static SECMODModule *pendingModule = NULL; -static SECMODListLock *moduleLock = NULL; - -int secmod_PrivateModuleCount = 0; - -extern PK11DefaultArrayEntry PK11_DefaultArray[]; -extern int num_pk11_default_mechanisms; - - -void -SECMOD_Init() { - /* don't initialize twice */ - if (moduleLock) return; - - moduleLock = SECMOD_NewListLock(); - PK11_InitSlotLists(); -} - - -SECStatus -SECMOD_Shutdown() { - /* destroy the lock */ - if (moduleLock) { - SECMOD_DestroyListLock(moduleLock); - moduleLock = NULL; - } - /* free the internal module */ - if (internalModule) { - SECMOD_DestroyModule(internalModule); - internalModule = NULL; - } - - /* free the default database module */ - if (defaultDBModule) { - SECMOD_DestroyModule(defaultDBModule); - defaultDBModule = NULL; - } - - /* destroy the list */ - if (modules) { - SECMOD_DestroyModuleList(modules); - modules = NULL; - } - - if (modulesDB) { - SECMOD_DestroyModuleList(modulesDB); - modulesDB = NULL; - } - - if (modulesUnload) { - SECMOD_DestroyModuleList(modulesUnload); - modulesUnload = NULL; - } - - /* make all the slots and the lists go away */ - PK11_DestroySlotLists(); - - nss_DumpModuleLog(); - -#ifdef DEBUG - if (PR_GetEnv("NSS_STRICT_SHUTDOWN")) { - PORT_Assert(secmod_PrivateModuleCount == 0); - } -#endif - return (secmod_PrivateModuleCount == 0) ? SECSuccess : SECFailure; -} - - -/* - * retrieve the internal module - */ -SECMODModule * -SECMOD_GetInternalModule(void) { - return internalModule; -} - - -SECStatus -secmod_AddModuleToList(SECMODModuleList **moduleList,SECMODModule *newModule) { - SECMODModuleList *mlp, *newListElement, *last = NULL; - - newListElement = SECMOD_NewModuleListElement(); - if (newListElement == NULL) { - return SECFailure; - } - - newListElement->module = SECMOD_ReferenceModule(newModule); - - SECMOD_GetWriteLock(moduleLock); - /* Added it to the end (This is very inefficient, but Adding a module - * on the fly should happen maybe 2-3 times through the life this program - * on a given computer, and this list should be *SHORT*. */ - for(mlp = *moduleList; mlp != NULL; mlp = mlp->next) { - last = mlp; - } - - if (last == NULL) { - *moduleList = newListElement; - } else { - SECMOD_AddList(last,newListElement,NULL); - } - SECMOD_ReleaseWriteLock(moduleLock); - return SECSuccess; -} - -SECStatus -SECMOD_AddModuleToList(SECMODModule *newModule) { - if (newModule->internal && !internalModule) { - internalModule = SECMOD_ReferenceModule(newModule); - } - return secmod_AddModuleToList(&modules,newModule); -} - -SECStatus -SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule) { - if (defaultDBModule == NULL) { - defaultDBModule = SECMOD_ReferenceModule(newModule); - } - return secmod_AddModuleToList(&modulesDB,newModule); -} - -SECStatus -SECMOD_AddModuleToUnloadList(SECMODModule *newModule) { - return secmod_AddModuleToList(&modulesUnload,newModule); -} - -/* - * get the list of PKCS11 modules that are available. - */ -SECMODModuleList *SECMOD_GetDefaultModuleList() { return modules; } -SECMODListLock *SECMOD_GetDefaultModuleListLock() { return moduleLock; } - - - -/* - * find a module by name, and add a reference to it. - * return that module. - */ -SECMODModule *SECMOD_FindModule(char *name) { - SECMODModuleList *mlp; - SECMODModule *module = NULL; - - SECMOD_GetReadLock(moduleLock); - for(mlp = modules; mlp != NULL; mlp = mlp->next) { - if (PORT_Strcmp(name,mlp->module->commonName) == 0) { - module = mlp->module; - SECMOD_ReferenceModule(module); - break; - } - } - SECMOD_ReleaseReadLock(moduleLock); - - return module; -} - -/* - * find a module by ID, and add a reference to it. - * return that module. - */ -SECMODModule *SECMOD_FindModuleByID(SECMODModuleID id) { - SECMODModuleList *mlp; - SECMODModule *module = NULL; - - SECMOD_GetReadLock(moduleLock); - for(mlp = modules; mlp != NULL; mlp = mlp->next) { - if (id == mlp->module->moduleID) { - module = mlp->module; - SECMOD_ReferenceModule(module); - break; - } - } - SECMOD_ReleaseReadLock(moduleLock); - - return module; -} - -/* - * lookup the Slot module based on it's module ID and slot ID. - */ -PK11SlotInfo *SECMOD_LookupSlot(SECMODModuleID moduleID,CK_SLOT_ID slotID) { - int i; - SECMODModule *module; - - module = SECMOD_FindModuleByID(moduleID); - if (module == NULL) return NULL; - - for (i=0; i < module->slotCount; i++) { - PK11SlotInfo *slot = module->slots[i]; - - if (slot->slotID == slotID) { - SECMOD_DestroyModule(module); - return PK11_ReferenceSlot(slot); - } - } - SECMOD_DestroyModule(module); - return NULL; -} - - -/* - * find a module by name or module pointer and delete it off the module list. - * optionally remove it from secmod.db. - */ -SECStatus -SECMOD_DeleteModuleEx(char *name, SECMODModule *mod, int *type, PRBool permdb) { - SECMODModuleList *mlp; - SECMODModuleList **mlpp; - SECStatus rv = SECFailure; - - - *type = SECMOD_EXTERNAL; - - SECMOD_GetWriteLock(moduleLock); - for(mlpp = &modules,mlp = modules; - mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) { - if ((name && (PORT_Strcmp(name,mlp->module->commonName) == 0)) || - mod == mlp->module) { - /* don't delete the internal module */ - if (!mlp->module->internal) { - SECMOD_RemoveList(mlpp,mlp); - /* delete it after we release the lock */ - rv = STAN_RemoveModuleFromDefaultTrustDomain(mlp->module); - } else if (mlp->module->isFIPS) { - *type = SECMOD_FIPS; - } else { - *type = SECMOD_INTERNAL; - } - break; - } - } - SECMOD_ReleaseWriteLock(moduleLock); - - - if (rv == SECSuccess) { - if (permdb) { - SECMOD_DeletePermDB(mlp->module); - } - SECMOD_DestroyModuleListElement(mlp); - } - return rv; -} - -/* - * find a module by name and delete it off the module list - */ -SECStatus -SECMOD_DeleteModule(char *name, int *type) { - return SECMOD_DeleteModuleEx(name, NULL, type, PR_TRUE); -} - -/* - * find a module by name and delete it off the module list - */ -SECStatus -SECMOD_DeleteInternalModule(char *name) { - SECMODModuleList *mlp; - SECMODModuleList **mlpp; - SECStatus rv = SECFailure; - - if (pendingModule) { - PORT_SetError(SEC_ERROR_MODULE_STUCK); - return rv; - } - - SECMOD_GetWriteLock(moduleLock); - for(mlpp = &modules,mlp = modules; - mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) { - if (PORT_Strcmp(name,mlp->module->commonName) == 0) { - /* don't delete the internal module */ - if (mlp->module->internal) { - SECMOD_RemoveList(mlpp,mlp); - rv = STAN_RemoveModuleFromDefaultTrustDomain(mlp->module); - } - break; - } - } - SECMOD_ReleaseWriteLock(moduleLock); - - if (rv == SECSuccess) { - SECMODModule *newModule,*oldModule; - - if (mlp->module->isFIPS) { - newModule = SECMOD_CreateModule(NULL, SECMOD_INT_NAME, - NULL, SECMOD_INT_FLAGS); - } else { - newModule = SECMOD_CreateModule(NULL, SECMOD_FIPS_NAME, - NULL, SECMOD_FIPS_FLAGS); - } - if (newModule == NULL) { - SECMODModuleList *last = NULL,*mlp2; - /* we're in pretty deep trouble if this happens...Security - * not going to work well... try to put the old module back on - * the list */ - SECMOD_GetWriteLock(moduleLock); - for(mlp2 = modules; mlp2 != NULL; mlp2 = mlp->next) { - last = mlp2; - } - - if (last == NULL) { - modules = mlp; - } else { - SECMOD_AddList(last,mlp,NULL); - } - SECMOD_ReleaseWriteLock(moduleLock); - return SECFailure; - } - newModule->libraryParams = - PORT_ArenaStrdup(newModule->arena,mlp->module->libraryParams); - pendingModule = oldModule = internalModule; - internalModule = NULL; - SECMOD_DestroyModule(oldModule); - SECMOD_DeletePermDB(mlp->module); - SECMOD_DestroyModuleListElement(mlp); - internalModule = newModule; /* adopt the module */ - SECMOD_AddModule(internalModule); - } - return rv; -} - -SECStatus -SECMOD_AddModule(SECMODModule *newModule) { - SECStatus rv; - SECMODModule *oldModule; - - /* Test if a module w/ the same name already exists */ - /* and return SECWouldBlock if so. */ - /* We should probably add a new return value such as */ - /* SECDublicateModule, but to minimize ripples, I'll */ - /* give SECWouldBlock a new meaning */ - if ((oldModule = SECMOD_FindModule(newModule->commonName)) != NULL) { - SECMOD_DestroyModule(oldModule); - return SECWouldBlock; - /* module already exists. */ - } - - rv = SECMOD_LoadPKCS11Module(newModule); - if (rv != SECSuccess) { - return rv; - } - - if (newModule->parent == NULL) { - newModule->parent = SECMOD_ReferenceModule(defaultDBModule); - } - - SECMOD_AddPermDB(newModule); - SECMOD_AddModuleToList(newModule); - - rv = STAN_AddModuleToDefaultTrustDomain(newModule); - - return rv; -} - -PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,char *name) { - int i; - char *string; - - for (i=0; i < module->slotCount; i++) { - PK11SlotInfo *slot = module->slots[i]; - - if (PK11_IsPresent(slot)) { - string = PK11_GetTokenName(slot); - } else { - string = PK11_GetSlotName(slot); - } - if (PORT_Strcmp(name,string) == 0) { - return PK11_ReferenceSlot(slot); - } - } - return NULL; -} - -SECStatus -PK11_GetModInfo(SECMODModule *mod,CK_INFO *info) { - CK_RV crv; - - if (mod->functionList == NULL) return SECFailure; - crv = PK11_GETTAB(mod)->C_GetInfo(info); - return (crv == CKR_OK) ? SECSuccess : SECFailure; -} - -/* Determine if we have the FIP's module loaded as the default - * module to trigger other bogus FIPS requirements in PKCS #12 and - * SSL - */ -PRBool -PK11_IsFIPS(void) -{ - SECMODModule *mod = SECMOD_GetInternalModule(); - - if (mod && mod->internal) { - return mod->isFIPS; - } - - return PR_FALSE; -} - -/* combines NewModule() & AddModule */ -/* give a string for the module name & the full-path for the dll, */ -/* installs the PKCS11 module & update registry */ -SECStatus SECMOD_AddNewModuleEx(char* moduleName, char* dllPath, - unsigned long defaultMechanismFlags, - unsigned long cipherEnableFlags, - char* modparms, - char* nssparms) { - SECMODModule *module; - SECStatus result = SECFailure; - int s,i; - PK11SlotInfo* slot; - - PR_SetErrorText(0, NULL); - - module = SECMOD_CreateModule(dllPath,moduleName, modparms, nssparms); - - if (module == NULL) { - return result; - } - - if (module->dllName != NULL) { - if (module->dllName[0] != 0) { - result = SECMOD_AddModule(module); - if (result == SECSuccess) { - /* turn on SSL cipher enable flags */ - module->ssl[0] = cipherEnableFlags; - - /* check each slot to turn on appropriate mechanisms */ - for (s = 0; s < module->slotCount; s++) { - slot = (module->slots)[s]; - /* for each possible mechanism */ - for (i=0; i < num_pk11_default_mechanisms; i++) { - /* we are told to turn it on by default ? */ - if (PK11_DefaultArray[i].flag & defaultMechanismFlags) { - /* it ignores if slot attribute update failes */ - result = PK11_UpdateSlotAttribute(slot, &(PK11_DefaultArray[i]), PR_TRUE); - } else { /* turn this mechanism of the slot off by default */ - result = PK11_UpdateSlotAttribute(slot, &(PK11_DefaultArray[i]), PR_FALSE); - } - } /* for each mechanism */ - /* disable each slot if the defaultFlags say so */ - if (defaultMechanismFlags & PK11_DISABLE_FLAG) { - PK11_UserDisableSlot(slot); - } - } /* for each slot of this module */ - - /* delete and re-add module in order to save changes to the module */ - result = SECMOD_UpdateModule(module); - } - } - } - SECMOD_DestroyModule(module); - return result; -} - -SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath, - unsigned long defaultMechanismFlags, - unsigned long cipherEnableFlags) -{ - return SECMOD_AddNewModuleEx(moduleName, dllPath, defaultMechanismFlags, - cipherEnableFlags, - NULL, NULL); /* don't pass module or nss params */ -} - -SECStatus SECMOD_UpdateModule(SECMODModule *module) -{ - SECStatus result; - - result = SECMOD_DeletePermDB(module); - - if (result == SECSuccess) { - result = SECMOD_AddPermDB(module); - } - return result; -} - -/* Public & Internal(Security Library) representation of - * encryption mechanism flags conversion */ - -/* Currently, the only difference is that internal representation - * puts RANDOM_FLAG at bit 31 (Most-significant bit), but - * public representation puts this bit at bit 28 - */ -unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags) { - unsigned long internalFlags = publicFlags; - - if (publicFlags & PUBLIC_MECH_RANDOM_FLAG) { - internalFlags &= ~PUBLIC_MECH_RANDOM_FLAG; - internalFlags |= SECMOD_RANDOM_FLAG; - } - return internalFlags; -} - -unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags) { - unsigned long publicFlags = internalFlags; - - if (internalFlags & SECMOD_RANDOM_FLAG) { - publicFlags &= ~SECMOD_RANDOM_FLAG; - publicFlags |= PUBLIC_MECH_RANDOM_FLAG; - } - return publicFlags; -} - - -/* Public & Internal(Security Library) representation of */ -/* cipher flags conversion */ -/* Note: currently they are just stubs */ -unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags) { - return publicFlags; -} - -unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags) { - return internalFlags; -} - -/* Funtion reports true if module of modType is installed/configured */ -PRBool -SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags ) -{ - PRBool result = PR_FALSE; - SECMODModuleList *mods = SECMOD_GetDefaultModuleList(); - SECMOD_GetReadLock(moduleLock); - - - for ( ; mods != NULL; mods = mods->next) { - if (mods->module->ssl[0] & SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) { - result = PR_TRUE; - } - } - - SECMOD_ReleaseReadLock(moduleLock); - return result; -} - -/* create a new ModuleListElement */ -SECMODModuleList *SECMOD_NewModuleListElement(void) { - SECMODModuleList *newModList; - - newModList= (SECMODModuleList *) PORT_Alloc(sizeof(SECMODModuleList)); - if (newModList) { - newModList->next = NULL; - newModList->module = NULL; - } - return newModList; -} -/* - * make a new reference to a module so It doesn't go away on us - */ -SECMODModule * -SECMOD_ReferenceModule(SECMODModule *module) { - PK11_USE_THREADS(PZ_Lock((PZLock *)module->refLock);) - PORT_Assert(module->refCount > 0); - - module->refCount++; - PK11_USE_THREADS(PZ_Unlock((PZLock*)module->refLock);) - return module; -} - - -/* destroy an existing module */ -void -SECMOD_DestroyModule(SECMODModule *module) { - PRBool willfree = PR_FALSE; - int slotCount; - int i; - - PK11_USE_THREADS(PZ_Lock((PZLock *)module->refLock);) - if (module->refCount-- == 1) { - willfree = PR_TRUE; - } - PORT_Assert(willfree || (module->refCount > 0)); - PK11_USE_THREADS(PZ_Unlock((PZLock *)module->refLock);) - - if (!willfree) { - return; - } - - if (module->parent != NULL) { - SECMODModule *parent = module->parent; - /* paranoia, don't loop forever if the modules are looped */ - module->parent = NULL; - SECMOD_DestroyModule(parent); - } - - /* slots can't really disappear until our module starts freeing them, - * so this check is safe */ - slotCount = module->slotCount; - if (slotCount == 0) { - SECMOD_SlotDestroyModule(module,PR_FALSE); - return; - } - - /* now free all out slots, when they are done, they will cause the - * module to disappear altogether */ - for (i=0 ; i < slotCount; i++) { - if (!module->slots[i]->disabled) { - PK11_ClearSlotList(module->slots[i]); - } - PK11_FreeSlot(module->slots[i]); - } - /* WARNING: once the last slot has been freed is it possible (even likely) - * that module is no more... touching it now is a good way to go south */ -} - - -/* we can only get here if we've destroyed the module, or some one has - * erroneously freed a slot that wasn't referenced. */ -void -SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot) { - PRBool willfree = PR_FALSE; - if (fromSlot) { - PORT_Assert(module->refCount == 0); - PK11_USE_THREADS(PZ_Lock((PZLock *)module->refLock);) - if (module->slotCount-- == 1) { - willfree = PR_TRUE; - } - PORT_Assert(willfree || (module->slotCount > 0)); - PK11_USE_THREADS(PZ_Unlock((PZLock *)module->refLock);) - if (!willfree) return; - } - - if (module == pendingModule) { - pendingModule = NULL; - } - - if (module->loaded) { - SECMOD_UnloadModule(module); - } - PK11_USE_THREADS(PZ_DestroyLock((PZLock *)module->refLock);) - PORT_FreeArena(module->arena,PR_FALSE); - secmod_PrivateModuleCount--; -} - -/* destroy a list element - * this destroys a single element, and returns the next element - * on the chain. It makes it easy to implement for loops to delete - * the chain. It also make deleting a single element easy */ -SECMODModuleList * -SECMOD_DestroyModuleListElement(SECMODModuleList *element) { - SECMODModuleList *next = element->next; - - if (element->module) { - SECMOD_DestroyModule(element->module); - element->module = NULL; - } - PORT_Free(element); - return next; -} - - -/* - * Destroy an entire module list - */ -void -SECMOD_DestroyModuleList(SECMODModuleList *list) { - SECMODModuleList *lp; - - for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ; -} - -PRBool -SECMOD_CanDeleteInternalModule(void) -{ - return (PRBool) pendingModule == NULL; -} diff --git a/security/nss/lib/pk11wrap/secmod.h b/security/nss/lib/pk11wrap/secmod.h deleted file mode 100644 index fd8037e65..000000000 --- a/security/nss/lib/pk11wrap/secmod.h +++ /dev/null @@ -1,153 +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. - * - * Definition of Security Module Data Structure. There is a separate data - * structure for each loaded PKCS #11 module. - */ -#ifndef _SECMOD_H_ -#define _SEDMOD_H_ -#include "seccomon.h" -#include "secmodt.h" - -#define PKCS11_USE_THREADS - -/* These mechanisms flags are visible to all other libraries. */ -/* They must be converted to internal SECMOD_*_FLAG */ -/* if used inside the functions of the security library */ -#define PUBLIC_MECH_RSA_FLAG 0x00000001ul -#define PUBLIC_MECH_DSA_FLAG 0x00000002ul -#define PUBLIC_MECH_RC2_FLAG 0x00000004ul -#define PUBLIC_MECH_RC4_FLAG 0x00000008ul -#define PUBLIC_MECH_DES_FLAG 0x00000010ul -#define PUBLIC_MECH_DH_FLAG 0x00000020ul -#define PUBLIC_MECH_FORTEZZA_FLAG 0x00000040ul -#define PUBLIC_MECH_RC5_FLAG 0x00000080ul -#define PUBLIC_MECH_SHA1_FLAG 0x00000100ul -#define PUBLIC_MECH_MD5_FLAG 0x00000200ul -#define PUBLIC_MECH_MD2_FLAG 0x00000400ul -#define PUBLIC_MECH_SSL_FLAG 0x00000800ul -#define PUBLIC_MECH_TLS_FLAG 0x00001000ul - -#define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul -#define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul -#define PUBLIC_OWN_PW_DEFAULTS 0X20000000ul -#define PUBLIC_DISABLE_FLAG 0x40000000ul - -/* warning: reserved means reserved */ -#define PUBLIC_MECH_RESERVED_FLAGS 0x87FFE000ul - -/* These cipher flags are visible to all other libraries, */ -/* But they must be converted before used in functions */ -/* withing the security module */ -#define PUBLIC_CIPHER_FORTEZZA_FLAG 0x00000001ul - -/* warning: reserved means reserved */ -#define PUBLIC_CIPHER_RESERVED_FLAGS 0xFFFFFFFEul - -SEC_BEGIN_PROTOS - -/* - * the following functions are going to be depricated in NSS 4.0 in - * favor of the new stan functions. - */ - -/* Initialization */ -extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent, - PRBool recurse); - -extern SECMODModule *SECMOD_LoadUserModule(char *moduleSpec,SECMODModule *parent, - PRBool recurse); - -SECStatus SECMOD_UnloadUserModule(SECMODModule *mod); - -SECMODModule * SECMOD_CreateModule(char *lib, char *name, char *param, - char *nss); -extern SECStatus SECMOD_Shutdown(void); -void nss_DumpModuleLog(void); - - -/* Module Management */ -char **SECMOD_GetModuleSpecList(SECMODModule *module); -SECStatus SECMOD_FreeModuleSpecList(SECMODModule *module,char **moduleSpecList); - - -/* protoypes */ -extern SECMODModuleList *SECMOD_GetDefaultModuleList(void); -extern SECMODListLock *SECMOD_GetDefaultModuleListLock(void); - -extern SECStatus SECMOD_UpdateModule(SECMODModule *module); - -/* lock management */ -extern SECMODListLock *SECMOD_NewListLock(void); -extern void SECMOD_DestroyListLock(SECMODListLock *); -extern void SECMOD_GetReadLock(SECMODListLock *); -extern void SECMOD_ReleaseReadLock(SECMODListLock *); -extern void SECMOD_GetWriteLock(SECMODListLock *); -extern void SECMOD_ReleaseWriteLock(SECMODListLock *); - -/* Operate on modules by name */ -extern SECMODModule *SECMOD_FindModule(char *name); -extern SECStatus SECMOD_DeleteModule(char *name, int *type); -extern SECStatus SECMOD_DeleteInternalModule(char *name); -extern PRBool SECMOD_CanDeleteInternalModule(void); -extern SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath, - unsigned long defaultMechanismFlags, - unsigned long cipherEnableFlags); -extern SECStatus SECMOD_AddNewModuleEx(char* moduleName, char* dllPath, - unsigned long defaultMechanismFlags, - unsigned long cipherEnableFlags, - char* modparms, - char* nssparms); - -/* database/memory management */ -extern SECMODModule *SECMOD_GetInternalModule(void); -extern SECMODModule *SECMOD_ReferenceModule(SECMODModule *module); -extern void SECMOD_DestroyModule(SECMODModule *module); -extern PK11SlotInfo *SECMOD_LookupSlot(SECMODModuleID module, - unsigned long slotID); -extern PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,char *name); - -/* Funtion reports true if at least one of the modules */ -/* of modType has been installed */ -PRBool SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags ); - -/* Functions used to convert between internal & public representation - * of Mechanism Flags and Cipher Enable Flags */ -extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags); -extern unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags); - -extern unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags); -extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags); - -SEC_END_PROTOS - -#endif diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h deleted file mode 100644 index 050f7de4f..000000000 --- a/security/nss/lib/pk11wrap/secmodi.h +++ /dev/null @@ -1,113 +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. - */ -/* - * Internal header file included only by files in pkcs11 dir, or in - * pkcs11 specific client and server files. - */ -#ifndef _SECMODI_H_ -#define _SECMODI_H_ 1 -#include "pkcs11.h" -#include "nssilock.h" -#include "mcom_db.h" -#include "secoidt.h" -#include "secdert.h" -#include "certt.h" -#include "secmodt.h" -#include "secmodti.h" - -#ifdef PKCS11_USE_THREADS -#define PK11_USE_THREADS(x) x -#else -#define PK11_USE_THREADS(x) -#endif - -SEC_BEGIN_PROTOS - -/* proto-types */ -extern SECStatus SECMOD_DeletePermDB(SECMODModule *module); -extern SECStatus SECMOD_AddPermDB(SECMODModule *module); - -extern int secmod_PrivateModuleCount; - -extern void SECMOD_Init(void); - -/* list managment */ -extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule); -extern SECStatus SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule); -extern SECStatus SECMOD_AddModuleToUnloadList(SECMODModule *newModule); -extern void SECMOD_RemoveList(SECMODModuleList **,SECMODModuleList *); -extern void SECMOD_AddList(SECMODModuleList *,SECMODModuleList *,SECMODListLock *); - -/* Operate on modules by name */ -extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID); - -/* database/memory management */ -extern SECMODModuleList *SECMOD_NewModuleListElement(void); -extern SECMODModuleList *SECMOD_DestroyModuleListElement(SECMODModuleList *); -extern void SECMOD_DestroyModuleList(SECMODModuleList *); -extern SECStatus SECMOD_AddModule(SECMODModule *newModule); -SECStatus SECMOD_DeleteModuleEx(char * name, SECMODModule *mod, int *type, PRBool permdb); - -extern unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags); -extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags); - -/* Library functions */ -SECStatus SECMOD_LoadPKCS11Module(SECMODModule *); -SECStatus SECMOD_UnloadModule(SECMODModule *); -void SECMOD_SetInternalModule(SECMODModule *); - -void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot); -CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event, - CK_VOID_PTR pdata); -void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib); -CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot, - CK_ATTRIBUTE *inTemplate,int tsize); -CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot, - CK_ATTRIBUTE *inTemplate,int tsize, int *objCount); -SECStatus PK11_UpdateSlotAttribute(PK11SlotInfo *slot, - PK11DefaultArrayEntry *entry, PRBool add); - -#define PK11_GETTAB(x) ((CK_FUNCTION_LIST_PTR)((x)->functionList)) -#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ - (x)->pValue=(v); (x)->ulValueLen = (l); -SECStatus PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session, - CK_ATTRIBUTE *theTemplate, int count, - PRBool token, CK_OBJECT_HANDLE *objectID); - -SECStatus pbe_PK11AlgidToParam(SECAlgorithmID *algid,SECItem *mech); -SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, - PRArenaPool *arena, SECAlgorithmID *algId); -SEC_END_PROTOS - -#endif - diff --git a/security/nss/lib/pk11wrap/secmodt.h b/security/nss/lib/pk11wrap/secmodt.h deleted file mode 100644 index b83f57d63..000000000 --- a/security/nss/lib/pk11wrap/secmodt.h +++ /dev/null @@ -1,248 +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. - * - * Definition of Security Module Data Structure. There is a separate data - * structure for each loaded PKCS #11 module. - */ -#ifndef _SECMODT_H_ -#define _SECMODT_H_ 1 - -#include "secoid.h" -#include "secasn1.h" - -/* find a better home for these... */ -extern const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[]; -extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_PointerToEncryptedPrivateKeyInfoTemplate; -extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[]; -extern const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[]; -extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_PrivateKeyInfoTemplate; -extern const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[]; -extern SEC_ASN1TemplateChooser NSS_Get_SECKEY_PointerToPrivateKeyInfoTemplate; - -/* PKCS11 needs to be included */ -typedef struct SECMODModuleStr SECMODModule; -typedef struct SECMODModuleListStr SECMODModuleList; -typedef struct SECMODListLockStr SECMODListLock; /* defined in secmodi.h */ -typedef struct PK11SlotInfoStr PK11SlotInfo; /* defined in secmodti.h */ -typedef struct PK11PreSlotInfoStr PK11PreSlotInfo; /* defined in secmodti.h */ -typedef struct PK11SymKeyStr PK11SymKey; /* defined in secmodti.h */ -typedef struct PK11ContextStr PK11Context; /* defined in secmodti.h */ -typedef struct PK11SlotListStr PK11SlotList; -typedef struct PK11SlotListElementStr PK11SlotListElement; -typedef struct PK11RSAGenParamsStr PK11RSAGenParams; -typedef unsigned long SECMODModuleID; -typedef struct PK11DefaultArrayEntryStr PK11DefaultArrayEntry; - -struct SECMODModuleStr { - PRArenaPool *arena; - PRBool internal; /* true of internally linked modules, false - * for the loaded modules */ - PRBool loaded; /* Set to true if module has been loaded */ - PRBool isFIPS; /* Set to true if module is finst internal */ - char *dllName; /* name of the shared library which implements - * this module */ - char *commonName; /* name of the module to display to the user */ - void *library; /* pointer to the library. opaque. used only by - * pk11load.c */ - void *functionList; /* The PKCS #11 function table */ - void *refLock; /* only used pk11db.c */ - int refCount; /* Module reference count */ - PK11SlotInfo **slots; /* array of slot points attatched to this mod*/ - int slotCount; /* count of slot in above array */ - PK11PreSlotInfo *slotInfo; /* special info about slots default settings */ - int slotInfoCount; /* count */ - SECMODModuleID moduleID; /* ID so we can find this module again */ - PRBool isThreadSafe; - unsigned long ssl[2]; /* SSL cipher enable flags */ - char *libraryParams; /* Module specific parameters */ - void *moduleDBFunc; /* function to return module configuration data*/ - SECMODModule *parent; /* module that loaded us */ - PRBool isCritical; /* This module must load successfully */ - PRBool isModuleDB; /* this module has lists of PKCS #11 modules */ - PRBool moduleDBOnly; /* this module only has lists of PKCS #11 modules */ - int trustOrder; /* order for this module's certificate trust rollup */ - int cipherOrder; /* order for cipher operations */ -}; - -struct SECMODModuleListStr { - SECMODModuleList *next; - SECMODModule *module; -}; - -struct PK11SlotListStr { - PK11SlotListElement *head; - PK11SlotListElement *tail; - void *lock; -}; - -struct PK11SlotListElementStr { - PK11SlotListElement *next; - PK11SlotListElement *prev; - PK11SlotInfo *slot; - int refCount; -}; - -struct PK11RSAGenParamsStr { - int keySizeInBits; - unsigned long pe; -}; - -typedef enum { - PK11CertListUnique = 0, - PK11CertListUser = 1, - PK11CertListRootUnique = 2, - PK11CertListCA = 3 -} PK11CertListType; - -/* - * Entry into the Array which lists all the legal bits for the default flags - * in the slot, their definition, and the PKCS #11 mechanism the represent - * Always Statically allocated. - */ -struct PK11DefaultArrayEntryStr { - char *name; - unsigned long flag; - unsigned long mechanism; /* this is a long so we don't include the - * whole pkcs 11 world to use this header */ -}; - - -#define SECMOD_RSA_FLAG 0x00000001L -#define SECMOD_DSA_FLAG 0x00000002L -#define SECMOD_RC2_FLAG 0x00000004L -#define SECMOD_RC4_FLAG 0x00000008L -#define SECMOD_DES_FLAG 0x00000010L -#define SECMOD_DH_FLAG 0x00000020L -#define SECMOD_FORTEZZA_FLAG 0x00000040L -#define SECMOD_RC5_FLAG 0x00000080L -#define SECMOD_SHA1_FLAG 0x00000100L -#define SECMOD_MD5_FLAG 0x00000200L -#define SECMOD_MD2_FLAG 0x00000400L -#define SECMOD_SSL_FLAG 0x00000800L -#define SECMOD_TLS_FLAG 0x00001000L -#define SECMOD_AES_FLAG 0x00002000L -/* reserved bit for future, do not use */ -#define SECMOD_RESERVED_FLAG 0X08000000L -#define SECMOD_FRIENDLY_FLAG 0x10000000L -#define SECMOD_RANDOM_FLAG 0x80000000L - -/* need to make SECMOD and PK11 prefixes consistant. */ -#define PK11_OWN_PW_DEFAULTS 0x20000000L -#define PK11_DISABLE_FLAG 0x40000000L - -/* FAKE PKCS #11 defines */ -#define CKM_FAKE_RANDOM 0x80000efeL -#define CKM_INVALID_MECHANISM 0xffffffffL -#define CKA_DIGEST 0x81000000L - -/* Cryptographic module types */ -#define SECMOD_EXTERNAL 0 /* external module */ -#define SECMOD_INTERNAL 1 /* internal default module */ -#define SECMOD_FIPS 2 /* internal fips module */ - -/* default module configuration strings */ -#define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES]" - -#define SECMOD_MAKE_NSS_FLAGS(fips,slot) \ -"Flags=internal,critical"fips" slotparams=("#slot"={"SECMOD_SLOT_FLAGS"})" - -#define SECMOD_INT_NAME "NSS Internal PKCS #11 Module" -#define SECMOD_INT_FLAGS SECMOD_MAKE_NSS_FLAGS("",1) -#define SECMOD_FIPS_NAME "NSS Internal FIPS PKCS #11 Module" -#define SECMOD_FIPS_FLAGS SECMOD_MAKE_NSS_FLAGS(",fips",3) - - -/* - * What is the origin of a given Key. Normally this doesn't matter, but - * the fortezza code needs to know if it needs to invoke the SSL3 fortezza - * hack. - */ -typedef enum { - PK11_OriginNULL = 0, /* There is not key, it's a null SymKey */ - PK11_OriginDerive = 1, /* Key was derived from some other key */ - PK11_OriginGenerated = 2, /* Key was generated (also PBE keys) */ - PK11_OriginFortezzaHack = 3,/* Key was marked for fortezza hack */ - PK11_OriginUnwrap = 4 /* Key was unwrapped or decrypted */ -} PK11Origin; - -/* PKCS #11 disable reasons */ -typedef enum { - PK11_DIS_NONE = 0, - PK11_DIS_USER_SELECTED = 1, - PK11_DIS_COULD_NOT_INIT_TOKEN = 2, - PK11_DIS_TOKEN_VERIFY_FAILED = 3, - PK11_DIS_TOKEN_NOT_PRESENT = 4 -} PK11DisableReasons; - -/* function pointer type for password callback function. - * This type is passed in to PK11_SetPasswordFunc() - */ -typedef char *(PR_CALLBACK *PK11PasswordFunc)(PK11SlotInfo *slot, PRBool retry, void *arg); -typedef PRBool (PR_CALLBACK *PK11VerifyPasswordFunc)(PK11SlotInfo *slot, void *arg); -typedef PRBool (PR_CALLBACK *PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg); - -/* - * PKCS #11 key structures - */ - -/* -** Attributes -*/ -struct SECKEYAttributeStr { - SECItem attrType; - SECItem **attrValue; -}; -typedef struct SECKEYAttributeStr SECKEYAttribute; - -/* -** A PKCS#8 private key info object -*/ -struct SECKEYPrivateKeyInfoStr { - PLArenaPool *arena; - SECItem version; - SECAlgorithmID algorithm; - SECItem privateKey; - SECKEYAttribute **attributes; -}; -typedef struct SECKEYPrivateKeyInfoStr SECKEYPrivateKeyInfo; - -/* -** A PKCS#8 private key info object -*/ -struct SECKEYEncryptedPrivateKeyInfoStr { - PLArenaPool *arena; - SECAlgorithmID algorithm; - SECItem encryptedData; -}; -typedef struct SECKEYEncryptedPrivateKeyInfoStr SECKEYEncryptedPrivateKeyInfo; - -#endif /*_SECMODT_H_ */ diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h deleted file mode 100644 index af7cc32e7..000000000 --- a/security/nss/lib/pk11wrap/secmodti.h +++ /dev/null @@ -1,190 +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. - */ -/* - * Internal header file included only by files in pkcs11 dir, or in - * pkcs11 specific client and server files. - */ - -#ifndef _SECMODTI_H_ -#define _SECMODTI_H_ 1 -#include "prmon.h" -#include "prtypes.h" -#include "nssilckt.h" -#include "pk11init.h" - -#ifndef NSS_3_4_CODE -#define NSS_3_4_CODE -#endif /* NSS_3_4_CODE */ -#include "nssdevt.h" - -/* internal data structures */ - -/* structure to allow us to implement the read/write locks for our - * module lists */ -struct SECMODListLockStr { - PZLock *mutex; /*general mutex to protect this data structure*/ - PZMonitor *monitor; /* monitor to allow us to signal */ - int state; /* read/write/waiting state */ - int count; /* how many waiters on this lock */ -}; - -/* represent a pkcs#11 slot reference counted. */ -struct PK11SlotInfoStr { - /* the PKCS11 function list for this slot */ - void *functionList; - SECMODModule *module; /* our parent module */ - /* Boolean to indicate the current state of this slot */ - PRBool needTest; /* Has this slot been tested for Export complience */ - PRBool isPerm; /* is this slot a permanment device */ - PRBool isHW; /* is this slot a hardware device */ - PRBool isInternal; /* is this slot one of our internal PKCS #11 devices */ - PRBool disabled; /* is this slot disabled... */ - PK11DisableReasons reason; /* Why this slot is disabled */ - PRBool readOnly; /* is the token in this slot read-only */ - PRBool needLogin; /* does the token of the type that needs - * authentication (still true even if token is logged - * in) */ - PRBool hasRandom; /* can this token generated random numbers */ - PRBool defRWSession; /* is the default session RW (we open our default - * session rw if the token can only handle one session - * at a time. */ - PRBool isThreadSafe; /* copied from the module */ - /* The actual flags (many of which are distilled into the above PRBools) */ - CK_FLAGS flags; /* flags from PKCS #11 token Info */ - /* a default session handle to do quick and dirty functions */ - CK_SESSION_HANDLE session; - PZLock *sessionLock; /* lock for this session */ - /* our ID */ - CK_SLOT_ID slotID; - /* persistant flags saved from startup to startup */ - unsigned long defaultFlags; - /* keep track of who is using us so we don't accidently get freed while - * still in use */ - int refCount; - PZLock *refLock; - PZLock *freeListLock; - PK11SymKey *freeSymKeysHead; - int keyCount; - int maxKeyCount; - /* Password control functions for this slot. many of these are only - * active if the appropriate flag is on in defaultFlags */ - int askpw; /* what our password options are */ - int timeout; /* If we're ask_timeout, what is our timeout time is - * seconds */ - int authTransact; /* allow multiple authentications off one password if - * they are all part of the same transaction */ - int64 authTime; /* when were we last authenticated */ - int minPassword; /* smallest legal password */ - int maxPassword; /* largest legal password */ - uint16 series; /* break up the slot info into various groups of - * inserted tokens so that keys and certs can be - * invalidated */ - uint16 wrapKey; /* current wrapping key for SSL master secrets */ - CK_MECHANISM_TYPE wrapMechanism; - /* current wrapping mechanism for current wrapKey */ - CK_OBJECT_HANDLE refKeys[1]; /* array of existing wrapping keys for */ - CK_MECHANISM_TYPE *mechanismList; /* list of mechanism supported by this - * token */ - int mechanismCount; - /* cache the certificates stored on the token of this slot */ - CERTCertificate **cert_array; - int array_size; - int cert_count; - char serial[16]; - /* since these are odd sizes, keep them last. They are odd sizes to - * allow them to become null terminated strings */ - char slot_name[65]; - char token_name[33]; - PRBool hasRootCerts; - PRBool hasRootTrust; - PRBool hasRSAInfo; - CK_FLAGS RSAInfoFlags; - PRBool protectedAuthPath; - PRBool isActiveCard; - PRIntervalTime lastLoginCheck; - unsigned int lastState; - /* for Stan */ - NSSToken *nssToken; -}; - -/* Symetric Key structure. Reference Counted */ -struct PK11SymKeyStr { - CK_MECHANISM_TYPE type; /* type of operation this key was created for*/ - CK_OBJECT_HANDLE objectID; /* object id of this key in the slot */ - PK11SlotInfo *slot; /* Slot this key is loaded into */ - void *cx; /* window context in case we need to loggin */ - PK11SymKey *next; - PRBool owner; - SECItem data; /* raw key data if available */ - CK_SESSION_HANDLE session; - PRBool sessionOwner; - PRInt32 refCount; /* number of references to this key */ - int size; /* key size in bytes */ - PK11Origin origin; /* where this key came from - (see def in secmodt.h) */ - uint16 series; /* break up the slot info into various groups of - * inserted tokens so that keys and certs can be - * invalidated */ -}; - - -/* - * hold a hash, encryption or signing context for multi-part operations. - * hold enough information so that multiple contexts can be interleaved - * if necessary. ... Not RefCounted. - */ -struct PK11ContextStr { - CK_ATTRIBUTE_TYPE operation; /* type of operation this context is doing - * (CKA_ENCRYPT, CKA_SIGN, CKA_HASH, etc. */ - PK11SymKey *key; /* symetric key used in this context */ - PK11SlotInfo *slot; /* slot this context is operationing on */ - CK_SESSION_HANDLE session; /* session this context is using */ - PZLock *sessionLock; /* lock before accessing a PKCS #11 - * session */ - PRBool ownSession;/* do we own the session? */ - void *cx; /* window context in case we need to loggin*/ - void *savedData;/* save data when we are multiplexing on a - * single context */ - unsigned long savedLength; /* length of the saved context */ - SECItem *param; /* mechanism parameters used to build this - context */ - PRBool init; /* has this contexted been initialized */ - CK_MECHANISM_TYPE type; /* what is the PKCS #11 this context is - * representing (usually what algorithm is - * being used (CKM_RSA_PKCS, CKM_DES, - * CKM_SHA, etc.*/ - PRBool fortezzaHack; /*Fortezza SSL has some special - * non-standard semantics*/ -}; - -#endif /* _SECMODTI_H_ */ diff --git a/security/nss/lib/pk11wrap/secpkcs5.h b/security/nss/lib/pk11wrap/secpkcs5.h deleted file mode 100644 index 1ace06c10..000000000 --- a/security/nss/lib/pk11wrap/secpkcs5.h +++ /dev/null @@ -1,71 +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 _SECPKS5_H_ -#define _SECPKCS5_H_ -#include "seccomon.h" -#include "secmodt.h" - -/* used for V2 PKCS 12 Draft Spec */ -typedef enum { - pbeBitGenIDNull = 0, - pbeBitGenCipherKey = 0x01, - pbeBitGenCipherIV = 0x02, - pbeBitGenIntegrityKey = 0x03 -} PBEBitGenID; - -typedef struct PBEBitGenContextStr PBEBitGenContext; - -SEC_BEGIN_PROTOS - -SECAlgorithmID * -SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm, SECItem *salt, int iteration); - -/* Get the initialization vector. The password is passed in, hashing - * is performed, and the initialization vector is returned. - * algid is a pointer to a PBE algorithm ID - * pwitem is the password - * If an error occurs or the algorithm id is not a PBE algrithm, - * NULL is returned. Otherwise, the iv is returned in a secitem. - */ -SECItem * -SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES); - -SECOidTag SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid); -PRBool SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid); -SECOidTag SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen); -int SEC_PKCS5GetKeyLength(SECAlgorithmID *algid); - -SEC_END_PROTOS - -#endif /* _SECPKS5_H_ */ diff --git a/security/nss/lib/cryptohi/hasht.h b/security/nss/lib/softoken/hasht.h index 143e37486..852ee706e 100644 --- a/security/nss/lib/cryptohi/hasht.h +++ b/security/nss/lib/softoken/hasht.h @@ -47,10 +47,13 @@ typedef struct HASHContextStr HASHContext; * NOTE the order must match the definition of SECHashObjects[]! */ typedef enum { - HASH_AlgNULL = 0, - HASH_AlgMD2 = 1, - HASH_AlgMD5 = 2, - HASH_AlgSHA1 = 3, + HASH_AlgNULL = 0, + HASH_AlgMD2 = 1, + HASH_AlgMD5 = 2, + HASH_AlgSHA1 = 3, + HASH_AlgSHA256 = 4, + HASH_AlgSHA384 = 5, + HASH_AlgSHA512 = 6, HASH_AlgTOTAL } HASH_HashType; @@ -60,6 +63,10 @@ typedef enum { #define MD2_LENGTH 16 #define MD5_LENGTH 16 #define SHA1_LENGTH 20 +#define SHA256_LENGTH 32 +#define SHA384_LENGTH 48 +#define SHA512_LENGTH 64 +#define HASH_LENGTH_MAX SHA512_LENGTH /* * Structure to hold hash computation info and routines diff --git a/security/nss/lib/cryptohi/sechash.h b/security/nss/lib/softoken/sechash.h index 0e5a92e3b..6bcbd5144 100644 --- a/security/nss/lib/cryptohi/sechash.h +++ b/security/nss/lib/softoken/sechash.h @@ -39,6 +39,7 @@ #include "seccomon.h" #include "hasht.h" +#include "secoidt.h" SEC_BEGIN_PROTOS @@ -50,6 +51,8 @@ extern unsigned int HASH_ResultLen(HASH_HashType type); extern unsigned int HASH_ResultLenContext(HASHContext *context); +extern unsigned int HASH_ResultLenByOidTag(SECOidTag hashOid); + extern SECStatus HASH_HashBuf(HASH_HashType type, unsigned char *dest, unsigned char *src, @@ -74,6 +77,10 @@ extern void HASH_End(HASHContext *context, extern const SECHashObject * HASH_GetHashObject(HASH_HashType type); +extern const SECHashObject * HASH_GetHashObjectByOidTag(SECOidTag hashOid); + +extern HASH_HashType HASH_GetHashTypeByOidTag(SECOidTag hashOid); + SEC_END_PROTOS #endif /* _HASH_H_ */ diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c index 179105488..10471106a 100644 --- a/security/nss/lib/util/secoid.c +++ b/security/nss/lib/util/secoid.c @@ -33,11 +33,15 @@ #include "secoid.h" #include "pkcs11t.h" -#include "secmodt.h" #include "secitem.h" #include "secerr.h" #include "plhash.h" +/* XXX from secmodt.h */ +#ifndef CKM_INVALID_MECHANISM +#define CKM_INVALID_MECHANISM 0xffffffffL +#endif /* CKM_INVALID_MECHANISM */ + /* MISSI Mosaic Object ID space */ #define USGOV 0x60, 0x86, 0x48, 0x01, 0x65 #define MISSI USGOV, 0x02, 0x01, 0x01 diff --git a/security/nss/lib/util/sectime.c b/security/nss/lib/util/sectime.c index d3cca6f87..d7cbabf43 100644 --- a/security/nss/lib/util/sectime.c +++ b/security/nss/lib/util/sectime.c @@ -34,8 +34,19 @@ #include "prlong.h" #include "prtime.h" #include "secder.h" -#include "cert.h" #include "secitem.h" +#include "secasn1.h" + +/* XXX from certt.h */ +/* +** An X.509 validity object +*/ +struct CERTValidityStr { + PRArenaPool *arena; + SECItem notBefore; + SECItem notAfter; +}; +typedef struct CERTValidityStr CERTValidity; const SEC_ASN1Template CERT_ValidityTemplate[] = { { SEC_ASN1_SEQUENCE, |