diff options
author | cvs2hg <devnull@localhost> | 2009-04-01 00:49:49 +0000 |
---|---|---|
committer | cvs2hg <devnull@localhost> | 2009-04-01 00:49:49 +0000 |
commit | 1748aed17b85aca2423114fea4558305d9116459 (patch) | |
tree | 91994935aaeb77e63515562c53024da0113c5d20 /security/nss/lib/softoken | |
parent | 130da2a8212388f0bdfc9fd9f263697e9bdd21d1 (diff) | |
download | nss-hg-1748aed17b85aca2423114fea4558305d9116459.tar.gz |
fixup commit for tag 'JSS_4_3_RTM'JSS_4_3_RTM
Diffstat (limited to 'security/nss/lib/softoken')
65 files changed, 0 insertions, 49813 deletions
diff --git a/security/nss/lib/softoken/Makefile b/security/nss/lib/softoken/Makefile deleted file mode 100644 index c7f7b2a33..000000000 --- a/security/nss/lib/softoken/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -#! gmake -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -####################################################################### -# (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) # -####################################################################### - -ifdef NSS_DISABLE_DBM -DIRS= dummy -endif - -####################################################################### -# (7) Execute "local" rules. (OPTIONAL). # -####################################################################### - -export:: private_export - -# indicates dependency on freebl static lib -$(SHARED_LIBRARY): $(CRYPTOLIB) - -# On AIX 4.3, IBM xlC_r compiler (version 3.6.6) cannot compile -# pkcs11c.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)/pkcs11.o: pkcs11.c - @$(MAKE_OBJDIR) - $(CC) -o $@ -c -O2 $(CFLAGS) $< -$(OBJDIR)/pkcs11c.o: pkcs11c.c - @$(MAKE_OBJDIR) - $(CC) -o $@ -c -O2 $(CFLAGS) $< -endif -endif -endif diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk deleted file mode 100644 index 7dddd3467..000000000 --- a/security/nss/lib/softoken/config.mk +++ /dev/null @@ -1,119 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS) -CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) -CRYPTODIR=../freebl -ifdef MOZILLA_SECURITY_BUILD - CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)crypto.$(LIB_SUFFIX) - CRYPTODIR=../crypto -endif - -EXTRA_LIBS += \ - $(CRYPTOLIB) \ - $(NULL) - -# can't do this in manifest.mn because OS_TARGET isn't defined there. -ifeq (,$(filter-out WIN%,$(OS_TARGET))) - -# don't want the 32 in the shared library name -SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) -IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX) - -RES = $(OBJDIR)/$(LIBRARY_NAME).res -RESNAME = $(LIBRARY_NAME).rc - -ifdef NS_USE_GCC -EXTRA_SHARED_LIBS += \ - -L$(DIST)/lib \ - -lnssutil3 \ - -lsqlite3 \ - -L$(NSPR_LIB_DIR) \ - -lplc4 \ - -lplds4 \ - -lnspr4 \ - $(NULL) -else # ! NS_USE_GCC - -EXTRA_SHARED_LIBS += \ - $(DIST)/lib/sqlite3.lib \ - $(DIST)/lib/nssutil3.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \ - $(DIST)/lib/nssutil3.lib \ - $(NULL) -endif # NS_USE_GCC - -else - -# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS) -# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX. -EXTRA_SHARED_LIBS += \ - -L$(DIST)/lib \ - -lnssutil3 \ - -lsqlite3 \ - -L$(NSPR_LIB_DIR) \ - -lplc4 \ - -lplds4 \ - -lnspr4 \ - $(NULL) -endif - -ifeq ($(OS_TARGET),AIX) -OS_LIBS += -lpthread -endif - -ifeq ($(OS_TARGET),SunOS) -# The -R '$ORIGIN' linker option instructs this library to search for its -# dependencies in the same directory where it resides. -MKSHLIB += -R '$$ORIGIN' -OS_LIBS += -lbsm -endif - -ifeq ($(OS_ARCH), HP-UX) -ifneq ($(OS_TEST), ia64) -# pa-risc -ifeq ($(USE_64), 1) -MKSHLIB += +b '$$ORIGIN' -endif -endif -endif - -ifeq ($(OS_TARGET),WINCE) -DEFINES += -DDBM_USING_NSPR -endif diff --git a/security/nss/lib/softoken/ecdecode.c b/security/nss/lib/softoken/ecdecode.c deleted file mode 100644 index c037dc519..000000000 --- a/security/nss/lib/softoken/ecdecode.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 Elliptic Curve Cryptography library. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com> and - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifdef NSS_ENABLE_ECC - -#include "blapi.h" -#include "secoid.h" -#include "secitem.h" -#include "secerr.h" -#include "ec.h" -#include "ecl-curve.h" - -#define CHECK_OK(func) if (func == NULL) goto cleanup -#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup - -/* - * Initializes a SECItem from a hexadecimal string - * - * Warning: This function ignores leading 00's, so any leading 00's - * in the hexadecimal string must be optional. - */ -static SECItem * -hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str) -{ - int i = 0; - int byteval = 0; - int tmp = PORT_Strlen(str); - - if ((tmp % 2) != 0) return NULL; - - /* skip leading 00's unless the hex string is "00" */ - while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { - str += 2; - tmp -= 2; - } - - item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2); - if (item->data == NULL) return NULL; - item->len = tmp/2; - - while (str[i]) { - if ((str[i] >= '0') && (str[i] <= '9')) - tmp = str[i] - '0'; - else if ((str[i] >= 'a') && (str[i] <= 'f')) - tmp = str[i] - 'a' + 10; - else if ((str[i] >= 'A') && (str[i] <= 'F')) - tmp = str[i] - 'A' + 10; - else - return NULL; - - byteval = byteval * 16 + tmp; - if ((i % 2) != 0) { - item->data[i/2] = byteval; - byteval = 0; - } - i++; - } - - return item; -} - -/* Copy all of the fields from srcParams into dstParams - */ -SECStatus -EC_CopyParams(PRArenaPool *arena, ECParams *dstParams, - const ECParams *srcParams) -{ - SECStatus rv = SECFailure; - - dstParams->arena = arena; - dstParams->type = srcParams->type; - dstParams->fieldID.size = srcParams->fieldID.size; - dstParams->fieldID.type = srcParams->fieldID.type; - if (srcParams->fieldID.type == ec_field_GFp) { - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime, - &srcParams->fieldID.u.prime)); - } else { - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.poly, - &srcParams->fieldID.u.poly)); - } - dstParams->fieldID.k1 = srcParams->fieldID.k1; - dstParams->fieldID.k2 = srcParams->fieldID.k2; - dstParams->fieldID.k3 = srcParams->fieldID.k3; - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.a, - &srcParams->curve.a)); - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.b, - &srcParams->curve.b)); - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.seed, - &srcParams->curve.seed)); - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->base, - &srcParams->base)); - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->order, - &srcParams->order)); - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->DEREncoding, - &srcParams->DEREncoding)); - dstParams->name = srcParams->name; - CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curveOID, - &srcParams->curveOID)); - dstParams->cofactor = srcParams->cofactor; - - return SECSuccess; - -cleanup: - return SECFailure; -} - -static SECStatus -gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params) -{ - SECStatus rv = SECFailure; - const ECCurveParams *curveParams; - /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */ - char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; - - if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup; - params->name = name; - curveParams = ecCurve_map[params->name]; - CHECK_OK(curveParams); - params->fieldID.size = curveParams->size; - params->fieldID.type = field_type; - if (field_type == ec_field_GFp) { - CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.prime, - curveParams->irr)); - } else { - CHECK_OK(hexString2SECItem(params->arena, ¶ms->fieldID.u.poly, - curveParams->irr)); - } - CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.a, - curveParams->curvea)); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->curve.b, - curveParams->curveb)); - genenc[0] = '0'; - genenc[1] = '4'; - genenc[2] = '\0'; - strcat(genenc, curveParams->genx); - strcat(genenc, curveParams->geny); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->base, genenc)); - CHECK_OK(hexString2SECItem(params->arena, ¶ms->order, - curveParams->order)); - params->cofactor = curveParams->cofactor; - - rv = SECSuccess; - -cleanup: - return rv; -} - -SECStatus -EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams, - ECParams *params) -{ - SECStatus rv = SECFailure; - SECOidTag tag; - SECItem oid = { siBuffer, NULL, 0}; - -#if EC_DEBUG - int i; - - printf("Encoded params in EC_DecodeParams: "); - for (i = 0; i < encodedParams->len; i++) { - printf("%02x:", encodedParams->data[i]); - } - printf("\n"); -#endif - - if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) && - (encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) { - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); - return SECFailure; - }; - - oid.len = encodedParams->len - 2; - oid.data = encodedParams->data + 2; - if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) || - ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) { - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); - return SECFailure; - } - - params->arena = arena; - params->cofactor = 0; - params->type = ec_params_named; - params->name = ECCurve_noName; - - /* For named curves, fill out curveOID */ - params->curveOID.len = oid.len; - params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len); - if (params->curveOID.data == NULL) goto cleanup; - memcpy(params->curveOID.data, oid.data, oid.len); - -#if EC_DEBUG - printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag)); -#endif - - switch (tag) { - - /* Binary curves */ - - case SEC_OID_ANSIX962_EC_C2PNB163V1: - /* Populate params for c2pnb163v1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2PNB163V2: - /* Populate params for c2pnb163v2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2PNB163V3: - /* Populate params for c2pnb163v3 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2PNB176V1: - /* Populate params for c2pnb176v1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB191V1: - /* Populate params for c2tnb191v1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB191V2: - /* Populate params for c2tnb191v2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB191V3: - /* Populate params for c2tnb191v3 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2PNB208W1: - /* Populate params for c2pnb208w1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB239V1: - /* Populate params for c2tnb239v1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB239V2: - /* Populate params for c2tnb239v2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB239V3: - /* Populate params for c2tnb239v3 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2PNB272W1: - /* Populate params for c2pnb272w1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2PNB304W1: - /* Populate params for c2pnb304w1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB359V1: - /* Populate params for c2tnb359v1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2PNB368W1: - /* Populate params for c2pnb368w1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_ANSIX962_EC_C2TNB431R1: - /* Populate params for c2tnb431r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT113R1: - /* Populate params for sect113r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT113R2: - /* Populate params for sect113r2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT131R1: - /* Populate params for sect131r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT131R2: - /* Populate params for sect131r2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT163K1: - /* Populate params for sect163k1 - * (the NIST K-163 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT163R1: - /* Populate params for sect163r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT163R2: - /* Populate params for sect163r2 - * (the NIST B-163 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT193R1: - /* Populate params for sect193r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT193R2: - /* Populate params for sect193r2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT233K1: - /* Populate params for sect233k1 - * (the NIST K-233 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT233R1: - /* Populate params for sect233r1 - * (the NIST B-233 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT239K1: - /* Populate params for sect239k1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT283K1: - /* Populate params for sect283k1 - * (the NIST K-283 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT283R1: - /* Populate params for sect283r1 - * (the NIST B-283 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT409K1: - /* Populate params for sect409k1 - * (the NIST K-409 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT409R1: - /* Populate params for sect409r1 - * (the NIST B-409 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT571K1: - /* Populate params for sect571k1 - * (the NIST K-571 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m, - params) ); - break; - - case SEC_OID_SECG_EC_SECT571R1: - /* Populate params for sect571r1 - * (the NIST B-571 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m, - params) ); - break; - - /* Prime curves */ - - case SEC_OID_ANSIX962_EC_PRIME192V1: - /* Populate params for prime192v1 aka secp192r1 - * (the NIST P-192 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp, - params) ); - break; - - case SEC_OID_ANSIX962_EC_PRIME192V2: - /* Populate params for prime192v2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp, - params) ); - break; - - case SEC_OID_ANSIX962_EC_PRIME192V3: - /* Populate params for prime192v3 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp, - params) ); - break; - - case SEC_OID_ANSIX962_EC_PRIME239V1: - /* Populate params for prime239v1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp, - params) ); - break; - - case SEC_OID_ANSIX962_EC_PRIME239V2: - /* Populate params for prime239v2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp, - params) ); - break; - - case SEC_OID_ANSIX962_EC_PRIME239V3: - /* Populate params for prime239v3 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp, - params) ); - break; - - case SEC_OID_ANSIX962_EC_PRIME256V1: - /* Populate params for prime256v1 aka secp256r1 - * (the NIST P-256 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP112R1: - /* Populate params for secp112r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP112R2: - /* Populate params for secp112r2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP128R1: - /* Populate params for secp128r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP128R2: - /* Populate params for secp128r2 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP160K1: - /* Populate params for secp160k1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP160R1: - /* Populate params for secp160r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP160R2: - /* Populate params for secp160r1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP192K1: - /* Populate params for secp192k1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP224K1: - /* Populate params for secp224k1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP224R1: - /* Populate params for secp224r1 - * (the NIST P-224 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP256K1: - /* Populate params for secp256k1 */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP384R1: - /* Populate params for secp384r1 - * (the NIST P-384 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp, - params) ); - break; - - case SEC_OID_SECG_EC_SECP521R1: - /* Populate params for secp521r1 - * (the NIST P-521 curve) - */ - CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp, - params) ); - break; - - default: - break; - }; - -cleanup: - if (!params->cofactor) { - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); -#if EC_DEBUG - printf("Unrecognized curve, returning NULL params\n"); -#endif - } - - return rv; -} - -SECStatus -EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams) -{ - PRArenaPool *arena; - ECParams *params; - SECStatus rv = SECFailure; - - /* Initialize an arena for the ECParams structure */ - if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE))) - return SECFailure; - - params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams)); - if (!params) { - PORT_FreeArena(arena, PR_TRUE); - return SECFailure; - } - - /* Copy the encoded params */ - SECITEM_AllocItem(arena, &(params->DEREncoding), - encodedParams->len); - memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len); - - /* Fill out the rest of the ECParams structure based on - * the encoded params - */ - rv = EC_FillParams(arena, encodedParams, params); - if (rv == SECFailure) { - PORT_FreeArena(arena, PR_TRUE); - return SECFailure; - } else { - *ecparams = params;; - return SECSuccess; - } -} - -#endif /* NSS_ENABLE_ECC */ diff --git a/security/nss/lib/softoken/fipsaudt.c b/security/nss/lib/softoken/fipsaudt.c deleted file mode 100644 index 573a17cf1..000000000 --- a/security/nss/lib/softoken/fipsaudt.c +++ /dev/null @@ -1,351 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 Network Security Services (NSS). - * - * The Initial Developer of the Original Code is - * Red Hat, Inc. - * Portions created by the Initial Developer are Copyright (C) 2006 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * This file implements audit logging required by FIPS 140-2 Security - * Level 2. - */ - -#include "prprf.h" -#include "softoken.h" - -/* - * Print the value of the returned object handle in the output buffer - * on a successful return of the PKCS #11 function. If the PKCS #11 - * function failed or the pointer to object handle is NULL (which is - * the case for C_DeriveKey with CKM_TLS_KEY_AND_MAC_DERIVE), an empty - * string is stored in the output buffer. - * - * out: the output buffer - * outlen: the length of the output buffer - * argName: the name of the "pointer to object handle" argument - * phObject: the pointer to object handle - * rv: the return value of the PKCS #11 function - */ -static void sftk_PrintReturnedObjectHandle(char *out, PRUint32 outlen, - const char *argName, CK_OBJECT_HANDLE_PTR phObject, CK_RV rv) -{ - if ((rv == CKR_OK) && phObject) { - PR_snprintf(out, outlen, - " *%s=0x%08lX", argName, (PRUint32)*phObject); - } else { - PORT_Assert(outlen != 0); - out[0] = '\0'; - } -} - -/* - * MECHANISM_BUFSIZE needs to be large enough for sftk_PrintMechanism, - * which uses <= 49 bytes. - */ -#define MECHANISM_BUFSIZE 64 - -static void sftk_PrintMechanism(char *out, PRUint32 outlen, - CK_MECHANISM_PTR pMechanism) -{ - if (pMechanism) { - /* - * If we change the format string, we need to make sure - * MECHANISM_BUFSIZE is still large enough. We allow - * 20 bytes for %p on a 64-bit platform. - */ - PR_snprintf(out, outlen, "%p {mechanism=0x%08lX, ...}", - pMechanism, (PRUint32)pMechanism->mechanism); - } else { - PR_snprintf(out, outlen, "%p", pMechanism); - } -} - -void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phObject, CK_RV rv) -{ - char msg[256]; - char shObject[32]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintReturnedObjectHandle(shObject, sizeof shObject, - "phObject", phObject, rv); - PR_snprintf(msg, sizeof msg, - "C_CreateObject(hSession=0x%08lX, pTemplate=%p, ulCount=%lu, " - "phObject=%p)=0x%08lX%s", - (PRUint32)hSession, pTemplate, (PRUint32)ulCount, - phObject, (PRUint32)rv, shObject); - sftk_LogAuditMessage(severity, NSS_AUDIT_LOAD_KEY, msg); -} - -void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv) -{ - char msg[256]; - char shNewObject[32]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintReturnedObjectHandle(shNewObject, sizeof shNewObject, - "phNewObject", phNewObject, rv); - PR_snprintf(msg, sizeof msg, - "C_CopyObject(hSession=0x%08lX, hObject=0x%08lX, " - "pTemplate=%p, ulCount=%lu, phNewObject=%p)=0x%08lX%s", - (PRUint32)hSession, (PRUint32)hObject, - pTemplate, (PRUint32)ulCount, phNewObject, (PRUint32)rv, shNewObject); - sftk_LogAuditMessage(severity, NSS_AUDIT_COPY_KEY, msg); -} - -/* WARNING: hObject has been destroyed and can only be printed. */ -void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_RV rv) -{ - char msg[256]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - PR_snprintf(msg, sizeof msg, - "C_DestroyObject(hSession=0x%08lX, hObject=0x%08lX)=0x%08lX", - (PRUint32)hSession, (PRUint32)hObject, (PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_DESTROY_KEY, msg); -} - -void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, CK_RV rv) -{ - char msg[256]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - PR_snprintf(msg, sizeof msg, - "C_GetObjectSize(hSession=0x%08lX, hObject=0x%08lX, " - "pulSize=%p)=0x%08lX", - (PRUint32)hSession, (PRUint32)hObject, - pulSize, (PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_ACCESS_KEY, msg); -} - -void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, CK_RV rv) -{ - char msg[256]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - PR_snprintf(msg, sizeof msg, - "C_GetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, " - "pTemplate=%p, ulCount=%lu)=0x%08lX", - (PRUint32)hSession, (PRUint32)hObject, - pTemplate, (PRUint32)ulCount, (PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_ACCESS_KEY, msg); -} - -void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, CK_RV rv) -{ - char msg[256]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - PR_snprintf(msg, sizeof msg, - "C_SetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, " - "pTemplate=%p, ulCount=%lu)=0x%08lX", - (PRUint32)hSession, (PRUint32)hObject, - pTemplate, (PRUint32)ulCount, (PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_CHANGE_KEY, msg); -} - -void sftk_AuditCryptInit(const char *opName, CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_RV rv) -{ - char msg[256]; - char mech[MECHANISM_BUFSIZE]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintMechanism(mech, sizeof mech, pMechanism); - PR_snprintf(msg, sizeof msg, - "C_%sInit(hSession=0x%08lX, pMechanism=%s, " - "hKey=0x%08lX)=0x%08lX", - opName, (PRUint32)hSession, mech, - (PRUint32)hKey, (PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_CRYPT, msg); -} - -void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) -{ - char msg[256]; - char mech[MECHANISM_BUFSIZE]; - char shKey[32]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintMechanism(mech, sizeof mech, pMechanism); - sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); - PR_snprintf(msg, sizeof msg, - "C_GenerateKey(hSession=0x%08lX, pMechanism=%s, " - "pTemplate=%p, ulCount=%lu, phKey=%p)=0x%08lX%s", - (PRUint32)hSession, mech, - pTemplate, (PRUint32)ulCount, phKey, (PRUint32)rv, shKey); - sftk_LogAuditMessage(severity, NSS_AUDIT_GENERATE_KEY, msg); -} - -void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, - CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, - CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv) -{ - char msg[512]; - char mech[MECHANISM_BUFSIZE]; - char shPublicKey[32]; - char shPrivateKey[32]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintMechanism(mech, sizeof mech, pMechanism); - sftk_PrintReturnedObjectHandle(shPublicKey, sizeof shPublicKey, - "phPublicKey", phPublicKey, rv); - sftk_PrintReturnedObjectHandle(shPrivateKey, sizeof shPrivateKey, - "phPrivateKey", phPrivateKey, rv); - PR_snprintf(msg, sizeof msg, - "C_GenerateKeyPair(hSession=0x%08lX, pMechanism=%s, " - "pPublicKeyTemplate=%p, ulPublicKeyAttributeCount=%lu, " - "pPrivateKeyTemplate=%p, ulPrivateKeyAttributeCount=%lu, " - "phPublicKey=%p, phPrivateKey=%p)=0x%08lX%s%s", - (PRUint32)hSession, mech, - pPublicKeyTemplate, (PRUint32)ulPublicKeyAttributeCount, - pPrivateKeyTemplate, (PRUint32)ulPrivateKeyAttributeCount, - phPublicKey, phPrivateKey, (PRUint32)rv, shPublicKey, shPrivateKey); - sftk_LogAuditMessage(severity, NSS_AUDIT_GENERATE_KEY, msg); -} - -void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, - CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, - CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv) -{ - char msg[256]; - char mech[MECHANISM_BUFSIZE]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintMechanism(mech, sizeof mech, pMechanism); - PR_snprintf(msg, sizeof msg, - "C_WrapKey(hSession=0x%08lX, pMechanism=%s, hWrappingKey=0x%08lX, " - "hKey=0x%08lX, pWrappedKey=%p, pulWrappedKeyLen=%p)=0x%08lX", - (PRUint32)hSession, mech, (PRUint32)hWrappingKey, - (PRUint32)hKey, pWrappedKey, pulWrappedKeyLen, (PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_WRAP_KEY, msg); -} - -void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, - CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) -{ - char msg[256]; - char mech[MECHANISM_BUFSIZE]; - char shKey[32]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintMechanism(mech, sizeof mech, pMechanism); - sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); - PR_snprintf(msg, sizeof msg, - "C_UnwrapKey(hSession=0x%08lX, pMechanism=%s, " - "hUnwrappingKey=0x%08lX, pWrappedKey=%p, ulWrappedKeyLen=%lu, " - "pTemplate=%p, ulAttributeCount=%lu, phKey=%p)=0x%08lX%s", - (PRUint32)hSession, mech, - (PRUint32)hUnwrappingKey, pWrappedKey, (PRUint32)ulWrappedKeyLen, - pTemplate, (PRUint32)ulAttributeCount, phKey, (PRUint32)rv, shKey); - sftk_LogAuditMessage(severity, NSS_AUDIT_UNWRAP_KEY, msg); -} - -void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) -{ - char msg[512]; - char mech[MECHANISM_BUFSIZE]; - char shKey[32]; - char sTlsKeys[128]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - sftk_PrintMechanism(mech, sizeof mech, pMechanism); - sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); - if ((rv == CKR_OK) && - (pMechanism->mechanism == CKM_TLS_KEY_AND_MAC_DERIVE)) { - CK_SSL3_KEY_MAT_PARAMS *param = - (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; - CK_SSL3_KEY_MAT_OUT *keymat = param->pReturnedKeyMaterial; - PR_snprintf(sTlsKeys, sizeof sTlsKeys, - " hClientMacSecret=0x%08lX hServerMacSecret=0x%08lX" - " hClientKey=0x%08lX hServerKey=0x%08lX", - (PRUint32)keymat->hClientMacSecret, - (PRUint32)keymat->hServerMacSecret, - (PRUint32)keymat->hClientKey, - (PRUint32)keymat->hServerKey); - } else { - sTlsKeys[0] = '\0'; - } - PR_snprintf(msg, sizeof msg, - "C_DeriveKey(hSession=0x%08lX, pMechanism=%s, " - "hBaseKey=0x%08lX, pTemplate=%p, ulAttributeCount=%lu, " - "phKey=%p)=0x%08lX%s%s", - (PRUint32)hSession, mech, - (PRUint32)hBaseKey, pTemplate,(PRUint32)ulAttributeCount, - phKey, (PRUint32)rv, shKey, sTlsKeys); - sftk_LogAuditMessage(severity, NSS_AUDIT_DERIVE_KEY, msg); -} - -void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hKey, CK_RV rv) -{ - char msg[256]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - - PR_snprintf(msg, sizeof msg, - "C_DigestKey(hSession=0x%08lX, hKey=0x%08lX)=0x%08lX", - (PRUint32)hSession, (PRUint32)hKey, (PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_DIGEST_KEY, msg); -} diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c deleted file mode 100644 index 8dddbc667..000000000 --- a/security/nss/lib/softoken/fipstest.c +++ /dev/null @@ -1,2057 +0,0 @@ -/* - * PKCS #11 FIPS Power-Up Self Test. - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#include "softoken.h" /* Required for RC2-ECB, RC2-CBC, RC4, DES-ECB, */ - /* DES-CBC, DES3-ECB, DES3-CBC, RSA */ - /* and DSA. */ -#include "seccomon.h" /* Required for RSA and DSA. */ -#include "lowkeyi.h" /* Required for RSA and DSA. */ -#include "pkcs11.h" /* Required for PKCS #11. */ -#include "secerr.h" - -#ifdef NSS_ENABLE_ECC -#include "ec.h" /* Required for ECDSA */ -#endif - - -/* FIPS preprocessor directives for RC2-ECB and RC2-CBC. */ -#define FIPS_RC2_KEY_LENGTH 5 /* 40-bits */ -#define FIPS_RC2_ENCRYPT_LENGTH 8 /* 64-bits */ -#define FIPS_RC2_DECRYPT_LENGTH 8 /* 64-bits */ - - -/* FIPS preprocessor directives for RC4. */ -#define FIPS_RC4_KEY_LENGTH 5 /* 40-bits */ -#define FIPS_RC4_ENCRYPT_LENGTH 8 /* 64-bits */ -#define FIPS_RC4_DECRYPT_LENGTH 8 /* 64-bits */ - - -/* FIPS preprocessor directives for DES-ECB and DES-CBC. */ -#define FIPS_DES_ENCRYPT_LENGTH 8 /* 64-bits */ -#define FIPS_DES_DECRYPT_LENGTH 8 /* 64-bits */ - - -/* FIPS preprocessor directives for DES3-CBC and DES3-ECB. */ -#define FIPS_DES3_ENCRYPT_LENGTH 8 /* 64-bits */ -#define FIPS_DES3_DECRYPT_LENGTH 8 /* 64-bits */ - - -/* FIPS preprocessor directives for AES-ECB and AES-CBC. */ -#define FIPS_AES_BLOCK_SIZE 16 /* 128-bits */ -#define FIPS_AES_ENCRYPT_LENGTH 16 /* 128-bits */ -#define FIPS_AES_DECRYPT_LENGTH 16 /* 128-bits */ -#define FIPS_AES_128_KEY_SIZE 16 /* 128-bits */ -#define FIPS_AES_192_KEY_SIZE 24 /* 192-bits */ -#define FIPS_AES_256_KEY_SIZE 32 /* 256-bits */ - - -/* FIPS preprocessor directives for message digests */ -#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */ - - -/* FIPS preprocessor directives for RSA. */ -#define FIPS_RSA_TYPE siBuffer -#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 3 /* 24-bits */ -#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */ -#define FIPS_RSA_MESSAGE_LENGTH 128 /* 1024-bits */ -#define FIPS_RSA_COEFFICIENT_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_PRIME0_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_PRIME1_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_EXPONENT0_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_EXPONENT1_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 128 /* 1024-bits */ -#define FIPS_RSA_ENCRYPT_LENGTH 128 /* 1024-bits */ -#define FIPS_RSA_DECRYPT_LENGTH 128 /* 1024-bits */ -#define FIPS_RSA_SIGNATURE_LENGTH 128 /* 1024-bits */ -#define FIPS_RSA_MODULUS_LENGTH 128 /* 1024-bits */ - - -/* FIPS preprocessor directives for DSA. */ -#define FIPS_DSA_TYPE siBuffer -#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */ -#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */ -#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */ -#define FIPS_DSA_PRIME_LENGTH 128 /* 1024-bits */ -#define FIPS_DSA_BASE_LENGTH 128 /* 1024-bits */ - -/* FIPS preprocessor directives for RNG. */ -#define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */ - -static CK_RV -sftk_fips_RC2_PowerUpSelfTest( void ) -{ - /* RC2 Known Key (40-bits). */ - static const PRUint8 rc2_known_key[] = { "RSARC" }; - - /* RC2-CBC Known Initialization Vector (64-bits). */ - static const PRUint8 rc2_cbc_known_initialization_vector[] = {"Security"}; - - /* RC2 Known Plaintext (64-bits). */ - static const PRUint8 rc2_ecb_known_plaintext[] = {"Netscape"}; - static const PRUint8 rc2_cbc_known_plaintext[] = {"Netscape"}; - - /* RC2 Known Ciphertext (64-bits). */ - static const PRUint8 rc2_ecb_known_ciphertext[] = { - 0x1a,0x71,0x33,0x54,0x8d,0x5c,0xd2,0x30}; - static const PRUint8 rc2_cbc_known_ciphertext[] = { - 0xff,0x41,0xdb,0x94,0x8a,0x4c,0x33,0xb3}; - - /* RC2 variables. */ - PRUint8 rc2_computed_ciphertext[FIPS_RC2_ENCRYPT_LENGTH]; - PRUint8 rc2_computed_plaintext[FIPS_RC2_DECRYPT_LENGTH]; - RC2Context * rc2_context; - unsigned int rc2_bytes_encrypted; - unsigned int rc2_bytes_decrypted; - SECStatus rc2_status; - - - /******************************************************/ - /* RC2-ECB Single-Round Known Answer Encryption Test: */ - /******************************************************/ - - rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH, - NULL, NSS_RC2, - FIPS_RC2_KEY_LENGTH ); - - if( rc2_context == NULL ) - return( CKR_HOST_MEMORY ); - - rc2_status = RC2_Encrypt( rc2_context, rc2_computed_ciphertext, - &rc2_bytes_encrypted, FIPS_RC2_ENCRYPT_LENGTH, - rc2_ecb_known_plaintext, - FIPS_RC2_DECRYPT_LENGTH ); - - RC2_DestroyContext( rc2_context, PR_TRUE ); - - if( ( rc2_status != SECSuccess ) || - ( rc2_bytes_encrypted != FIPS_RC2_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( rc2_computed_ciphertext, rc2_ecb_known_ciphertext, - FIPS_RC2_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* RC2-ECB Single-Round Known Answer Decryption Test: */ - /******************************************************/ - - rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH, - NULL, NSS_RC2, - FIPS_RC2_KEY_LENGTH ); - - if( rc2_context == NULL ) - return( CKR_HOST_MEMORY ); - - rc2_status = RC2_Decrypt( rc2_context, rc2_computed_plaintext, - &rc2_bytes_decrypted, FIPS_RC2_DECRYPT_LENGTH, - rc2_ecb_known_ciphertext, - FIPS_RC2_ENCRYPT_LENGTH ); - - RC2_DestroyContext( rc2_context, PR_TRUE ); - - if( ( rc2_status != SECSuccess ) || - ( rc2_bytes_decrypted != FIPS_RC2_DECRYPT_LENGTH ) || - ( PORT_Memcmp( rc2_computed_plaintext, rc2_ecb_known_plaintext, - FIPS_RC2_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* RC2-CBC Single-Round Known Answer Encryption Test: */ - /******************************************************/ - - rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH, - rc2_cbc_known_initialization_vector, - NSS_RC2_CBC, FIPS_RC2_KEY_LENGTH ); - - if( rc2_context == NULL ) - return( CKR_HOST_MEMORY ); - - rc2_status = RC2_Encrypt( rc2_context, rc2_computed_ciphertext, - &rc2_bytes_encrypted, FIPS_RC2_ENCRYPT_LENGTH, - rc2_cbc_known_plaintext, - FIPS_RC2_DECRYPT_LENGTH ); - - RC2_DestroyContext( rc2_context, PR_TRUE ); - - if( ( rc2_status != SECSuccess ) || - ( rc2_bytes_encrypted != FIPS_RC2_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( rc2_computed_ciphertext, rc2_cbc_known_ciphertext, - FIPS_RC2_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* RC2-CBC Single-Round Known Answer Decryption Test: */ - /******************************************************/ - - rc2_context = RC2_CreateContext( rc2_known_key, FIPS_RC2_KEY_LENGTH, - rc2_cbc_known_initialization_vector, - NSS_RC2_CBC, FIPS_RC2_KEY_LENGTH ); - - if( rc2_context == NULL ) - return( CKR_HOST_MEMORY ); - - rc2_status = RC2_Decrypt( rc2_context, rc2_computed_plaintext, - &rc2_bytes_decrypted, FIPS_RC2_DECRYPT_LENGTH, - rc2_cbc_known_ciphertext, - FIPS_RC2_ENCRYPT_LENGTH ); - - RC2_DestroyContext( rc2_context, PR_TRUE ); - - if( ( rc2_status != SECSuccess ) || - ( rc2_bytes_decrypted != FIPS_RC2_DECRYPT_LENGTH ) || - ( PORT_Memcmp( rc2_computed_plaintext, rc2_ecb_known_plaintext, - FIPS_RC2_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - - -static CK_RV -sftk_fips_RC4_PowerUpSelfTest( void ) -{ - /* RC4 Known Key (40-bits). */ - static const PRUint8 rc4_known_key[] = { "RSARC" }; - - /* RC4 Known Plaintext (64-bits). */ - static const PRUint8 rc4_known_plaintext[] = { "Netscape" }; - - /* RC4 Known Ciphertext (64-bits). */ - static const PRUint8 rc4_known_ciphertext[] = { - 0x29,0x33,0xc7,0x9a,0x9d,0x6c,0x09,0xdd}; - - /* RC4 variables. */ - PRUint8 rc4_computed_ciphertext[FIPS_RC4_ENCRYPT_LENGTH]; - PRUint8 rc4_computed_plaintext[FIPS_RC4_DECRYPT_LENGTH]; - RC4Context * rc4_context; - unsigned int rc4_bytes_encrypted; - unsigned int rc4_bytes_decrypted; - SECStatus rc4_status; - - - /**************************************************/ - /* RC4 Single-Round Known Answer Encryption Test: */ - /**************************************************/ - - rc4_context = RC4_CreateContext( rc4_known_key, FIPS_RC4_KEY_LENGTH ); - - if( rc4_context == NULL ) - return( CKR_HOST_MEMORY ); - - rc4_status = RC4_Encrypt( rc4_context, rc4_computed_ciphertext, - &rc4_bytes_encrypted, FIPS_RC4_ENCRYPT_LENGTH, - rc4_known_plaintext, FIPS_RC4_DECRYPT_LENGTH ); - - RC4_DestroyContext( rc4_context, PR_TRUE ); - - if( ( rc4_status != SECSuccess ) || - ( rc4_bytes_encrypted != FIPS_RC4_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( rc4_computed_ciphertext, rc4_known_ciphertext, - FIPS_RC4_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /**************************************************/ - /* RC4 Single-Round Known Answer Decryption Test: */ - /**************************************************/ - - rc4_context = RC4_CreateContext( rc4_known_key, FIPS_RC4_KEY_LENGTH ); - - if( rc4_context == NULL ) - return( CKR_HOST_MEMORY ); - - rc4_status = RC4_Decrypt( rc4_context, rc4_computed_plaintext, - &rc4_bytes_decrypted, FIPS_RC4_DECRYPT_LENGTH, - rc4_known_ciphertext, FIPS_RC4_ENCRYPT_LENGTH ); - - RC4_DestroyContext( rc4_context, PR_TRUE ); - - if( ( rc4_status != SECSuccess ) || - ( rc4_bytes_decrypted != FIPS_RC4_DECRYPT_LENGTH ) || - ( PORT_Memcmp( rc4_computed_plaintext, rc4_known_plaintext, - FIPS_RC4_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - - -static CK_RV -sftk_fips_DES_PowerUpSelfTest( void ) -{ - /* DES Known Key (56-bits). */ - static const PRUint8 des_known_key[] = { "ANSI DES" }; - - /* DES-CBC Known Initialization Vector (64-bits). */ - static const PRUint8 des_cbc_known_initialization_vector[] = { "Security" }; - - /* DES Known Plaintext (64-bits). */ - static const PRUint8 des_ecb_known_plaintext[] = { "Netscape" }; - static const PRUint8 des_cbc_known_plaintext[] = { "Netscape" }; - - /* DES Known Ciphertext (64-bits). */ - static const PRUint8 des_ecb_known_ciphertext[] = { - 0x26,0x14,0xe9,0xc3,0x28,0x80,0x50,0xb0}; - static const PRUint8 des_cbc_known_ciphertext[] = { - 0x5e,0x95,0x94,0x5d,0x76,0xa2,0xd3,0x7d}; - - /* DES variables. */ - PRUint8 des_computed_ciphertext[FIPS_DES_ENCRYPT_LENGTH]; - PRUint8 des_computed_plaintext[FIPS_DES_DECRYPT_LENGTH]; - DESContext * des_context; - unsigned int des_bytes_encrypted; - unsigned int des_bytes_decrypted; - SECStatus des_status; - - - /******************************************************/ - /* DES-ECB Single-Round Known Answer Encryption Test: */ - /******************************************************/ - - des_context = DES_CreateContext( des_known_key, NULL, NSS_DES, PR_TRUE ); - - if( des_context == NULL ) - return( CKR_HOST_MEMORY ); - - des_status = DES_Encrypt( des_context, des_computed_ciphertext, - &des_bytes_encrypted, FIPS_DES_ENCRYPT_LENGTH, - des_ecb_known_plaintext, - FIPS_DES_DECRYPT_LENGTH ); - - DES_DestroyContext( des_context, PR_TRUE ); - - if( ( des_status != SECSuccess ) || - ( des_bytes_encrypted != FIPS_DES_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( des_computed_ciphertext, des_ecb_known_ciphertext, - FIPS_DES_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* DES-ECB Single-Round Known Answer Decryption Test: */ - /******************************************************/ - - des_context = DES_CreateContext( des_known_key, NULL, NSS_DES, PR_FALSE ); - - if( des_context == NULL ) - return( CKR_HOST_MEMORY ); - - des_status = DES_Decrypt( des_context, des_computed_plaintext, - &des_bytes_decrypted, FIPS_DES_DECRYPT_LENGTH, - des_ecb_known_ciphertext, - FIPS_DES_ENCRYPT_LENGTH ); - - DES_DestroyContext( des_context, PR_TRUE ); - - if( ( des_status != SECSuccess ) || - ( des_bytes_decrypted != FIPS_DES_DECRYPT_LENGTH ) || - ( PORT_Memcmp( des_computed_plaintext, des_ecb_known_plaintext, - FIPS_DES_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* DES-CBC Single-Round Known Answer Encryption Test. */ - /******************************************************/ - - des_context = DES_CreateContext( des_known_key, - des_cbc_known_initialization_vector, - NSS_DES_CBC, PR_TRUE ); - - if( des_context == NULL ) - return( CKR_HOST_MEMORY ); - - des_status = DES_Encrypt( des_context, des_computed_ciphertext, - &des_bytes_encrypted, FIPS_DES_ENCRYPT_LENGTH, - des_cbc_known_plaintext, - FIPS_DES_DECRYPT_LENGTH ); - - DES_DestroyContext( des_context, PR_TRUE ); - - if( ( des_status != SECSuccess ) || - ( des_bytes_encrypted != FIPS_DES_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( des_computed_ciphertext, des_cbc_known_ciphertext, - FIPS_DES_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* DES-CBC Single-Round Known Answer Decryption Test. */ - /******************************************************/ - - des_context = DES_CreateContext( des_known_key, - des_cbc_known_initialization_vector, - NSS_DES_CBC, PR_FALSE ); - - if( des_context == NULL ) - return( CKR_HOST_MEMORY ); - - des_status = DES_Decrypt( des_context, des_computed_plaintext, - &des_bytes_decrypted, FIPS_DES_DECRYPT_LENGTH, - des_cbc_known_ciphertext, - FIPS_DES_ENCRYPT_LENGTH ); - - DES_DestroyContext( des_context, PR_TRUE ); - - if( ( des_status != SECSuccess ) || - ( des_bytes_decrypted != FIPS_DES_DECRYPT_LENGTH ) || - ( PORT_Memcmp( des_computed_plaintext, des_cbc_known_plaintext, - FIPS_DES_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - - -static CK_RV -sftk_fips_DES3_PowerUpSelfTest( void ) -{ - /* DES3 Known Key (56-bits). */ - static const PRUint8 des3_known_key[] = { "ANSI Triple-DES Key Data" }; - - /* DES3-CBC Known Initialization Vector (64-bits). */ - static const PRUint8 des3_cbc_known_initialization_vector[] = { "Security" }; - - /* DES3 Known Plaintext (64-bits). */ - static const PRUint8 des3_ecb_known_plaintext[] = { "Netscape" }; - static const PRUint8 des3_cbc_known_plaintext[] = { "Netscape" }; - - /* DES3 Known Ciphertext (64-bits). */ - static const PRUint8 des3_ecb_known_ciphertext[] = { - 0x55,0x8e,0xad,0x3c,0xee,0x49,0x69,0xbe}; - static const PRUint8 des3_cbc_known_ciphertext[] = { - 0x43,0xdc,0x6a,0xc1,0xaf,0xa6,0x32,0xf5}; - - /* DES3 variables. */ - PRUint8 des3_computed_ciphertext[FIPS_DES3_ENCRYPT_LENGTH]; - PRUint8 des3_computed_plaintext[FIPS_DES3_DECRYPT_LENGTH]; - DESContext * des3_context; - unsigned int des3_bytes_encrypted; - unsigned int des3_bytes_decrypted; - SECStatus des3_status; - - - /*******************************************************/ - /* DES3-ECB Single-Round Known Answer Encryption Test. */ - /*******************************************************/ - - des3_context = DES_CreateContext( des3_known_key, NULL, - NSS_DES_EDE3, PR_TRUE ); - - if( des3_context == NULL ) - return( CKR_HOST_MEMORY ); - - des3_status = DES_Encrypt( des3_context, des3_computed_ciphertext, - &des3_bytes_encrypted, FIPS_DES3_ENCRYPT_LENGTH, - des3_ecb_known_plaintext, - FIPS_DES3_DECRYPT_LENGTH ); - - DES_DestroyContext( des3_context, PR_TRUE ); - - if( ( des3_status != SECSuccess ) || - ( des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( des3_computed_ciphertext, des3_ecb_known_ciphertext, - FIPS_DES3_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /*******************************************************/ - /* DES3-ECB Single-Round Known Answer Decryption Test. */ - /*******************************************************/ - - des3_context = DES_CreateContext( des3_known_key, NULL, - NSS_DES_EDE3, PR_FALSE ); - - if( des3_context == NULL ) - return( CKR_HOST_MEMORY ); - - des3_status = DES_Decrypt( des3_context, des3_computed_plaintext, - &des3_bytes_decrypted, FIPS_DES3_DECRYPT_LENGTH, - des3_ecb_known_ciphertext, - FIPS_DES3_ENCRYPT_LENGTH ); - - DES_DestroyContext( des3_context, PR_TRUE ); - - if( ( des3_status != SECSuccess ) || - ( des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH ) || - ( PORT_Memcmp( des3_computed_plaintext, des3_ecb_known_plaintext, - FIPS_DES3_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /*******************************************************/ - /* DES3-CBC Single-Round Known Answer Encryption Test. */ - /*******************************************************/ - - des3_context = DES_CreateContext( des3_known_key, - des3_cbc_known_initialization_vector, - NSS_DES_EDE3_CBC, PR_TRUE ); - - if( des3_context == NULL ) - return( CKR_HOST_MEMORY ); - - des3_status = DES_Encrypt( des3_context, des3_computed_ciphertext, - &des3_bytes_encrypted, FIPS_DES3_ENCRYPT_LENGTH, - des3_cbc_known_plaintext, - FIPS_DES3_DECRYPT_LENGTH ); - - DES_DestroyContext( des3_context, PR_TRUE ); - - if( ( des3_status != SECSuccess ) || - ( des3_bytes_encrypted != FIPS_DES3_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( des3_computed_ciphertext, des3_cbc_known_ciphertext, - FIPS_DES3_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /*******************************************************/ - /* DES3-CBC Single-Round Known Answer Decryption Test. */ - /*******************************************************/ - - des3_context = DES_CreateContext( des3_known_key, - des3_cbc_known_initialization_vector, - NSS_DES_EDE3_CBC, PR_FALSE ); - - if( des3_context == NULL ) - return( CKR_HOST_MEMORY ); - - des3_status = DES_Decrypt( des3_context, des3_computed_plaintext, - &des3_bytes_decrypted, FIPS_DES3_DECRYPT_LENGTH, - des3_cbc_known_ciphertext, - FIPS_DES3_ENCRYPT_LENGTH ); - - DES_DestroyContext( des3_context, PR_TRUE ); - - if( ( des3_status != SECSuccess ) || - ( des3_bytes_decrypted != FIPS_DES3_DECRYPT_LENGTH ) || - ( PORT_Memcmp( des3_computed_plaintext, des3_cbc_known_plaintext, - FIPS_DES3_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - - -/* AES self-test for 128-bit, 192-bit, or 256-bit key sizes*/ -static CK_RV -sftk_fips_AES_PowerUpSelfTest( int aes_key_size ) -{ - /* AES Known Key (up to 256-bits). */ - static const PRUint8 aes_known_key[] = - { "AES-128 RIJNDAELLEADNJIR 821-SEA" }; - - /* AES-CBC Known Initialization Vector (128-bits). */ - static const PRUint8 aes_cbc_known_initialization_vector[] = - { "SecurityytiruceS" }; - - /* AES Known Plaintext (128-bits). (blocksize is 128-bits) */ - static const PRUint8 aes_known_plaintext[] = { "NetscapeepacsteN" }; - - /* AES Known Ciphertext (128-bit key). */ - static const PRUint8 aes_ecb128_known_ciphertext[] = { - 0x3c,0xa5,0x96,0xf3,0x34,0x6a,0x96,0xc1, - 0x03,0x88,0x16,0x7b,0x20,0xbf,0x35,0x47 }; - - static const PRUint8 aes_cbc128_known_ciphertext[] = { - 0xcf,0x15,0x1d,0x4f,0x96,0xe4,0x4f,0x63, - 0x15,0x54,0x14,0x1d,0x4e,0xd8,0xd5,0xea }; - - /* AES Known Ciphertext (192-bit key). */ - static const PRUint8 aes_ecb192_known_ciphertext[] = { - 0xa0,0x18,0x62,0xed,0x88,0x19,0xcb,0x62, - 0x88,0x1d,0x4d,0xfe,0x84,0x02,0x89,0x0e }; - - static const PRUint8 aes_cbc192_known_ciphertext[] = { - 0x83,0xf7,0xa4,0x76,0xd1,0x6f,0x07,0xbe, - 0x07,0xbc,0x43,0x2f,0x6d,0xad,0x29,0xe1 }; - - /* AES Known Ciphertext (256-bit key). */ - static const PRUint8 aes_ecb256_known_ciphertext[] = { - 0xdb,0xa6,0x52,0x01,0x8a,0x70,0xae,0x66, - 0x3a,0x99,0xd8,0x95,0x7f,0xfb,0x01,0x67 }; - - static const PRUint8 aes_cbc256_known_ciphertext[] = { - 0x37,0xea,0x07,0x06,0x31,0x1c,0x59,0x27, - 0xc5,0xc5,0x68,0x71,0x6e,0x34,0x40,0x16 }; - - const PRUint8 *aes_ecb_known_ciphertext = - ( aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext : - ( aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext : - aes_ecb256_known_ciphertext; - - const PRUint8 *aes_cbc_known_ciphertext = - ( aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cbc128_known_ciphertext : - ( aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cbc192_known_ciphertext : - aes_cbc256_known_ciphertext; - - /* AES variables. */ - PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH]; - PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH]; - AESContext * aes_context; - unsigned int aes_bytes_encrypted; - unsigned int aes_bytes_decrypted; - SECStatus aes_status; - - /*check if aes_key_size is 128, 192, or 256 bits */ - if ((aes_key_size != FIPS_AES_128_KEY_SIZE) && - (aes_key_size != FIPS_AES_192_KEY_SIZE) && - (aes_key_size != FIPS_AES_256_KEY_SIZE)) - return( CKR_DEVICE_ERROR ); - - /******************************************************/ - /* AES-ECB Single-Round Known Answer Encryption Test: */ - /******************************************************/ - - aes_context = AES_CreateContext( aes_known_key, NULL, NSS_AES, PR_TRUE, - aes_key_size, FIPS_AES_BLOCK_SIZE ); - - if( aes_context == NULL ) - return( CKR_HOST_MEMORY ); - - aes_status = AES_Encrypt( aes_context, aes_computed_ciphertext, - &aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH, - aes_known_plaintext, - FIPS_AES_DECRYPT_LENGTH ); - - AES_DestroyContext( aes_context, PR_TRUE ); - - if( ( aes_status != SECSuccess ) || - ( aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( aes_computed_ciphertext, aes_ecb_known_ciphertext, - FIPS_AES_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* AES-ECB Single-Round Known Answer Decryption Test: */ - /******************************************************/ - - aes_context = AES_CreateContext( aes_known_key, NULL, NSS_AES, PR_FALSE, - aes_key_size, FIPS_AES_BLOCK_SIZE ); - - if( aes_context == NULL ) - return( CKR_HOST_MEMORY ); - - aes_status = AES_Decrypt( aes_context, aes_computed_plaintext, - &aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH, - aes_ecb_known_ciphertext, - FIPS_AES_ENCRYPT_LENGTH ); - - AES_DestroyContext( aes_context, PR_TRUE ); - - if( ( aes_status != SECSuccess ) || - ( aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH ) || - ( PORT_Memcmp( aes_computed_plaintext, aes_known_plaintext, - FIPS_AES_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* AES-CBC Single-Round Known Answer Encryption Test. */ - /******************************************************/ - - aes_context = AES_CreateContext( aes_known_key, - aes_cbc_known_initialization_vector, - NSS_AES_CBC, PR_TRUE, aes_key_size, - FIPS_AES_BLOCK_SIZE ); - - if( aes_context == NULL ) - return( CKR_HOST_MEMORY ); - - aes_status = AES_Encrypt( aes_context, aes_computed_ciphertext, - &aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH, - aes_known_plaintext, - FIPS_AES_DECRYPT_LENGTH ); - - AES_DestroyContext( aes_context, PR_TRUE ); - - if( ( aes_status != SECSuccess ) || - ( aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH ) || - ( PORT_Memcmp( aes_computed_ciphertext, aes_cbc_known_ciphertext, - FIPS_AES_ENCRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - - /******************************************************/ - /* AES-CBC Single-Round Known Answer Decryption Test. */ - /******************************************************/ - - aes_context = AES_CreateContext( aes_known_key, - aes_cbc_known_initialization_vector, - NSS_AES_CBC, PR_FALSE, aes_key_size, - FIPS_AES_BLOCK_SIZE ); - - if( aes_context == NULL ) - return( CKR_HOST_MEMORY ); - - aes_status = AES_Decrypt( aes_context, aes_computed_plaintext, - &aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH, - aes_cbc_known_ciphertext, - FIPS_AES_ENCRYPT_LENGTH ); - - AES_DestroyContext( aes_context, PR_TRUE ); - - if( ( aes_status != SECSuccess ) || - ( aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH ) || - ( PORT_Memcmp( aes_computed_plaintext, aes_known_plaintext, - FIPS_AES_DECRYPT_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - -/* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */ -static const PRUint8 known_hash_message[] = { - "The test message for the MD2, MD5, and SHA-1 hashing algorithms." }; - - -static CK_RV -sftk_fips_MD2_PowerUpSelfTest( void ) -{ - /* MD2 Known Digest Message (128-bits). */ - static const PRUint8 md2_known_digest[] = { - 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17, - 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b}; - - /* MD2 variables. */ - MD2Context * md2_context; - unsigned int md2_bytes_hashed; - PRUint8 md2_computed_digest[MD2_LENGTH]; - - - /***********************************************/ - /* MD2 Single-Round Known Answer Hashing Test. */ - /***********************************************/ - - md2_context = MD2_NewContext(); - - if( md2_context == NULL ) - return( CKR_HOST_MEMORY ); - - MD2_Begin( md2_context ); - - MD2_Update( md2_context, known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH ); - - MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH ); - - MD2_DestroyContext( md2_context , PR_TRUE ); - - if( ( md2_bytes_hashed != MD2_LENGTH ) || - ( PORT_Memcmp( md2_computed_digest, md2_known_digest, - MD2_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - - -static CK_RV -sftk_fips_MD5_PowerUpSelfTest( void ) -{ - /* MD5 Known Digest Message (128-bits). */ - static const PRUint8 md5_known_digest[] = { - 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28, - 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d}; - - /* MD5 variables. */ - PRUint8 md5_computed_digest[MD5_LENGTH]; - SECStatus md5_status; - - - /***********************************************/ - /* MD5 Single-Round Known Answer Hashing Test. */ - /***********************************************/ - - md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH ); - - if( ( md5_status != SECSuccess ) || - ( PORT_Memcmp( md5_computed_digest, md5_known_digest, - MD5_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - -/****************************************************/ -/* Single Round HMAC SHA-X test */ -/****************************************************/ -static SECStatus -sftk_fips_HMAC(unsigned char *hmac_computed, - const PRUint8 *secret_key, - unsigned int secret_key_length, - const PRUint8 *message, - unsigned int message_length, - HASH_HashType hashAlg ) -{ - SECStatus hmac_status = SECFailure; - HMACContext *cx = NULL; - SECHashObject *hashObj = NULL; - unsigned int bytes_hashed = 0; - - hashObj = (SECHashObject *) HASH_GetRawHashObject(hashAlg); - - if (!hashObj) - return( SECFailure ); - - cx = HMAC_Create(hashObj, secret_key, - secret_key_length, - PR_TRUE); /* PR_TRUE for in FIPS mode */ - - if (cx == NULL) - return( SECFailure ); - - HMAC_Begin(cx); - HMAC_Update(cx, message, message_length); - hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed, - hashObj->length); - - HMAC_Destroy(cx, PR_TRUE); - - return( hmac_status ); -} - -static CK_RV -sftk_fips_HMAC_PowerUpSelfTest( void ) -{ - static const PRUint8 HMAC_known_secret_key[] = { - "Firefox and ThunderBird are awesome!"}; - - static const PRUint8 HMAC_known_secret_key_length - = sizeof HMAC_known_secret_key; - - /* known SHA1 hmac (20 bytes) */ - static const PRUint8 known_SHA1_hmac[] = { - 0xd5, 0x85, 0xf6, 0x5b, 0x39, 0xfa, 0xb9, 0x05, - 0x3b, 0x57, 0x1d, 0x61, 0xe7, 0xb8, 0x84, 0x1e, - 0x5d, 0x0e, 0x1e, 0x11}; - - /* known SHA256 hmac (32 bytes) */ - static const PRUint8 known_SHA256_hmac[] = { - 0x05, 0x75, 0x9a, 0x9e, 0x70, 0x5e, 0xe7, 0x44, - 0xe2, 0x46, 0x4b, 0x92, 0x22, 0x14, 0x22, 0xe0, - 0x1b, 0x92, 0x8a, 0x0c, 0xfe, 0xf5, 0x49, 0xe9, - 0xa7, 0x1b, 0x56, 0x7d, 0x1d, 0x29, 0x40, 0x48}; - - /* known SHA384 hmac (48 bytes) */ - static const PRUint8 known_SHA384_hmac[] = { - 0xcd, 0x56, 0x14, 0xec, 0x05, 0x53, 0x06, 0x2b, - 0x7e, 0x9c, 0x8a, 0x18, 0x5e, 0xea, 0xf3, 0x91, - 0x33, 0xfb, 0x64, 0xf6, 0xe3, 0x9f, 0x89, 0x0b, - 0xaf, 0xbe, 0x83, 0x4d, 0x3f, 0x3c, 0x43, 0x4d, - 0x4a, 0x0c, 0x56, 0x98, 0xf8, 0xca, 0xb4, 0xaa, - 0x9a, 0xf4, 0x0a, 0xaf, 0x4f, 0x69, 0xca, 0x87}; - - /* known SHA512 hmac (64 bytes) */ - static const PRUint8 known_SHA512_hmac[] = { - 0xf6, 0x0e, 0x97, 0x12, 0x00, 0x67, 0x6e, 0xb9, - 0x0c, 0xb2, 0x63, 0xf0, 0x60, 0xac, 0x75, 0x62, - 0x70, 0x95, 0x2a, 0x52, 0x22, 0xee, 0xdd, 0xd2, - 0x71, 0xb1, 0xe8, 0x26, 0x33, 0xd3, 0x13, 0x27, - 0xcb, 0xff, 0x44, 0xef, 0x87, 0x97, 0x16, 0xfb, - 0xd3, 0x0b, 0x48, 0xbe, 0x12, 0x4e, 0xda, 0xb1, - 0x89, 0x90, 0xfb, 0x06, 0x0c, 0xbe, 0xe5, 0xc4, - 0xff, 0x24, 0x37, 0x3d, 0xc7, 0xe4, 0xe4, 0x37}; - - SECStatus hmac_status; - PRUint8 hmac_computed[HASH_LENGTH_MAX]; - - /***************************************************/ - /* HMAC SHA-1 Single-Round Known Answer HMAC Test. */ - /***************************************************/ - - hmac_status = sftk_fips_HMAC(hmac_computed, - HMAC_known_secret_key, - HMAC_known_secret_key_length, - known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH, - HASH_AlgSHA1); - - if( ( hmac_status != SECSuccess ) || - ( PORT_Memcmp( hmac_computed, known_SHA1_hmac, - SHA1_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - /***************************************************/ - /* HMAC SHA-256 Single-Round Known Answer Test. */ - /***************************************************/ - - hmac_status = sftk_fips_HMAC(hmac_computed, - HMAC_known_secret_key, - HMAC_known_secret_key_length, - known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH, - HASH_AlgSHA256); - - if( ( hmac_status != SECSuccess ) || - ( PORT_Memcmp( hmac_computed, known_SHA256_hmac, - SHA256_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - /***************************************************/ - /* HMAC SHA-384 Single-Round Known Answer Test. */ - /***************************************************/ - - hmac_status = sftk_fips_HMAC(hmac_computed, - HMAC_known_secret_key, - HMAC_known_secret_key_length, - known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH, - HASH_AlgSHA384); - - if( ( hmac_status != SECSuccess ) || - ( PORT_Memcmp( hmac_computed, known_SHA384_hmac, - SHA384_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - /***************************************************/ - /* HMAC SHA-512 Single-Round Known Answer Test. */ - /***************************************************/ - - hmac_status = sftk_fips_HMAC(hmac_computed, - HMAC_known_secret_key, - HMAC_known_secret_key_length, - known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH, - HASH_AlgSHA512); - - if( ( hmac_status != SECSuccess ) || - ( PORT_Memcmp( hmac_computed, known_SHA512_hmac, - SHA512_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - -static CK_RV -sftk_fips_SHA_PowerUpSelfTest( void ) -{ - /* SHA-1 Known Digest Message (160-bits). */ - static const PRUint8 sha1_known_digest[] = { - 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b, - 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0, - 0xe0,0x68,0x47,0x7a}; - - /* SHA-256 Known Digest Message (256-bits). */ - static const PRUint8 sha256_known_digest[] = { - 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61, - 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d, - 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9, - 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79}; - - /* SHA-384 Known Digest Message (384-bits). */ - static const PRUint8 sha384_known_digest[] = { - 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3, - 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe, - 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8, - 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b, - 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3, - 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72}; - - /* SHA-512 Known Digest Message (512-bits). */ - static const PRUint8 sha512_known_digest[] = { - 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf, - 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb, - 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99, - 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28, - 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12, - 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f, - 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a, - 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07}; - - /* SHA-X variables. */ - PRUint8 sha_computed_digest[HASH_LENGTH_MAX]; - SECStatus sha_status; - - /*************************************************/ - /* SHA-1 Single-Round Known Answer Hashing Test. */ - /*************************************************/ - - sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH ); - - if( ( sha_status != SECSuccess ) || - ( PORT_Memcmp( sha_computed_digest, sha1_known_digest, - SHA1_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - /***************************************************/ - /* SHA-256 Single-Round Known Answer Hashing Test. */ - /***************************************************/ - - sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH ); - - if( ( sha_status != SECSuccess ) || - ( PORT_Memcmp( sha_computed_digest, sha256_known_digest, - SHA256_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - /***************************************************/ - /* SHA-384 Single-Round Known Answer Hashing Test. */ - /***************************************************/ - - sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH ); - - if( ( sha_status != SECSuccess ) || - ( PORT_Memcmp( sha_computed_digest, sha384_known_digest, - SHA384_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - /***************************************************/ - /* SHA-512 Single-Round Known Answer Hashing Test. */ - /***************************************************/ - - sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message, - FIPS_KNOWN_HASH_MESSAGE_LENGTH ); - - if( ( sha_status != SECSuccess ) || - ( PORT_Memcmp( sha_computed_digest, sha512_known_digest, - SHA512_LENGTH ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - -/* -* Single round RSA Signature Known Answer Test -*/ -static SECStatus -sftk_fips_RSA_PowerUpSigSelfTest (HASH_HashType shaAlg, - NSSLOWKEYPublicKey *rsa_public_key, - NSSLOWKEYPrivateKey *rsa_private_key, - const unsigned char *rsa_known_msg, - const unsigned int rsa_kmsg_length, - const unsigned char *rsa_known_signature) -{ - SECOidTag shaOid; /* SHA OID */ - unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */ - unsigned int shaLength = 0; /* length of SHA */ - unsigned int rsa_bytes_signed; - unsigned char rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH]; - SECStatus rv; - - if (shaAlg == HASH_AlgSHA1) { - if (SHA1_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) - != SECSuccess) { - goto loser; - } - shaLength = SHA1_LENGTH; - shaOid = SEC_OID_SHA1; - } else if (shaAlg == HASH_AlgSHA256) { - if (SHA256_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) - != SECSuccess) { - goto loser; - } - shaLength = SHA256_LENGTH; - shaOid = SEC_OID_SHA256; - } else if (shaAlg == HASH_AlgSHA384) { - if (SHA384_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) - != SECSuccess) { - goto loser; - } - shaLength = SHA384_LENGTH; - shaOid = SEC_OID_SHA384; - } else if (shaAlg == HASH_AlgSHA512) { - if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) - != SECSuccess) { - goto loser; - } - shaLength = SHA512_LENGTH; - shaOid = SEC_OID_SHA512; - } else { - goto loser; - } - - /*************************************************/ - /* RSA Single-Round Known Answer Signature Test. */ - /*************************************************/ - - /* Perform RSA signature with the RSA private key. */ - rv = RSA_HashSign( shaOid, - rsa_private_key, - rsa_computed_signature, - &rsa_bytes_signed, - FIPS_RSA_SIGNATURE_LENGTH, - sha, - shaLength); - - if( ( rv != SECSuccess ) || - ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) || - ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature, - FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) ) { - goto loser; - } - - /****************************************************/ - /* RSA Single-Round Known Answer Verification Test. */ - /****************************************************/ - - /* Perform RSA verification with the RSA public key. */ - rv = RSA_HashCheckSign( shaOid, - rsa_public_key, - rsa_computed_signature, - rsa_bytes_signed, - sha, - shaLength); - - if( rv != SECSuccess ) { - goto loser; - } - return( SECSuccess ); - -loser: - - return( SECFailure ); - -} - -static CK_RV -sftk_fips_RSA_PowerUpSelfTest( void ) -{ - /* RSA Known Modulus used in both Public/Private Key Values (1024-bits). */ - static const PRUint8 rsa_modulus[FIPS_RSA_MODULUS_LENGTH] = { - 0xd5, 0x84, 0x95, 0x07, 0xf4, 0xd0, 0x1f, 0x82, - 0xf3, 0x79, 0xf4, 0x99, 0x48, 0x10, 0xe1, 0x71, - 0xa5, 0x62, 0x22, 0xa3, 0x4b, 0x00, 0xe3, 0x5b, - 0x3a, 0xcc, 0x10, 0x83, 0xe0, 0xaf, 0x61, 0x13, - 0x54, 0x6a, 0xa2, 0x6a, 0x2c, 0x5e, 0xb3, 0xcc, - 0xa3, 0x71, 0x9a, 0xb2, 0x3e, 0x78, 0xec, 0xb5, - 0x0e, 0x6e, 0x31, 0x3b, 0x77, 0x1f, 0x6e, 0x94, - 0x41, 0x60, 0xd5, 0x6e, 0xd9, 0xc6, 0xf9, 0x29, - 0xc3, 0x40, 0x36, 0x25, 0xdb, 0xea, 0x0b, 0x07, - 0xae, 0x76, 0xfd, 0x99, 0x29, 0xf4, 0x22, 0xc1, - 0x1a, 0x8f, 0x05, 0xfe, 0x98, 0x09, 0x07, 0x05, - 0xc2, 0x0f, 0x0b, 0x11, 0x83, 0x39, 0xca, 0xc7, - 0x43, 0x63, 0xff, 0x33, 0x80, 0xe7, 0xc3, 0x78, - 0xae, 0xf1, 0x73, 0x52, 0x98, 0x1d, 0xde, 0x5c, - 0x53, 0x6e, 0x01, 0x73, 0x0d, 0x12, 0x7e, 0x77, - 0x03, 0xf1, 0xef, 0x1b, 0xc8, 0xa8, 0x0f, 0x97}; - - /* RSA Known Public Key Values (24-bits). */ - static const PRUint8 rsa_public_exponent[FIPS_RSA_PUBLIC_EXPONENT_LENGTH] - = { 0x01, 0x00, 0x01 }; - /* RSA Known Private Key Values (version is 8-bits), */ - /* (private exponent is 1024-bits), */ - /* (private prime0 is 512-bits), */ - /* (private prime1 is 512-bits), */ - /* (private prime exponent0 is 512-bits), */ - /* (private prime exponent1 is 512-bits), */ - /* and (private coefficient is 512-bits). */ - static const PRUint8 rsa_version[] = { 0x00 }; - - static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH] - = { 0x85, 0x27, 0x47, 0x61, 0x4c, 0xd4, 0xb5, 0xb2, - 0x0e, 0x70, 0x91, 0x8f, 0x3d, 0x97, 0xf9, 0x5f, - 0xcc, 0x09, 0x65, 0x1c, 0x7c, 0x5b, 0xb3, 0x6d, - 0x63, 0x3f, 0x7b, 0x55, 0x22, 0xbb, 0x7c, 0x48, - 0x77, 0xae, 0x80, 0x56, 0xc2, 0x10, 0xd5, 0x03, - 0xdb, 0x31, 0xaf, 0x8d, 0x54, 0xd4, 0x48, 0x99, - 0xa8, 0xc4, 0x23, 0x43, 0xb8, 0x48, 0x0b, 0xc7, - 0xbc, 0xf5, 0xcc, 0x64, 0x72, 0xbf, 0x59, 0x06, - 0x04, 0x1c, 0x32, 0xf5, 0x14, 0x2e, 0x6e, 0xe2, - 0x0f, 0x5c, 0xde, 0x36, 0x3c, 0x6e, 0x7c, 0x4d, - 0xcc, 0xd3, 0x00, 0x6e, 0xe5, 0x45, 0x46, 0xef, - 0x4d, 0x25, 0x46, 0x6d, 0x7f, 0xed, 0xbb, 0x4f, - 0x4d, 0x9f, 0xda, 0x87, 0x47, 0x8f, 0x74, 0x44, - 0xb7, 0xbe, 0x9d, 0xf5, 0xdd, 0xd2, 0x4c, 0xa5, - 0xab, 0x74, 0xe5, 0x29, 0xa1, 0xd2, 0x45, 0x3b, - 0x33, 0xde, 0xd5, 0xae, 0xf7, 0x03, 0x10, 0x21}; - - static const PRUint8 rsa_prime0[FIPS_RSA_PRIME0_LENGTH] = { - 0xf9, 0x74, 0x8f, 0x16, 0x02, 0x6b, 0xa0, 0xee, - 0x7f, 0x28, 0x97, 0x91, 0xdc, 0xec, 0xc0, 0x7c, - 0x49, 0xc2, 0x85, 0x76, 0xee, 0x66, 0x74, 0x2d, - 0x1a, 0xb8, 0xf7, 0x2f, 0x11, 0x5b, 0x36, 0xd8, - 0x46, 0x33, 0x3b, 0xd8, 0xf3, 0x2d, 0xa1, 0x03, - 0x83, 0x2b, 0xec, 0x35, 0x43, 0x32, 0xff, 0xdd, - 0x81, 0x7c, 0xfd, 0x65, 0x13, 0x04, 0x7c, 0xfc, - 0x03, 0x97, 0xf0, 0xd5, 0x62, 0xdc, 0x0d, 0xbf}; - static const PRUint8 rsa_prime1[FIPS_RSA_PRIME1_LENGTH] = { - 0xdb, 0x1e, 0xa7, 0x3d, 0xe7, 0xfa, 0x8b, 0x04, - 0x83, 0x48, 0xf3, 0xa5, 0x31, 0x9d, 0x35, 0x5e, - 0x4d, 0x54, 0x77, 0xcc, 0x84, 0x09, 0xf3, 0x11, - 0x0d, 0x54, 0xed, 0x85, 0x39, 0xa9, 0xca, 0xa8, - 0xea, 0xae, 0x19, 0x9c, 0x75, 0xdb, 0x88, 0xb8, - 0x04, 0x8d, 0x54, 0xc6, 0xa4, 0x80, 0xf8, 0x93, - 0xf0, 0xdb, 0x19, 0xef, 0xd7, 0x87, 0x8a, 0x8f, - 0x5a, 0x09, 0x2e, 0x54, 0xf3, 0x45, 0x24, 0x29}; - static const PRUint8 rsa_exponent0[FIPS_RSA_EXPONENT0_LENGTH] = { - 0x6a, 0xd1, 0x25, 0x80, 0x18, 0x33, 0x3c, 0x2b, - 0x44, 0x19, 0xfe, 0xa5, 0x40, 0x03, 0xc4, 0xfc, - 0xb3, 0x9c, 0xef, 0x07, 0x99, 0x58, 0x17, 0xc1, - 0x44, 0xa3, 0x15, 0x7d, 0x7b, 0x22, 0x22, 0xdf, - 0x03, 0x58, 0x66, 0xf5, 0x24, 0x54, 0x52, 0x91, - 0x2d, 0x76, 0xfe, 0x63, 0x64, 0x4e, 0x0f, 0x50, - 0x2b, 0x65, 0x79, 0x1f, 0xf1, 0xbf, 0xc7, 0x41, - 0x26, 0xcc, 0xc6, 0x1c, 0xa9, 0x83, 0x6f, 0x03}; - static const PRUint8 rsa_exponent1[FIPS_RSA_EXPONENT1_LENGTH] = { - 0x12, 0x84, 0x1a, 0x99, 0xce, 0x9a, 0x8b, 0x58, - 0xcc, 0x47, 0x43, 0xdf, 0x77, 0xbb, 0xd3, 0x20, - 0xae, 0xe4, 0x2e, 0x63, 0x67, 0xdc, 0xf7, 0x5f, - 0x3f, 0x83, 0x27, 0xb7, 0x14, 0x52, 0x56, 0xbf, - 0xc3, 0x65, 0x06, 0xe1, 0x03, 0xcc, 0x93, 0x57, - 0x09, 0x7b, 0x6f, 0xe8, 0x81, 0x4a, 0x2c, 0xb7, - 0x43, 0xa9, 0x20, 0x1d, 0xf6, 0x56, 0x8b, 0xcc, - 0xe5, 0x4c, 0xd5, 0x4f, 0x74, 0x67, 0x29, 0x51}; - static const PRUint8 rsa_coefficient[FIPS_RSA_COEFFICIENT_LENGTH] = { - 0x23, 0xab, 0xf4, 0x03, 0x2f, 0x29, 0x95, 0x74, - 0xac, 0x1a, 0x33, 0x96, 0x62, 0xed, 0xf7, 0xf6, - 0xae, 0x07, 0x2a, 0x2e, 0xe8, 0xab, 0xfb, 0x1e, - 0xb9, 0xb2, 0x88, 0x1e, 0x85, 0x05, 0x42, 0x64, - 0x03, 0xb2, 0x8b, 0xc1, 0x81, 0x75, 0xd7, 0xba, - 0xaa, 0xd4, 0x31, 0x3c, 0x8a, 0x96, 0x23, 0x9d, - 0x3f, 0x06, 0x3e, 0x44, 0xa9, 0x62, 0x2f, 0x61, - 0x5a, 0x51, 0x82, 0x2c, 0x04, 0x85, 0x73, 0xd1}; - - /* RSA Known Plaintext Message (1024-bits). */ - static const PRUint8 rsa_known_plaintext_msg[FIPS_RSA_MESSAGE_LENGTH] = { - "Known plaintext message utilized" - "for RSA Encryption & Decryption" - "block, SHA1, SHA256, SHA384 and" - "SHA512 RSA Signature KAT tests."}; - - /* RSA Known Ciphertext (1024-bits). */ - static const PRUint8 rsa_known_ciphertext[] = { - 0x1e, 0x7e, 0x12, 0xbb, 0x15, 0x62, 0xd0, 0x23, - 0x53, 0x4c, 0x51, 0x97, 0x77, 0x06, 0xa0, 0xbb, - 0x26, 0x99, 0x9a, 0x8f, 0x39, 0xad, 0x88, 0x5c, - 0xc4, 0xce, 0x33, 0x40, 0x94, 0x92, 0xb4, 0x0e, - 0xab, 0x71, 0xa9, 0x5d, 0x9a, 0x37, 0xe3, 0x9a, - 0x24, 0x95, 0x13, 0xea, 0x0f, 0xbb, 0xf7, 0xff, - 0xdf, 0x31, 0x33, 0x23, 0x1d, 0xce, 0x26, 0x9e, - 0xd1, 0xde, 0x98, 0x40, 0xde, 0x57, 0x86, 0x12, - 0xf1, 0xe6, 0x5a, 0x3f, 0x08, 0x02, 0x81, 0x85, - 0xe0, 0xd9, 0xad, 0x3c, 0x8c, 0x71, 0xf8, 0xcf, - 0x0a, 0x98, 0xc5, 0x08, 0xdc, 0xc4, 0xca, 0x8c, - 0x23, 0x1b, 0x4d, 0x9b, 0xb5, 0x13, 0x44, 0xe1, - 0x5f, 0xf9, 0x30, 0x80, 0x25, 0xe0, 0x1e, 0x94, - 0xa3, 0x0c, 0xdc, 0x82, 0x2e, 0xfb, 0x30, 0xbe, - 0x89, 0xba, 0x76, 0xb6, 0x23, 0xf7, 0xda, 0x7c, - 0xca, 0xe6, 0x02, 0xbd, 0x92, 0xce, 0x64, 0xfc}; - - /* RSA Known Signed Hash (1024-bits). */ - static const PRUint8 rsa_known_sha1_signature[] = { - 0xd2, 0xa4, 0xe0, 0x2b, 0xc7, 0x03, 0x7f, 0xc6, - 0x06, 0x9e, 0xa2, 0x82, 0x19, 0xe9, 0x2b, 0xaf, - 0xe3, 0x48, 0x88, 0xc1, 0xf3, 0xb5, 0x0d, 0xe4, - 0x52, 0x9e, 0xad, 0xd5, 0x58, 0xb5, 0x9f, 0xe8, - 0x40, 0xe9, 0xb7, 0x2e, 0xc6, 0x71, 0x58, 0x56, - 0x04, 0xac, 0xb0, 0xf3, 0x3a, 0x42, 0x38, 0x08, - 0xc4, 0x43, 0x39, 0xba, 0x19, 0xce, 0xb1, 0x99, - 0xf1, 0x8d, 0x89, 0xd8, 0x50, 0x07, 0x14, 0x3d, - 0xcf, 0xd0, 0xb6, 0x79, 0xde, 0x9c, 0x89, 0x32, - 0xb0, 0x73, 0x3f, 0xed, 0x03, 0x0b, 0xdf, 0x6d, - 0x7e, 0xc9, 0x1c, 0x39, 0xe8, 0x2b, 0x16, 0x09, - 0xbb, 0x5f, 0x99, 0x2f, 0xeb, 0xf3, 0x37, 0x73, - 0x0d, 0x0e, 0xcc, 0x95, 0xad, 0x90, 0x80, 0x03, - 0x1d, 0x80, 0x55, 0x37, 0xa1, 0x2a, 0x71, 0x76, - 0x23, 0x87, 0x8c, 0x9b, 0x41, 0x07, 0xc6, 0x3d, - 0xc6, 0xa3, 0x7d, 0x1b, 0xff, 0x4e, 0x11, 0x19}; - - /* RSA Known Signed Hash (1024-bits). */ - static const PRUint8 rsa_known_sha256_signature[] = { - 0x27, 0x35, 0xdd, 0xc4, 0xf8, 0xe2, 0x0b, 0xa3, - 0xef, 0x63, 0x57, 0x3b, 0xe1, 0x58, 0x9a, 0xbc, - 0x20, 0x9c, 0x25, 0x12, 0x01, 0xbf, 0xbb, 0x29, - 0x80, 0x1a, 0xb1, 0x37, 0x9c, 0xcd, 0x67, 0xc7, - 0x0d, 0xf8, 0x64, 0x10, 0x9f, 0xe2, 0xa1, 0x9b, - 0x21, 0x90, 0xcc, 0xda, 0x8b, 0x76, 0x5e, 0x79, - 0x00, 0x9d, 0x58, 0x8b, 0x8a, 0xb3, 0xc3, 0xb5, - 0xf1, 0x54, 0xc5, 0x8c, 0x72, 0xba, 0xde, 0x51, - 0x3c, 0x6b, 0x94, 0xd6, 0xf3, 0x1b, 0xa2, 0x53, - 0xe6, 0x1a, 0x46, 0x1d, 0x7f, 0x14, 0x86, 0xcc, - 0xa6, 0x30, 0x92, 0x96, 0xc0, 0x96, 0x24, 0xf0, - 0x42, 0x53, 0x4c, 0xdd, 0x27, 0xdf, 0x1d, 0x2e, - 0x8b, 0x83, 0xbe, 0xed, 0x85, 0x1d, 0x50, 0x46, - 0xa3, 0x7d, 0x20, 0xea, 0x3e, 0x91, 0xfb, 0xf6, - 0x86, 0x51, 0xfd, 0x8c, 0xe5, 0x31, 0xe6, 0x7e, - 0x60, 0x08, 0x0e, 0xec, 0xa6, 0xea, 0x24, 0x8d}; - - /* RSA Known Signed Hash (1024-bits). */ - static const PRUint8 rsa_known_sha384_signature[] = { - 0x0b, 0x03, 0x94, 0x4f, 0x94, 0x78, 0x9b, 0x96, - 0x76, 0xeb, 0x72, 0x58, 0xe1, 0xc5, 0xc7, 0x5f, - 0x85, 0x01, 0xa8, 0xc4, 0xf6, 0x1a, 0xb5, 0x2c, - 0xd1, 0xd8, 0x87, 0xde, 0x3a, 0x9c, 0x9f, 0x57, - 0x81, 0x2a, 0x1e, 0x23, 0x07, 0x70, 0xb0, 0xf9, - 0x28, 0x3d, 0xfa, 0xe5, 0x2e, 0x1b, 0x9a, 0x72, - 0xc3, 0x74, 0xb3, 0x42, 0x1c, 0x9a, 0x13, 0xdc, - 0xc9, 0xd6, 0xd5, 0x88, 0xc9, 0x9c, 0x46, 0xf1, - 0x0c, 0xa6, 0xf7, 0xd8, 0x06, 0xa3, 0x1b, 0xdf, - 0x55, 0xb3, 0x1b, 0x7b, 0x58, 0x1d, 0xff, 0x19, - 0xc7, 0xe0, 0xdd, 0x59, 0xac, 0x2f, 0x78, 0x71, - 0xe7, 0xe0, 0x17, 0xa3, 0x1c, 0x5c, 0x92, 0xef, - 0xb6, 0x75, 0xed, 0xbe, 0x18, 0x39, 0x6b, 0xd7, - 0xc9, 0x08, 0x62, 0x55, 0x62, 0xac, 0x5d, 0xa1, - 0x9b, 0xd5, 0xb8, 0x98, 0x15, 0xc0, 0xf5, 0x41, - 0x85, 0x44, 0x96, 0xca, 0x10, 0xdc, 0x57, 0x21}; - - /* RSA Known Signed Hash (1024-bits). */ - static const PRUint8 rsa_known_sha512_signature[] = { - 0xa5, 0xd0, 0x80, 0x04, 0x22, 0xfc, 0x80, 0x73, - 0x7d, 0x46, 0xc8, 0x7b, 0xac, 0x44, 0x7b, 0xe6, - 0x07, 0xe5, 0x61, 0x4c, 0x33, 0x7f, 0x6f, 0x46, - 0x7c, 0x30, 0xe3, 0x75, 0x59, 0x4b, 0x42, 0xf3, - 0x9f, 0x35, 0x3c, 0x10, 0x56, 0xdb, 0xd2, 0x69, - 0x43, 0xcb, 0x77, 0xe9, 0x7d, 0xcd, 0x07, 0x43, - 0xc5, 0xd4, 0x0c, 0x9d, 0xf5, 0x92, 0xbd, 0x0e, - 0x3b, 0xb7, 0x68, 0x88, 0x84, 0xca, 0xae, 0x0d, - 0xab, 0x71, 0x10, 0xad, 0xab, 0x27, 0xe4, 0xa3, - 0x24, 0x41, 0xeb, 0x1c, 0xa6, 0x5f, 0xf1, 0x85, - 0xd0, 0xf6, 0x22, 0x74, 0x3d, 0x81, 0xbe, 0xdd, - 0x1b, 0x2a, 0x4c, 0xd1, 0x6c, 0xb5, 0x6d, 0x7a, - 0xbb, 0x99, 0x69, 0x01, 0xa6, 0xc0, 0x98, 0xfa, - 0x97, 0xa3, 0xd1, 0xb0, 0xdf, 0x09, 0xe3, 0x3d, - 0x88, 0xee, 0x90, 0xf3, 0x10, 0x41, 0x0f, 0x06, - 0x31, 0xe9, 0x60, 0x2d, 0xbf, 0x63, 0x7b, 0xf8}; - - static const RSAPublicKey bl_public_key = { NULL, - { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, - FIPS_RSA_MODULUS_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, - FIPS_RSA_PUBLIC_EXPONENT_LENGTH } - }; - static const RSAPrivateKey bl_private_key = { NULL, - { FIPS_RSA_TYPE, (unsigned char *)rsa_version, - FIPS_RSA_PRIVATE_VERSION_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, - FIPS_RSA_MODULUS_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, - FIPS_RSA_PUBLIC_EXPONENT_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent, - FIPS_RSA_PRIVATE_EXPONENT_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0, - FIPS_RSA_PRIME0_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1, - FIPS_RSA_PRIME1_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0, - FIPS_RSA_EXPONENT0_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1, - FIPS_RSA_EXPONENT1_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient, - FIPS_RSA_COEFFICIENT_LENGTH } - }; - - /* RSA variables. */ -#ifdef CREATE_TEMP_ARENAS - PLArenaPool * rsa_public_arena; - PLArenaPool * rsa_private_arena; -#endif - NSSLOWKEYPublicKey * rsa_public_key; - NSSLOWKEYPrivateKey * rsa_private_key; - SECStatus rsa_status; - - NSSLOWKEYPublicKey low_public_key = { NULL, NSSLOWKEYRSAKey, }; - NSSLOWKEYPrivateKey low_private_key = { NULL, NSSLOWKEYRSAKey, }; - PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH]; - PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH]; - - /****************************************/ - /* Compose RSA Public/Private Key Pair. */ - /****************************************/ - - low_public_key.u.rsa = bl_public_key; - low_private_key.u.rsa = bl_private_key; - - rsa_public_key = &low_public_key; - rsa_private_key = &low_private_key; - -#ifdef CREATE_TEMP_ARENAS - /* Create some space for the RSA public key. */ - rsa_public_arena = PORT_NewArena( NSS_SOFTOKEN_DEFAULT_CHUNKSIZE ); - - if( rsa_public_arena == NULL ) { - PORT_SetError( SEC_ERROR_NO_MEMORY ); - return( CKR_HOST_MEMORY ); - } - - /* Create some space for the RSA private key. */ - rsa_private_arena = PORT_NewArena( NSS_SOFTOKEN_DEFAULT_CHUNKSIZE ); - - if( rsa_private_arena == NULL ) { - PORT_FreeArena( rsa_public_arena, PR_TRUE ); - PORT_SetError( SEC_ERROR_NO_MEMORY ); - return( CKR_HOST_MEMORY ); - } - - rsa_public_key->arena = rsa_public_arena; - rsa_private_key->arena = rsa_private_arena; -#endif - - /**************************************************/ - /* RSA Single-Round Known Answer Encryption Test. */ - /**************************************************/ - - /* Perform RSA Public Key Encryption. */ - rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa, - rsa_computed_ciphertext, - rsa_known_plaintext_msg); - - if( ( rsa_status != SECSuccess ) || - ( PORT_Memcmp( rsa_computed_ciphertext, rsa_known_ciphertext, - FIPS_RSA_ENCRYPT_LENGTH ) != 0 ) ) - goto rsa_loser; - - /**************************************************/ - /* RSA Single-Round Known Answer Decryption Test. */ - /**************************************************/ - - /* Perform RSA Private Key Decryption. */ - rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa, - rsa_computed_plaintext, - rsa_known_ciphertext); - - if( ( rsa_status != SECSuccess ) || - ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext_msg, - FIPS_RSA_DECRYPT_LENGTH ) != 0 ) ) - goto rsa_loser; - - rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA1, - rsa_public_key, rsa_private_key, - rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, - rsa_known_sha1_signature); - if( rsa_status != SECSuccess ) - goto rsa_loser; - - rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA256, - rsa_public_key, rsa_private_key, - rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, - rsa_known_sha256_signature); - if( rsa_status != SECSuccess ) - goto rsa_loser; - - rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA384, - rsa_public_key, rsa_private_key, - rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, - rsa_known_sha384_signature); - if( rsa_status != SECSuccess ) - goto rsa_loser; - - rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA512, - rsa_public_key, rsa_private_key, - rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, - rsa_known_sha512_signature); - if( rsa_status != SECSuccess ) - goto rsa_loser; - - /* Dispose of all RSA key material. */ - nsslowkey_DestroyPublicKey( rsa_public_key ); - nsslowkey_DestroyPrivateKey( rsa_private_key ); - - return( CKR_OK ); - -rsa_loser: - - nsslowkey_DestroyPublicKey( rsa_public_key ); - nsslowkey_DestroyPrivateKey( rsa_private_key ); - - return( CKR_DEVICE_ERROR ); -} - -#ifdef NSS_ENABLE_ECC - -static CK_RV -sftk_fips_ECDSA_Test(const PRUint8 *encodedParams, - unsigned int encodedParamsLen, - const PRUint8 *knownSignature, - unsigned int knownSignatureLen) { - - /* ECDSA Known Seed info for curves nistp256 and nistk283 */ - static const PRUint8 ecdsa_Known_Seed[] = { - 0x6a, 0x9b, 0xf6, 0xf7, 0xce, 0xed, 0x79, 0x11, - 0xf0, 0xc7, 0xc8, 0x9a, 0xa5, 0xd1, 0x57, 0xb1, - 0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc, - 0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f}; - - static const PRUint8 msg[] = { - "Firefox and ThunderBird are awesome!"}; - - unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */ - unsigned char sig[2*MAX_ECKEY_LEN]; - SECItem signature, digest; - SECItem encodedparams; - ECParams *ecparams = NULL; - ECPrivateKey *ecdsa_private_key = NULL; - ECPublicKey ecdsa_public_key; - SECStatus ecdsaStatus = SECSuccess; - - /* construct the ECDSA private/public key pair */ - encodedparams.type = siBuffer; - encodedparams.data = (unsigned char *) encodedParams; - encodedparams.len = encodedParamsLen; - - if (EC_DecodeParams(&encodedparams, &ecparams) != SECSuccess) { - return( CKR_DEVICE_ERROR ); - } - - /* Generates a new EC key pair. The private key is a supplied - * random value (in seed) and the public key is the result of - * performing a scalar point multiplication of that value with - * the curve's base point. - */ - ecdsaStatus = EC_NewKeyFromSeed(ecparams, &ecdsa_private_key, - ecdsa_Known_Seed, - sizeof(ecdsa_Known_Seed)); - /* free the ecparams they are no longer needed */ - PORT_FreeArena(ecparams->arena, PR_FALSE); - ecparams = NULL; - if (ecdsaStatus != SECSuccess) { - return ( CKR_DEVICE_ERROR ); - } - - /* construct public key from private key. */ - ecdsaStatus = EC_CopyParams(ecdsa_private_key->ecParams.arena, - &ecdsa_public_key.ecParams, - &ecdsa_private_key->ecParams); - if (ecdsaStatus != SECSuccess) { - goto loser; - } - ecdsa_public_key.publicValue = ecdsa_private_key->publicValue; - - /* validate public key value */ - ecdsaStatus = EC_ValidatePublicKey(&ecdsa_public_key.ecParams, - &ecdsa_public_key.publicValue); - if (ecdsaStatus != SECSuccess) { - goto loser; - } - - /* validate public key value */ - ecdsaStatus = EC_ValidatePublicKey(&ecdsa_private_key->ecParams, - &ecdsa_private_key->publicValue); - if (ecdsaStatus != SECSuccess) { - goto loser; - } - - /***************************************************/ - /* ECDSA Single-Round Known Answer Signature Test. */ - /***************************************************/ - - ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg); - if (ecdsaStatus != SECSuccess) { - goto loser; - } - digest.type = siBuffer; - digest.data = sha1; - digest.len = SHA1_LENGTH; - - memset(sig, 0, sizeof sig); - signature.type = siBuffer; - signature.data = sig; - signature.len = sizeof sig; - - ecdsaStatus = ECDSA_SignDigestWithSeed(ecdsa_private_key, &signature, - &digest, ecdsa_Known_Seed, sizeof ecdsa_Known_Seed); - if (ecdsaStatus != SECSuccess) { - goto loser; - } - - if( ( signature.len != knownSignatureLen ) || - ( PORT_Memcmp( signature.data, knownSignature, - knownSignatureLen ) != 0 ) ) { - ecdsaStatus = SECFailure; - goto loser; - } - - /******************************************************/ - /* ECDSA Single-Round Known Answer Verification Test. */ - /******************************************************/ - - /* Perform ECDSA verification process. */ - ecdsaStatus = ECDSA_VerifyDigest(&ecdsa_public_key, &signature, &digest); - -loser: - /* free the memory for the private key arena*/ - if (ecdsa_private_key != NULL) { - PORT_FreeArena(ecdsa_private_key->ecParams.arena, PR_FALSE); - } - - if (ecdsaStatus != SECSuccess) { - return CKR_DEVICE_ERROR ; - } - return( CKR_OK ); -} - -static CK_RV -sftk_fips_ECDSA_PowerUpSelfTest() { - - /* ECDSA Known curve nistp256 == SEC_OID_SECG_EC_SECP256R1 params */ - static const PRUint8 ecdsa_known_P256_EncodedParams[] = { - 0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03, - 0x01,0x07}; - - static const PRUint8 ecdsa_known_P256_signature[] = { - 0x07,0xb1,0xcb,0x57,0x20,0xa7,0x10,0xd6, - 0x9d,0x37,0x4b,0x1c,0xdc,0x35,0x90,0xff, - 0x1a,0x2d,0x98,0x95,0x1b,0x2f,0xeb,0x7f, - 0xbb,0x81,0xca,0xc0,0x69,0x75,0xea,0xc5, - 0x59,0x6a,0x62,0x49,0x3d,0x50,0xc9,0xe1, - 0x27,0x3b,0xff,0x9b,0x13,0x66,0x67,0xdd, - 0x7d,0xd1,0x0d,0x2d,0x7c,0x44,0x04,0x1b, - 0x16,0x21,0x12,0xc5,0xcb,0xbd,0x9e,0x75}; - -#ifdef NSS_ECC_MORE_THAN_SUITE_B - /* ECDSA Known curve nistk283 == SEC_OID_SECG_EC_SECT283K1 params */ - static const PRUint8 ecdsa_known_K283_EncodedParams[] = { - 0x06,0x05,0x2b,0x81,0x04,0x00,0x10}; - - static const PRUint8 ecdsa_known_K283_signature[] = { - 0x00,0x45,0x88,0xc0,0x79,0x09,0x07,0xd1, - 0x4e,0x88,0xe6,0xd5,0x2f,0x22,0x04,0x74, - 0x35,0x24,0x65,0xe8,0x15,0xde,0x90,0x66, - 0x94,0x70,0xdd,0x3a,0x14,0x70,0x02,0xd1, - 0xef,0x86,0xbd,0x15,0x00,0xd9,0xdc,0xfc, - 0x87,0x2e,0x7c,0x99,0xe2,0xe3,0x79,0xb8, - 0xd9,0x10,0x49,0x78,0x4b,0x59,0x8b,0x05, - 0x77,0xec,0x6c,0xe8,0x35,0xe6,0x2e,0xa9, - 0xf9,0x77,0x1f,0x71,0x86,0xa5,0x4a,0xd0}; -#endif - - CK_RV crv; - - /* ECDSA GF(p) prime field curve test */ - crv = sftk_fips_ECDSA_Test(ecdsa_known_P256_EncodedParams, - sizeof ecdsa_known_P256_EncodedParams, - ecdsa_known_P256_signature, - sizeof ecdsa_known_P256_signature ); - if (crv != CKR_OK) { - return( CKR_DEVICE_ERROR ); - } - -#ifdef NSS_ECC_MORE_THAN_SUITE_B - /* ECDSA GF(2m) binary field curve test */ - crv = sftk_fips_ECDSA_Test(ecdsa_known_K283_EncodedParams, - sizeof ecdsa_known_K283_EncodedParams, - ecdsa_known_K283_signature, - sizeof ecdsa_known_K283_signature ); - if (crv != CKR_OK) { - return( CKR_DEVICE_ERROR ); - } -#endif - - return( CKR_OK ); -} - -#endif /* NSS_ENABLE_ECC */ - -static CK_RV -sftk_fips_DSA_PowerUpSelfTest( void ) -{ - /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */ - static const PRUint8 dsa_P[] = { - 0x80,0xb0,0xd1,0x9d,0x6e,0xa4,0xf3,0x28, - 0x9f,0x24,0xa9,0x8a,0x49,0xd0,0x0c,0x63, - 0xe8,0x59,0x04,0xf9,0x89,0x4a,0x5e,0xc0, - 0x6d,0xd2,0x67,0x6b,0x37,0x81,0x83,0x0c, - 0xfe,0x3a,0x8a,0xfd,0xa0,0x3b,0x08,0x91, - 0x1c,0xcb,0xb5,0x63,0xb0,0x1c,0x70,0xd0, - 0xae,0xe1,0x60,0x2e,0x12,0xeb,0x54,0xc7, - 0xcf,0xc6,0xcc,0xae,0x97,0x52,0x32,0x63, - 0xd3,0xeb,0x55,0xea,0x2f,0x4c,0xd5,0xd7, - 0x3f,0xda,0xec,0x49,0x27,0x0b,0x14,0x56, - 0xc5,0x09,0xbe,0x4d,0x09,0x15,0x75,0x2b, - 0xa3,0x42,0x0d,0x03,0x71,0xdf,0x0f,0xf4, - 0x0e,0xe9,0x0c,0x46,0x93,0x3d,0x3f,0xa6, - 0x6c,0xdb,0xca,0xe5,0xac,0x96,0xc8,0x64, - 0x5c,0xec,0x4b,0x35,0x65,0xfc,0xfb,0x5a, - 0x1b,0x04,0x1b,0xa1,0x0e,0xfd,0x88,0x15}; - - static const PRUint8 dsa_Q[] = { - 0xad,0x22,0x59,0xdf,0xe5,0xec,0x4c,0x6e, - 0xf9,0x43,0xf0,0x4b,0x2d,0x50,0x51,0xc6, - 0x91,0x99,0x8b,0xcf}; - - static const PRUint8 dsa_G[] = { - 0x78,0x6e,0xa9,0xd8,0xcd,0x4a,0x85,0xa4, - 0x45,0xb6,0x6e,0x5d,0x21,0x50,0x61,0xf6, - 0x5f,0xdf,0x5c,0x7a,0xde,0x0d,0x19,0xd3, - 0xc1,0x3b,0x14,0xcc,0x8e,0xed,0xdb,0x17, - 0xb6,0xca,0xba,0x86,0xa9,0xea,0x51,0x2d, - 0xc1,0xa9,0x16,0xda,0xf8,0x7b,0x59,0x8a, - 0xdf,0xcb,0xa4,0x67,0x00,0x44,0xea,0x24, - 0x73,0xe5,0xcb,0x4b,0xaf,0x2a,0x31,0x25, - 0x22,0x28,0x3f,0x16,0x10,0x82,0xf7,0xeb, - 0x94,0x0d,0xdd,0x09,0x22,0x14,0x08,0x79, - 0xba,0x11,0x0b,0xf1,0xff,0x2d,0x67,0xac, - 0xeb,0xb6,0x55,0x51,0x69,0x97,0xa7,0x25, - 0x6b,0x9c,0xa0,0x9b,0xd5,0x08,0x9b,0x27, - 0x42,0x1c,0x7a,0x69,0x57,0xe6,0x2e,0xed, - 0xa9,0x5b,0x25,0xe8,0x1f,0xd2,0xed,0x1f, - 0xdf,0xe7,0x80,0x17,0xba,0x0d,0x4d,0x38}; - - /* DSA Known Random Values (known random key block is 160-bits) */ - /* and (known random signature block is 160-bits). */ - static const PRUint8 dsa_known_random_key_block[] = { - "Mozilla Rules World!"}; - static const PRUint8 dsa_known_random_signature_block[] = { - "Random DSA Signature"}; - - /* DSA Known Digest (160-bits) */ - static const PRUint8 dsa_known_digest[] = { "DSA Signature Digest" }; - - /* DSA Known Signature (320-bits). */ - static const PRUint8 dsa_known_signature[] = { - 0x25,0x7c,0x3a,0x79,0x32,0x45,0xb7,0x32, - 0x70,0xca,0x62,0x63,0x2b,0xf6,0x29,0x2c, - 0x22,0x2a,0x03,0xce,0x48,0x15,0x11,0x72, - 0x7b,0x7e,0xf5,0x7a,0xf3,0x10,0x3b,0xde, - 0x34,0xc1,0x9e,0xd7,0x27,0x9e,0x77,0x38}; - - /* DSA variables. */ - DSAPrivateKey * dsa_private_key; - SECStatus dsa_status; - SECItem dsa_signature_item; - SECItem dsa_digest_item; - DSAPublicKey dsa_public_key; - PRUint8 dsa_computed_signature[FIPS_DSA_SIGNATURE_LENGTH]; - static const PQGParams dsa_pqg = { NULL, - { FIPS_DSA_TYPE, (unsigned char *)dsa_P, FIPS_DSA_PRIME_LENGTH }, - { FIPS_DSA_TYPE, (unsigned char *)dsa_Q, FIPS_DSA_SUBPRIME_LENGTH }, - { FIPS_DSA_TYPE, (unsigned char *)dsa_G, FIPS_DSA_BASE_LENGTH }}; - - /*******************************************/ - /* Generate a DSA public/private key pair. */ - /*******************************************/ - - /* Generate a DSA public/private key pair. */ - dsa_status = DSA_NewKeyFromSeed(&dsa_pqg, dsa_known_random_key_block, - &dsa_private_key); - - if( dsa_status != SECSuccess ) - return( CKR_HOST_MEMORY ); - - /* construct public key from private key. */ - dsa_public_key.params = dsa_private_key->params; - dsa_public_key.publicValue = dsa_private_key->publicValue; - - /*************************************************/ - /* DSA Single-Round Known Answer Signature Test. */ - /*************************************************/ - - dsa_signature_item.data = dsa_computed_signature; - dsa_signature_item.len = sizeof dsa_computed_signature; - - dsa_digest_item.data = (unsigned char *)dsa_known_digest; - dsa_digest_item.len = SHA1_LENGTH; - - /* Perform DSA signature process. */ - dsa_status = DSA_SignDigestWithSeed( dsa_private_key, - &dsa_signature_item, - &dsa_digest_item, - dsa_known_random_signature_block ); - - if( ( dsa_status != SECSuccess ) || - ( dsa_signature_item.len != FIPS_DSA_SIGNATURE_LENGTH ) || - ( PORT_Memcmp( dsa_computed_signature, dsa_known_signature, - FIPS_DSA_SIGNATURE_LENGTH ) != 0 ) ) { - dsa_status = SECFailure; - } else { - - /****************************************************/ - /* DSA Single-Round Known Answer Verification Test. */ - /****************************************************/ - - /* Perform DSA verification process. */ - dsa_status = DSA_VerifyDigest( &dsa_public_key, - &dsa_signature_item, - &dsa_digest_item); - } - - PORT_FreeArena(dsa_private_key->params.arena, PR_TRUE); - /* Don't free public key, it uses same arena as private key */ - - /* Verify DSA signature. */ - if( dsa_status != SECSuccess ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); - - -} - -static CK_RV -sftk_fips_RNG_PowerUpSelfTest( void ) -{ - static const PRUint8 entropy[] = { - 0x8e,0x9c,0x0d,0x25,0x75,0x22,0x04,0xf9, - 0xc5,0x79,0x10,0x8b,0x23,0x79,0x37,0x14, - 0x9f,0x2c,0xc7,0x0b,0x39,0xf8,0xee,0xef, - 0x95,0x0c,0x97,0x59,0xfc,0x0a,0x85,0x41, - 0x76,0x9d,0x6d,0x67,0x00,0x4e,0x19,0x12, - 0x02,0x16,0x53,0xea,0xf2,0x73,0xd7,0xd6, - 0x7f,0x7e,0xc8,0xae,0x9c,0x09,0x99,0x7d, - 0xbb,0x9e,0x48,0x7f,0xbb,0x96,0x46,0xb3, - 0x03,0x75,0xf8,0xc8,0x69,0x45,0x3f,0x97, - 0x5e,0x2e,0x48,0xe1,0x5d,0x58,0x97,0x4c}; - static const PRUint8 rng_known_result[] = { - 0x16,0xe1,0x8c,0x57,0x21,0xd8,0xf1,0x7e, - 0x5a,0xa0,0x16,0x0b,0x7e,0xa6,0x25,0xb4, - 0x24,0x19,0xdb,0x54,0xfa,0x35,0x13,0x66, - 0xbb,0xaa,0x2a,0x1b,0x22,0x33,0x2e,0x4a, - 0x14,0x07,0x9d,0x52,0xfc,0x73,0x61,0x48, - 0xac,0xc1,0x22,0xfc,0xa4,0xfc,0xac,0xa4, - 0xdb,0xda,0x5b,0x27,0x33,0xc4,0xb3,0xec, - 0xb0,0xf2,0xee,0x63,0x11,0x61,0xdb,0x30, - 0xd3,0x04,0x6b,0x96,0x22,0x1e,0x17,0x24, - 0x1a,0x54,0x70,0xf3,0x4d,0x1c,0x6a,0xb0, - 0xf9,0xe3,0xc8,0x07,0x97,0x5f,0xbb,0xe5, - 0xde,0xce,0xa9,0x3f,0x91,0xd3,0x82,0x33, - 0x11,0x3f,0x5b,0xb2,0xa9,0x1e,0x71,0x59, - 0x68,0x8f,0x7d,0x77,0xfd,0xf5,0xcb,0xc8, - 0x8f,0x51,0xb9,0x62,0x30,0x1b,0x12,0xa5, - 0x7a,0xe1,0xf3,0x15,0x49,0x15,0xe9,0xc4, - 0x3d,0x2d,0x1f,0x8c,0xe8,0x4e,0xd1,0xe6, - 0x4e,0xf1,0x7a,0x64,0x2e,0x05,0xd6,0xee, - 0xb8,0x7b,0x71,0x82,0x38,0x2b,0xc5,0xdd, - 0x3a,0x32,0xae,0x64,0x0e,0xed,0x30,0xb2, - 0x00,0x72,0x61,0x65,0xfb,0x09,0x26,0x68, - 0x3e,0x36,0xb3,0x15,0xe2,0x30,0xde,0x49, - 0xed,0x60,0xc5,0x40,0xe1,0x1a,0xe9,0x33, - 0x7f,0x77,0xb5,0xa9,0xf7,0xa1,0xb9,0xdb, - 0x77,0x61,0x00,0xc2,0x18,0xa1,0xa1,0x3a, - 0x0e,0x2a,0x6c,0xa1,0x3f,0x33,0xdd,0xb9, - 0x23,0x48,0x75,0x50,0xd3,0xbb,0xd9,0x0e, - 0xdb,0xb4,0x62,0x33,0x52,0x41,0x5c,0xfc, - 0xdd,0x89,0xd6,0x60,0xe8,0x2b,0x6f,0xb2, - 0x7f,0x4d,0x97,0x8c,0x69,0xa4,0x15,0x16, - 0x4c,0x7f,0x4d,0x8d,0x2e,0xec,0xfa,0x0e, - 0xfa,0x37,0xe9,0x9d,0x21,0x9b,0x69,0x2a, - 0xc5,0x4f,0x5b,0x59,0xe9,0x98,0x73,0x54, - 0x28,0x33,0x4d,0x7c,0x53,0x8c,0x43,0x2b, - 0xc7,0x0e,0xfb,0x35,0x9d,0xf7,0x2e,0x1a, - 0xaa,0x80,0xa3,0x70,0x2c,0x72,0x43,0xb0, - 0x35,0x3b,0xe2,0x58,0x63,0xf8,0x1d,0xcd, - 0x55,0x66,0xb8,0x1e,0x06,0xa5,0xb6,0x4d, - 0xc2,0x9f,0x9b,0xde,0xa3,0xda,0x67,0x0e, - 0xd9,0x4b,0xfd,0x29,0xba,0x16,0x4e,0x03, - 0xe9,0x04,0x9a,0x67,0xf8,0xc4,0xb7,0x01, - 0xba,0x3c,0x5f,0xdd,0x8e,0x56,0xf3,0xea, - 0xf4,0xfb,0x75,0x76,0x30,0x20,0xe6,0xec, - 0x44,0xc9,0x76,0xb2,0x21,0x0c,0x1c,0xb9, - 0x5f,0x27,0xff,0x09,0x45,0x2c,0x26,0xfd, - 0x27,0xb0,0xca,0x67,0xd3,0xb0,0x77,0x3e, - 0x10,0x46,0xdd,0x81,0x70,0x47,0x5c,0x12, - 0xe7,0x37,0x49,0x17,0xf5,0x04,0xbc,0x62, - 0xef,0xba,0x6e,0x1d,0xb9,0x42,0xb5,0xf9, - 0xda,0x2f,0x5b,0x05,0xa7,0x34,0x19,0xf6, - 0xa4,0xdb,0x45,0xb0,0x18,0x6b,0x32,0x75, - 0x0f,0x34,0xc8,0x1c,0x14,0xca,0x4f,0xf9, - 0x43,0x76,0xa5,0x41,0xeb,0xd4,0x37,0xc9, - 0xc8,0x94,0xe7,0x0f,0x4a,0xa1,0x72,0xc7, - 0x48,0xbd,0x1c,0x84,0x74,0x73,0xd1,0x73, - 0xcd,0x1e,0xf0,0xb9,0x66,0x00,0x63,0xab}; - static const PRUint8 Q[] = { - 0x85,0x89,0x9c,0x77,0xa3,0x79,0xff,0x1a, - 0x86,0x6f,0x2f,0x3e,0x2e,0xf9,0x8c,0x9c, - 0x9d,0xef,0xeb,0xed}; - static const PRUint8 GENX[] = { - 0x65,0x48,0xe3,0xca,0xac,0x64,0x2d,0xf7, - 0x7b,0xd3,0x4e,0x79,0xc9,0x7d,0xa6,0xa8, - 0xa2,0xc2,0x1f,0x8f,0xe9,0xb9,0xd3,0xa1, - 0x3f,0xf7,0x0c,0xcd,0xa6,0xca,0xbf,0xce, - 0x84,0x0e,0xb6,0xf1,0x0d,0xbe,0xa9,0xa3}; - static const PRUint8 rng_known_DSAX[] = { - 0x7a,0x86,0xf1,0x7f,0xbd,0x4e,0x6e,0xd9, - 0x0a,0x26,0x21,0xd0,0x19,0xcb,0x86,0x73, - 0x10,0x1f,0x60,0xd7}; - - - - SECStatus rng_status = SECSuccess; - PRUint8 result[sizeof(rng_known_result)]; - PRUint8 DSAX[FIPS_DSA_SUBPRIME_LENGTH]; - - /********************************************/ - /* Generate random bytes with a known seed. */ - /********************************************/ - rng_status = PRNGTEST_Instantiate(entropy, sizeof entropy, - NULL, 0, NULL, 0); - if (rng_status != SECSuccess) { - return ( CKR_DEVICE_ERROR ); - } - rng_status = PRNGTEST_Generate(result, sizeof result, NULL, 0); - if ( ( rng_status != SECSuccess) || - ( PORT_Memcmp( result, rng_known_result, - sizeof result ) != 0 ) ) { - return ( CKR_DEVICE_ERROR ); - } - rng_status = PRNGTEST_Uninstantiate(); - if (rng_status != SECSuccess) { - return ( CKR_DEVICE_ERROR ); - } - - /*******************************************/ - /* Generate DSAX fow given Q. */ - /*******************************************/ - - rng_status = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX); - - /* Verify DSAX to perform the RNG integrity check */ - if( ( rng_status != SECSuccess ) || - ( PORT_Memcmp( DSAX, rng_known_DSAX, - (FIPS_DSA_SUBPRIME_LENGTH) ) != 0 ) ) - return( CKR_DEVICE_ERROR ); - - return( CKR_OK ); -} - -static CK_RV -sftk_fipsSoftwareIntegrityTest(void) -{ - CK_RV crv = CKR_OK; - - /* make sure that our check file signatures are OK */ - if( !BLAPI_VerifySelf( NULL ) || - !BLAPI_SHVerify( SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_fips_HMAC ) ) { - crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */ - } - return crv; -} - -CK_RV -sftk_fipsPowerUpSelfTest( void ) -{ - CK_RV rv; - - /* RC2 Power-Up SelfTest(s). */ - rv = sftk_fips_RC2_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* RC4 Power-Up SelfTest(s). */ - rv = sftk_fips_RC4_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* DES Power-Up SelfTest(s). */ - rv = sftk_fips_DES_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* DES3 Power-Up SelfTest(s). */ - rv = sftk_fips_DES3_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* AES Power-Up SelfTest(s) for 128-bit key. */ - rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_128_KEY_SIZE); - - if( rv != CKR_OK ) - return rv; - - /* AES Power-Up SelfTest(s) for 192-bit key. */ - rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_192_KEY_SIZE); - - if( rv != CKR_OK ) - return rv; - - /* AES Power-Up SelfTest(s) for 256-bit key. */ - rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_256_KEY_SIZE); - - if( rv != CKR_OK ) - return rv; - - /* MD2 Power-Up SelfTest(s). */ - rv = sftk_fips_MD2_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* MD5 Power-Up SelfTest(s). */ - rv = sftk_fips_MD5_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* SHA-X Power-Up SelfTest(s). */ - rv = sftk_fips_SHA_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* HMAC SHA-X Power-Up SelfTest(s). */ - rv = sftk_fips_HMAC_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* RSA Power-Up SelfTest(s). */ - rv = sftk_fips_RSA_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* DSA Power-Up SelfTest(s). */ - rv = sftk_fips_DSA_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - - /* RNG Power-Up SelfTest(s). */ - rv = sftk_fips_RNG_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; - -#ifdef NSS_ENABLE_ECC - /* ECDSA Power-Up SelfTest(s). */ - rv = sftk_fips_ECDSA_PowerUpSelfTest(); - - if( rv != CKR_OK ) - return rv; -#endif - - /* Software/Firmware Integrity Test. */ - rv = sftk_fipsSoftwareIntegrityTest(); - - if( rv != CKR_OK ) - return rv; - - /* Passed Power-Up SelfTest(s). */ - return( CKR_OK ); -} - diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c deleted file mode 100644 index 96fc6f2f0..000000000 --- a/security/nss/lib/softoken/fipstokn.c +++ /dev/null @@ -1,1607 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * This file implements PKCS 11 on top of our existing security modules - * - * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. - * This implementation has two slots: - * slot 1 is our generic crypto support. It does not require login - * (unless you've enabled FIPS). It supports Public Key ops, and all they - * bulk ciphers and hashes. It can also support Private Key ops for imported - * Private keys. It does not have any token storage. - * slot 2 is our private key support. It requires a login before use. It - * can store Private Keys and Certs as token objects. Currently only private - * keys and their associated Certificates are saved on the token. - * - * In this implementation, session objects are only visible to the session - * that created or generated them. - */ -#include "seccomon.h" -#include "softoken.h" -#include "lowkeyi.h" -#include "pkcs11.h" -#include "pkcs11i.h" -#include "prenv.h" -#include "prprf.h" - -#include <ctype.h> - -#ifdef XP_UNIX -#define NSS_AUDIT_WITH_SYSLOG 1 -#include <syslog.h> -#include <unistd.h> -#endif - -#ifdef SOLARIS -#include <bsm/libbsm.h> -#define AUE_FIPS_AUDIT 34444 -#endif - -#ifdef LINUX -#include <pthread.h> -#include <dlfcn.h> -#define LIBAUDIT_NAME "libaudit.so.0" -#ifndef AUDIT_CRYPTO_TEST_USER -#define AUDIT_CRYPTO_TEST_USER 2400 /* Crypto test results */ -#define AUDIT_CRYPTO_PARAM_CHANGE_USER 2401 /* Crypto attribute change */ -#define AUDIT_CRYPTO_LOGIN 2402 /* Logged in as crypto officer */ -#define AUDIT_CRYPTO_LOGOUT 2403 /* Logged out from crypto */ -#define AUDIT_CRYPTO_KEY_USER 2404 /* Create,delete,negotiate */ -#define AUDIT_CRYPTO_FAILURE_USER 2405 /* Fail decrypt,encrypt,randomize */ -#endif -static void *libaudit_handle; -static int (*audit_open_func)(void); -static void (*audit_close_func)(int fd); -static int (*audit_log_user_message_func)(int audit_fd, int type, - const char *message, const char *hostname, const char *addr, - const char *tty, int result); -static int (*audit_send_user_message_func)(int fd, int type, - const char *message); - -static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT; - -static void -libaudit_init(void) -{ - libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY); - if (!libaudit_handle) { - return; - } - audit_open_func = dlsym(libaudit_handle, "audit_open"); - audit_close_func = dlsym(libaudit_handle, "audit_close"); - /* - * audit_send_user_message is the older function. - * audit_log_user_message, if available, is preferred. - */ - audit_log_user_message_func = dlsym(libaudit_handle, - "audit_log_user_message"); - if (!audit_log_user_message_func) { - audit_send_user_message_func = dlsym(libaudit_handle, - "audit_send_user_message"); - } - if (!audit_open_func || !audit_close_func || - (!audit_log_user_message_func && !audit_send_user_message_func)) { - dlclose(libaudit_handle); - libaudit_handle = NULL; - audit_open_func = NULL; - audit_close_func = NULL; - audit_log_user_message_func = NULL; - audit_send_user_message_func = NULL; - } -} -#endif /* LINUX */ - - -/* - * ******************** Password Utilities ******************************* - */ -static PRBool isLoggedIn = PR_FALSE; -PRBool sftk_fatalError = PR_FALSE; - -/* - * This function returns - * - CKR_PIN_INVALID if the password/PIN is not a legal UTF8 string - * - CKR_PIN_LEN_RANGE if the password/PIN is too short or does not - * consist of characters from three or more character classes. - * - CKR_OK otherwise - * - * The minimum password/PIN length is FIPS_MIN_PIN Unicode characters. - * We define five character classes: digits (0-9), ASCII lowercase letters, - * ASCII uppercase letters, ASCII non-alphanumeric characters (such as - * space and punctuation marks), and non-ASCII characters. If an ASCII - * uppercase letter is the first character of the password/PIN, the - * uppercase letter is not counted toward its character class. Similarly, - * if a digit is the last character of the password/PIN, the digit is not - * counted toward its character class. - * - * Although NSC_SetPIN and NSC_InitPIN already do the maximum and minimum - * password/PIN length checks, they check the length in bytes as opposed - * to characters. To meet the minimum password/PIN guessing probability - * requirements in FIPS 140-2, we need to check the length in characters. - */ -static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { - unsigned int i; - int nchar = 0; /* number of characters */ - int ntrail = 0; /* number of trailing bytes to follow */ - int ndigit = 0; /* number of decimal digits */ - int nlower = 0; /* number of ASCII lowercase letters */ - int nupper = 0; /* number of ASCII uppercase letters */ - int nnonalnum = 0; /* number of ASCII non-alphanumeric characters */ - int nnonascii = 0; /* number of non-ASCII characters */ - int nclass; /* number of character classes */ - - for (i = 0; i < ulPinLen; i++) { - unsigned int byte = pPin[i]; - - if (ntrail) { - if ((byte & 0xc0) != 0x80) { - /* illegal */ - nchar = -1; - break; - } - if (--ntrail == 0) { - nchar++; - nnonascii++; - } - continue; - } - if ((byte & 0x80) == 0x00) { - /* single-byte (ASCII) character */ - nchar++; - if (isdigit(byte)) { - if (i < ulPinLen - 1) { - ndigit++; - } - } else if (islower(byte)) { - nlower++; - } else if (isupper(byte)) { - if (i > 0) { - nupper++; - } - } else { - nnonalnum++; - } - } else if ((byte & 0xe0) == 0xc0) { - /* leading byte of two-byte character */ - ntrail = 1; - } else if ((byte & 0xf0) == 0xe0) { - /* leading byte of three-byte character */ - ntrail = 2; - } else if ((byte & 0xf8) == 0xf0) { - /* leading byte of four-byte character */ - ntrail = 3; - } else { - /* illegal */ - nchar = -1; - break; - } - } - if (nchar == -1) { - /* illegal UTF8 string */ - return CKR_PIN_INVALID; - } - if (nchar < FIPS_MIN_PIN) { - return CKR_PIN_LEN_RANGE; - } - nclass = (ndigit != 0) + (nlower != 0) + (nupper != 0) + - (nnonalnum != 0) + (nnonascii != 0); - if (nclass < 3) { - return CKR_PIN_LEN_RANGE; - } - return CKR_OK; -} - - -/* FIPS required checks before any useful cryptographic services */ -static CK_RV sftk_fipsCheck(void) { - if (sftk_fatalError) - return CKR_DEVICE_ERROR; - if (!isLoggedIn) - return CKR_USER_NOT_LOGGED_IN; - return CKR_OK; -} - - -#define SFTK_FIPSCHECK() \ - CK_RV rv; \ - if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; - -#define SFTK_FIPSFATALCHECK() \ - if (sftk_fatalError) return CKR_DEVICE_ERROR; - - -/* grab an attribute out of a raw template */ -void * -fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, CK_ATTRIBUTE_TYPE type) -{ - int i; - - for (i=0; i < (int) ulCount; i++) { - if (pTemplate[i].type == type) { - return pTemplate[i].pValue; - } - } - return NULL; -} - - -#define __PASTE(x,y) x##y - -/* ------------- forward declare all the NSC_ functions ------------- */ -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO - -#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS,name) -#define CK_NEED_ARG_LIST 1 - -#include "pkcs11f.h" - -/* ------------- forward declare all the FIPS functions ------------- */ -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO - -#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(F,name) -#define CK_NEED_ARG_LIST 1 - -#include "pkcs11f.h" - -/* ------------- build the CK_CRYPTO_TABLE ------------------------- */ -static CK_FUNCTION_LIST sftk_fipsTable = { - { 1, 10 }, - -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO - -#define CK_PKCS11_FUNCTION_INFO(name) __PASTE(F,name), - - -#include "pkcs11f.h" - -}; - -#undef CK_NEED_ARG_LIST -#undef CK_PKCS11_FUNCTION_INFO - - -#undef __PASTE - -/* CKO_NOT_A_KEY can be any object class that's not a key object. */ -#define CKO_NOT_A_KEY CKO_DATA - -#define SFTK_IS_KEY_OBJECT(objClass) \ - (((objClass) == CKO_PUBLIC_KEY) || \ - ((objClass) == CKO_PRIVATE_KEY) || \ - ((objClass) == CKO_SECRET_KEY)) - -#define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \ - (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY)) - -static CK_RV -sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass) -{ - CK_RV rv; - CK_ATTRIBUTE class; - class.type = CKA_CLASS; - class.pValue = pObjClass; - class.ulValueLen = sizeof(*pObjClass); - rv = NSC_GetAttributeValue(hSession, hObject, &class, 1); - if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) { - rv = sftk_fipsCheck(); - } - return rv; -} - -#ifdef LINUX - -int -sftk_mapLinuxAuditType(NSSAuditSeverity severity, NSSAuditType auditType) -{ - switch (auditType) { - case NSS_AUDIT_ACCESS_KEY: - case NSS_AUDIT_CHANGE_KEY: - case NSS_AUDIT_COPY_KEY: - case NSS_AUDIT_DERIVE_KEY: - case NSS_AUDIT_DESTROY_KEY: - case NSS_AUDIT_DIGEST_KEY: - case NSS_AUDIT_GENERATE_KEY: - case NSS_AUDIT_LOAD_KEY: - case NSS_AUDIT_UNWRAP_KEY: - case NSS_AUDIT_WRAP_KEY: - return AUDIT_CRYPTO_KEY_USER; - case NSS_AUDIT_CRYPT: - return (severity == NSS_AUDIT_ERROR) ? AUDIT_CRYPTO_FAILURE_USER : - AUDIT_CRYPTO_KEY_USER; - case NSS_AUDIT_FIPS_STATE: - case NSS_AUDIT_INIT_PIN: - case NSS_AUDIT_INIT_TOKEN: - case NSS_AUDIT_SET_PIN: - return AUDIT_CRYPTO_PARAM_CHANGE_USER; - case NSS_AUDIT_SELF_TEST: - return AUDIT_CRYPTO_TEST_USER; - case NSS_AUDIT_LOGIN: - return AUDIT_CRYPTO_LOGIN; - case NSS_AUDIT_LOGOUT: - return AUDIT_CRYPTO_LOGOUT; - /* we skip the fault case here so we can get compiler - * warnings if new 'NSSAuditType's are added without - * added them to this list, defaults fall through */ - } - /* default */ - return AUDIT_CRYPTO_PARAM_CHANGE_USER; -} -#endif - - -/********************************************************************** - * - * FIPS 140 auditable event logging - * - **********************************************************************/ - -PRBool sftk_audit_enabled = PR_FALSE; - -/* - * Each audit record must have the following information: - * - Date and time of the event - * - Type of event - * - user (subject) identity - * - outcome (success or failure) of the event - * - process ID - * - name (ID) of the object - * - for changes to data (except for authentication data and CSPs), the new - * and old values of the data - * - for authentication attempts, the origin of the attempt (e.g., terminal - * identifier) - * - for assuming a role, the type of role, and the location of the request - */ -void -sftk_LogAuditMessage(NSSAuditSeverity severity, NSSAuditType auditType, - const char *msg) -{ -#ifdef NSS_AUDIT_WITH_SYSLOG - int level; - - switch (severity) { - case NSS_AUDIT_ERROR: - level = LOG_ERR; - break; - case NSS_AUDIT_WARNING: - level = LOG_WARNING; - break; - default: - level = LOG_INFO; - break; - } - /* timestamp is provided by syslog in the message header */ - syslog(level | LOG_USER /* facility */, - "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s", - (int)getpid(), (int)getuid(), msg); -#ifdef LINUX - if (pthread_once(&libaudit_once_control, libaudit_init) != 0) { - return; - } - if (libaudit_handle) { - int audit_fd; - int linuxAuditType; - int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */ - char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); - if (!message) { - return; - } - audit_fd = audit_open_func(); - if (audit_fd < 0) { - PR_smprintf_free(message); - return; - } - linuxAuditType = sftk_mapLinuxAuditType(severity, auditType); - if (audit_log_user_message_func) { - audit_log_user_message_func(audit_fd, linuxAuditType, message, - NULL, NULL, NULL, result); - } else { - audit_send_user_message_func(audit_fd, linuxAuditType, message); - } - audit_close_func(audit_fd); - PR_smprintf_free(message); - } -#endif /* LINUX */ -#ifdef SOLARIS - { - int rd; - char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); - - if (!message) { - return; - } - - /* open the record descriptor */ - if ((rd = au_open()) == -1) { - PR_smprintf_free(message); - return; - } - - /* write the audit tokens to the audit record */ - if (au_write(rd, au_to_text(message))) { - (void)au_close(rd, AU_TO_NO_WRITE, AUE_FIPS_AUDIT); - PR_smprintf_free(message); - return; - } - - /* close the record and send it to the audit trail */ - (void)au_close(rd, AU_TO_WRITE, AUE_FIPS_AUDIT); - - PR_smprintf_free(message); - } -#endif /* SOLARIS */ -#else - /* do nothing */ -#endif -} - - -/********************************************************************** - * - * Start of PKCS 11 functions - * - **********************************************************************/ -/* return the function list */ -CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) { - - CHECK_FORK(); - - *pFunctionList = &sftk_fipsTable; - return CKR_OK; -} - -/* sigh global so pkcs11 can read it */ -PRBool nsf_init = PR_FALSE; - -/* FC_Initialize initializes the PKCS #11 library. */ -CK_RV FC_Initialize(CK_VOID_PTR pReserved) { - const char *envp; - CK_RV crv; - - sftk_ForkReset(pReserved, &crv); - - if (nsf_init) { - return CKR_CRYPTOKI_ALREADY_INITIALIZED; - } - - if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) { - sftk_audit_enabled = (atoi(envp) == 1); - } - - crv = nsc_CommonInitialize(pReserved, PR_TRUE); - - /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/ - if (crv != CKR_OK) { - sftk_fatalError = PR_TRUE; - return crv; - } - - sftk_fatalError = PR_FALSE; /* any error has been reset */ - - crv = sftk_fipsPowerUpSelfTest(); - if (crv != CKR_OK) { - nsc_CommonFinalize(NULL, PR_TRUE); - sftk_fatalError = PR_TRUE; - if (sftk_audit_enabled) { - char msg[128]; - PR_snprintf(msg,sizeof msg, - "C_Initialize()=0x%08lX " - "power-up self-tests failed", - (PRUint32)crv); - sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); - } - return crv; - } - nsf_init = PR_TRUE; - - return CKR_OK; -} - -/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/ -CK_RV FC_Finalize (CK_VOID_PTR pReserved) { - CK_RV crv; - - if (sftk_ForkReset(pReserved, &crv)) { - return crv; - } - - if (!nsf_init) { - return CKR_OK; - } - - crv = nsc_CommonFinalize (pReserved, PR_TRUE); - - nsf_init = (PRBool) !(crv == CKR_OK); - return crv; -} - - -/* FC_GetInfo returns general information about PKCS #11. */ -CK_RV FC_GetInfo(CK_INFO_PTR pInfo) { - CHECK_FORK(); - - return NSC_GetInfo(pInfo); -} - -/* FC_GetSlotList obtains a list of slots in the system. */ -CK_RV FC_GetSlotList(CK_BBOOL tokenPresent, - CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { - CHECK_FORK(); - - return nsc_CommonGetSlotList(tokenPresent,pSlotList,pulCount, - NSC_FIPS_MODULE); -} - -/* FC_GetSlotInfo obtains information about a particular slot in the system. */ -CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { - CHECK_FORK(); - - return NSC_GetSlotInfo(slotID,pInfo); -} - - -/*FC_GetTokenInfo obtains information about a particular token in the system.*/ - CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) { - CK_RV crv; - - CHECK_FORK(); - - crv = NSC_GetTokenInfo(slotID,pInfo); - if (crv == CKR_OK) - pInfo->flags |= CKF_LOGIN_REQUIRED; - return crv; - -} - - - -/*FC_GetMechanismList obtains a list of mechanism types supported by a token.*/ - CK_RV FC_GetMechanismList(CK_SLOT_ID slotID, - CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) { - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID; - /* FIPS Slot supports all functions */ - return NSC_GetMechanismList(slotID,pMechanismList,pusCount); -} - - -/* FC_GetMechanismInfo obtains information about a particular mechanism - * possibly supported by a token. */ - CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR pInfo) { - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID; - /* FIPS Slot supports all functions */ - return NSC_GetMechanismInfo(slotID,type,pInfo); -} - - -/* FC_InitToken initializes a token. */ - CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin, - CK_ULONG usPinLen,CK_CHAR_PTR pLabel) { - CK_RV crv; - - CHECK_FORK(); - - crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel); - if (sftk_audit_enabled) { - char msg[128]; - NSSAuditSeverity severity = (crv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - /* pLabel points to a 32-byte label, which is not null-terminated */ - PR_snprintf(msg,sizeof msg, - "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX", - (PRUint32)slotID,pLabel,(PRUint32)crv); - sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_TOKEN, msg); - } - return crv; -} - - -/* FC_InitPIN initializes the normal user's PIN. */ - CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession, - CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { - CK_RV rv; - - CHECK_FORK(); - - if (sftk_fatalError) return CKR_DEVICE_ERROR; - if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) { - rv = NSC_InitPIN(hSession,pPin,ulPinLen); - } - if (sftk_audit_enabled) { - char msg[128]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - PR_snprintf(msg,sizeof msg, - "C_InitPIN(hSession=0x%08lX)=0x%08lX", - (PRUint32)hSession,(PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_INIT_PIN, msg); - } - return rv; -} - - -/* FC_SetPIN modifies the PIN of user that is currently logged in. */ -/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */ - CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, - CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) { - CK_RV rv; - - CHECK_FORK(); - - if ((rv = sftk_fipsCheck()) == CKR_OK && - (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) { - rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen); - } - if (sftk_audit_enabled) { - char msg[128]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - PR_snprintf(msg,sizeof msg, - "C_SetPIN(hSession=0x%08lX)=0x%08lX", - (PRUint32)hSession,(PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_SET_PIN, msg); - } - return rv; -} - -/* FC_OpenSession opens a session between an application and a token. */ - CK_RV FC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, - CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) { - SFTK_FIPSFATALCHECK(); - - CHECK_FORK(); - - return NSC_OpenSession(slotID,flags,pApplication,Notify,phSession); -} - - -/* FC_CloseSession closes a session between an application and a token. */ - CK_RV FC_CloseSession(CK_SESSION_HANDLE hSession) { - CHECK_FORK(); - - return NSC_CloseSession(hSession); -} - - -/* FC_CloseAllSessions closes all sessions with a token. */ - CK_RV FC_CloseAllSessions (CK_SLOT_ID slotID) { - - CHECK_FORK(); - - return NSC_CloseAllSessions (slotID); -} - - -/* FC_GetSessionInfo obtains information about the session. */ - CK_RV FC_GetSessionInfo(CK_SESSION_HANDLE hSession, - CK_SESSION_INFO_PTR pInfo) { - CK_RV rv; - SFTK_FIPSFATALCHECK(); - - CHECK_FORK(); - - rv = NSC_GetSessionInfo(hSession,pInfo); - if (rv == CKR_OK) { - if ((isLoggedIn) && (pInfo->state == CKS_RO_PUBLIC_SESSION)) { - pInfo->state = CKS_RO_USER_FUNCTIONS; - } - if ((isLoggedIn) && (pInfo->state == CKS_RW_PUBLIC_SESSION)) { - pInfo->state = CKS_RW_USER_FUNCTIONS; - } - } - return rv; -} - -/* FC_Login logs a user into a token. */ - CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, - CK_CHAR_PTR pPin, CK_ULONG usPinLen) { - CK_RV rv; - PRBool successful; - if (sftk_fatalError) return CKR_DEVICE_ERROR; - rv = NSC_Login(hSession,userType,pPin,usPinLen); - successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); - if (successful) - isLoggedIn = PR_TRUE; - if (sftk_audit_enabled) { - char msg[128]; - NSSAuditSeverity severity; - severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - PR_snprintf(msg,sizeof msg, - "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX", - (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg); - } - return rv; -} - -/* FC_Logout logs a user out from a token. */ - CK_RV FC_Logout(CK_SESSION_HANDLE hSession) { - CK_RV rv; - - CHECK_FORK(); - - if ((rv = sftk_fipsCheck()) == CKR_OK) { - rv = NSC_Logout(hSession); - isLoggedIn = PR_FALSE; - } - if (sftk_audit_enabled) { - char msg[128]; - NSSAuditSeverity severity = (rv == CKR_OK) ? - NSS_AUDIT_INFO : NSS_AUDIT_ERROR; - PR_snprintf(msg,sizeof msg, - "C_Logout(hSession=0x%08lX)=0x%08lX", - (PRUint32)hSession,(PRUint32)rv); - sftk_LogAuditMessage(severity, NSS_AUDIT_LOGOUT, msg); - } - return rv; -} - - -/* FC_CreateObject creates a new object. */ - CK_RV FC_CreateObject(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phObject) { - CK_OBJECT_CLASS * classptr; - - SFTK_FIPSCHECK(); - CHECK_FORK(); - - classptr = (CK_OBJECT_CLASS *)fc_getAttribute(pTemplate,ulCount,CKA_CLASS); - if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE; - - /* FIPS can't create keys from raw key material */ - if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) { - rv = CKR_ATTRIBUTE_VALUE_INVALID; - } else { - rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject); - } - if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) { - sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv); - } - return rv; -} - - - - - -/* FC_CopyObject copies an object, creating a new object for the copy. */ - CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phNewObject) { - CK_RV rv; - CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; - - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); - if (rv == CKR_OK) { - rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject); - } - if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { - sftk_AuditCopyObject(hSession, - hObject,pTemplate,ulCount,phNewObject,rv); - } - return rv; -} - - -/* FC_DestroyObject destroys an object. */ - CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject) { - CK_RV rv; - CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; - - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); - if (rv == CKR_OK) { - rv = NSC_DestroyObject(hSession,hObject); - } - if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { - sftk_AuditDestroyObject(hSession,hObject,rv); - } - return rv; -} - - -/* FC_GetObjectSize gets the size of an object in bytes. */ - CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { - CK_RV rv; - CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; - - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); - if (rv == CKR_OK) { - rv = NSC_GetObjectSize(hSession, hObject, pulSize); - } - if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { - sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv); - } - return rv; -} - - -/* FC_GetAttributeValue obtains the value of one or more object attributes. */ - CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { - CK_RV rv; - CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; - - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); - if (rv == CKR_OK) { - rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount); - } - if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { - sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); - } - return rv; -} - - -/* FC_SetAttributeValue modifies the value of one or more object attributes */ - CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { - CK_RV rv; - CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; - - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); - if (rv == CKR_OK) { - rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount); - } - if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { - sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); - } - return rv; -} - - - -/* FC_FindObjectsInit initializes a search for token and session objects - * that match a template. */ - CK_RV FC_FindObjectsInit(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) { - /* let publically readable object be found */ - unsigned int i; - CK_RV rv; - PRBool needLogin = PR_FALSE; - - - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - - for (i=0; i < usCount; i++) { - CK_OBJECT_CLASS class; - if (pTemplate[i].type != CKA_CLASS) { - continue; - } - if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) { - continue; - } - if (pTemplate[i].pValue == NULL) { - continue; - } - class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; - if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) { - needLogin = PR_TRUE; - break; - } - } - if (needLogin) { - if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; - } - return NSC_FindObjectsInit(hSession,pTemplate,usCount); -} - - -/* FC_FindObjects continues a search for token and session objects - * that match a template, obtaining additional object handles. */ - CK_RV FC_FindObjects(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE_PTR phObject,CK_ULONG usMaxObjectCount, - CK_ULONG_PTR pusObjectCount) { - CHECK_FORK(); - - /* let publically readable object be found */ - SFTK_FIPSFATALCHECK(); - return NSC_FindObjects(hSession,phObject,usMaxObjectCount, - pusObjectCount); -} - - -/* - ************** Crypto Functions: Encrypt ************************ - */ - -/* FC_EncryptInit initializes an encryption operation. */ - CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_EncryptInit(hSession,pMechanism,hKey); - if (sftk_audit_enabled) { - sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv); - } - return rv; -} - -/* FC_Encrypt encrypts single-part data. */ - CK_RV FC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG usDataLen, CK_BYTE_PTR pEncryptedData, - CK_ULONG_PTR pusEncryptedDataLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_Encrypt(hSession,pData,usDataLen,pEncryptedData, - pusEncryptedDataLen); -} - - -/* FC_EncryptUpdate continues a multiple-part encryption operation. */ - CK_RV FC_EncryptUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pPart, CK_ULONG usPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pusEncryptedPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_EncryptUpdate(hSession,pPart,usPartLen,pEncryptedPart, - pusEncryptedPartLen); -} - - -/* FC_EncryptFinal finishes a multiple-part encryption operation. */ - CK_RV FC_EncryptFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pusLastEncryptedPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_EncryptFinal(hSession,pLastEncryptedPart, - pusLastEncryptedPartLen); -} - -/* - ************** Crypto Functions: Decrypt ************************ - */ - - -/* FC_DecryptInit initializes a decryption operation. */ - CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_DecryptInit(hSession,pMechanism,hKey); - if (sftk_audit_enabled) { - sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv); - } - return rv; -} - -/* FC_Decrypt decrypts encrypted data in a single part. */ - CK_RV FC_Decrypt(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedData,CK_ULONG usEncryptedDataLen,CK_BYTE_PTR pData, - CK_ULONG_PTR pusDataLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_Decrypt(hSession,pEncryptedData,usEncryptedDataLen,pData, - pusDataLen); -} - - -/* FC_DecryptUpdate continues a multiple-part decryption operation. */ - CK_RV FC_DecryptUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedPart, CK_ULONG usEncryptedPartLen, - CK_BYTE_PTR pPart, CK_ULONG_PTR pusPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_DecryptUpdate(hSession,pEncryptedPart,usEncryptedPartLen, - pPart,pusPartLen); -} - - -/* FC_DecryptFinal finishes a multiple-part decryption operation. */ - CK_RV FC_DecryptFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pLastPart, CK_ULONG_PTR pusLastPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_DecryptFinal(hSession,pLastPart,pusLastPartLen); -} - - -/* - ************** Crypto Functions: Digest (HASH) ************************ - */ - -/* FC_DigestInit initializes a message-digesting operation. */ - CK_RV FC_DigestInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism) { - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - return NSC_DigestInit(hSession, pMechanism); -} - - -/* FC_Digest digests data in a single part. */ - CK_RV FC_Digest(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pData, CK_ULONG usDataLen, CK_BYTE_PTR pDigest, - CK_ULONG_PTR pusDigestLen) { - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - return NSC_Digest(hSession,pData,usDataLen,pDigest,pusDigestLen); -} - - -/* FC_DigestUpdate continues a multiple-part message-digesting operation. */ - CK_RV FC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, - CK_ULONG usPartLen) { - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - return NSC_DigestUpdate(hSession,pPart,usPartLen); -} - - -/* FC_DigestFinal finishes a multiple-part message-digesting operation. */ - CK_RV FC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest, - CK_ULONG_PTR pusDigestLen) { - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - return NSC_DigestFinal(hSession,pDigest,pusDigestLen); -} - - -/* - ************** Crypto Functions: Sign ************************ - */ - -/* FC_SignInit initializes a signature (private key encryption) operation, - * where the signature is (will be) an appendix to the data, - * and plaintext cannot be recovered from the signature */ - CK_RV FC_SignInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_SignInit(hSession,pMechanism,hKey); - if (sftk_audit_enabled) { - sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv); - } - return rv; -} - - -/* FC_Sign signs (encrypts with private key) data in a single part, - * where the signature is (will be) an appendix to the data, - * and plaintext cannot be recovered from the signature */ - CK_RV FC_Sign(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pData,CK_ULONG usDataLen,CK_BYTE_PTR pSignature, - CK_ULONG_PTR pusSignatureLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_Sign(hSession,pData,usDataLen,pSignature,pusSignatureLen); -} - - -/* FC_SignUpdate continues a multiple-part signature operation, - * where the signature is (will be) an appendix to the data, - * and plaintext cannot be recovered from the signature */ - CK_RV FC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, - CK_ULONG usPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_SignUpdate(hSession,pPart,usPartLen); -} - - -/* FC_SignFinal finishes a multiple-part signature operation, - * returning the signature. */ - CK_RV FC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature, - CK_ULONG_PTR pusSignatureLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_SignFinal(hSession,pSignature,pusSignatureLen); -} - -/* - ************** Crypto Functions: Sign Recover ************************ - */ -/* FC_SignRecoverInit initializes a signature operation, - * where the (digest) data can be recovered from the signature. - * E.g. encryption with the user's private key */ - CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_SignRecoverInit(hSession,pMechanism,hKey); - if (sftk_audit_enabled) { - sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv); - } - return rv; -} - - -/* FC_SignRecover signs data in a single operation - * where the (digest) data can be recovered from the signature. - * E.g. encryption with the user's private key */ - CK_RV FC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pusSignatureLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_SignRecover(hSession,pData,usDataLen,pSignature,pusSignatureLen); -} - -/* - ************** Crypto Functions: verify ************************ - */ - -/* FC_VerifyInit initializes a verification operation, - * where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature (e.g. DSA) */ - CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_VerifyInit(hSession,pMechanism,hKey); - if (sftk_audit_enabled) { - sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv); - } - return rv; -} - - -/* FC_Verify verifies a signature in a single-part operation, - * where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature */ - CK_RV FC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG usDataLen, CK_BYTE_PTR pSignature, CK_ULONG usSignatureLen) { - /* make sure we're legal */ - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_Verify(hSession,pData,usDataLen,pSignature,usSignatureLen); -} - - -/* FC_VerifyUpdate continues a multiple-part verification operation, - * where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature */ - CK_RV FC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG usPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_VerifyUpdate(hSession,pPart,usPartLen); -} - - -/* FC_VerifyFinal finishes a multiple-part verification operation, - * checking the signature. */ - CK_RV FC_VerifyFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_VerifyFinal(hSession,pSignature,usSignatureLen); -} - -/* - ************** Crypto Functions: Verify Recover ************************ - */ - -/* FC_VerifyRecoverInit initializes a signature verification operation, - * where the data is recovered from the signature. - * E.g. Decryption with the user's public key */ - CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey); - if (sftk_audit_enabled) { - sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv); - } - return rv; -} - - -/* FC_VerifyRecover verifies a signature in a single-part operation, - * where the data is recovered from the signature. - * E.g. Decryption with the user's public key */ - CK_RV FC_VerifyRecover(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pSignature,CK_ULONG usSignatureLen, - CK_BYTE_PTR pData,CK_ULONG_PTR pusDataLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_VerifyRecover(hSession,pSignature,usSignatureLen,pData, - pusDataLen); -} - -/* - **************************** Key Functions: ************************ - */ - -/* FC_GenerateKey generates a secret key, creating a new key object. */ - CK_RV FC_GenerateKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phKey) { - CK_BBOOL *boolptr; - - SFTK_FIPSCHECK(); - CHECK_FORK(); - - /* all secret keys must be sensitive, if the upper level code tries to say - * otherwise, reject it. */ - boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, ulCount, CKA_SENSITIVE); - if (boolptr != NULL) { - if (!(*boolptr)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - } - - rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); - if (sftk_audit_enabled) { - sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv); - } - return rv; -} - - -/* FC_GenerateKeyPair generates a public-key/private-key pair, - * creating new key objects. */ - CK_RV FC_GenerateKeyPair (CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, - CK_ULONG usPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - CK_ULONG usPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, - CK_OBJECT_HANDLE_PTR phPrivateKey) { - CK_BBOOL *boolptr; - CK_RV crv; - - SFTK_FIPSCHECK(); - CHECK_FORK(); - - - /* all private keys must be sensitive, if the upper level code tries to say - * otherwise, reject it. */ - boolptr = (CK_BBOOL *) fc_getAttribute(pPrivateKeyTemplate, - usPrivateKeyAttributeCount, CKA_SENSITIVE); - if (boolptr != NULL) { - if (!(*boolptr)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - } - crv = NSC_GenerateKeyPair (hSession,pMechanism,pPublicKeyTemplate, - usPublicKeyAttributeCount,pPrivateKeyTemplate, - usPrivateKeyAttributeCount,phPublicKey,phPrivateKey); - if (crv == CKR_GENERAL_ERROR) { - /* pairwise consistency check failed. */ - sftk_fatalError = PR_TRUE; - } - if (sftk_audit_enabled) { - sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate, - usPublicKeyAttributeCount,pPrivateKeyTemplate, - usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv); - } - return crv; -} - - -/* FC_WrapKey wraps (i.e., encrypts) a key. */ - CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, - CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, - CK_ULONG_PTR pulWrappedKeyLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, - pulWrappedKeyLen); - if (sftk_audit_enabled) { - sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, - pulWrappedKeyLen,rv); - } - return rv; -} - - -/* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ - CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, - CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey) { - CK_BBOOL *boolptr; - - SFTK_FIPSCHECK(); - CHECK_FORK(); - - /* all secret keys must be sensitive, if the upper level code tries to say - * otherwise, reject it. */ - boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - ulAttributeCount, CKA_SENSITIVE); - if (boolptr != NULL) { - if (!(*boolptr)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - } - rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, - ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey); - if (sftk_audit_enabled) { - sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, - ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv); - } - return rv; -} - - -/* FC_DeriveKey derives a key from a base key, creating a new key object. */ - CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey) { - CK_BBOOL *boolptr; - - SFTK_FIPSCHECK(); - CHECK_FORK(); - - /* all secret keys must be sensitive, if the upper level code tries to say - * otherwise, reject it. */ - boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - ulAttributeCount, CKA_SENSITIVE); - if (boolptr != NULL) { - if (!(*boolptr)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - } - rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, - ulAttributeCount, phKey); - if (sftk_audit_enabled) { - sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate, - ulAttributeCount,phKey,rv); - } - return rv; -} - -/* - **************************** Radom Functions: ************************ - */ - -/* FC_SeedRandom mixes additional seed material into the token's random number - * generator. */ - CK_RV FC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, - CK_ULONG usSeedLen) { - CK_RV crv; - - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - crv = NSC_SeedRandom(hSession,pSeed,usSeedLen); - if (crv != CKR_OK) { - sftk_fatalError = PR_TRUE; - } - return crv; -} - - -/* FC_GenerateRandom generates random data. */ - CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) { - CK_RV crv; - - CHECK_FORK(); - - SFTK_FIPSFATALCHECK(); - crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen); - if (crv != CKR_OK) { - sftk_fatalError = PR_TRUE; - if (sftk_audit_enabled) { - char msg[128]; - PR_snprintf(msg,sizeof msg, - "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, " - "ulRandomLen=%lu)=0x%08lX " - "self-test: continuous RNG test failed", - (PRUint32)hSession,pRandomData, - (PRUint32)ulRandomLen,(PRUint32)crv); - sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); - } - } - return crv; -} - - -/* FC_GetFunctionStatus obtains an updated status of a function running - * in parallel with an application. */ - CK_RV FC_GetFunctionStatus(CK_SESSION_HANDLE hSession) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_GetFunctionStatus(hSession); -} - - -/* FC_CancelFunction cancels a function running in parallel */ - CK_RV FC_CancelFunction(CK_SESSION_HANDLE hSession) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_CancelFunction(hSession); -} - -/* - **************************** Version 1.1 Functions: ************************ - */ - -/* FC_GetOperationState saves the state of the cryptographic - *operation in a session. */ -CK_RV FC_GetOperationState(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) { - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - return NSC_GetOperationState(hSession,pOperationState,pulOperationStateLen); -} - - -/* FC_SetOperationState restores the state of the cryptographic operation - * in a session. */ -CK_RV FC_SetOperationState(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, - CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) { - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - return NSC_SetOperationState(hSession,pOperationState,ulOperationStateLen, - hEncryptionKey,hAuthenticationKey); -} - -/* FC_FindObjectsFinal finishes a search for token and session objects. */ -CK_RV FC_FindObjectsFinal(CK_SESSION_HANDLE hSession) { - /* let publically readable object be found */ - SFTK_FIPSFATALCHECK(); - CHECK_FORK(); - - return NSC_FindObjectsFinal(hSession); -} - - -/* Dual-function cryptographic operations */ - -/* FC_DigestEncryptUpdate continues a multiple-part digesting and encryption - * operation. */ -CK_RV FC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_DigestEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart, - pulEncryptedPartLen); -} - - -/* FC_DecryptDigestUpdate continues a multiple-part decryption and digesting - * operation. */ -CK_RV FC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, - CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_DecryptDigestUpdate(hSession, pEncryptedPart,ulEncryptedPartLen, - pPart,pulPartLen); -} - -/* FC_SignEncryptUpdate continues a multiple-part signing and encryption - * operation. */ -CK_RV FC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_SignEncryptUpdate(hSession,pPart,ulPartLen,pEncryptedPart, - pulEncryptedPartLen); -} - -/* FC_DecryptVerifyUpdate continues a multiple-part decryption and verify - * operation. */ -CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, - CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - return NSC_DecryptVerifyUpdate(hSession,pEncryptedData,ulEncryptedDataLen, - pData,pulDataLen); -} - - -/* FC_DigestKey continues a multi-part message-digesting operation, - * by digesting the value of a secret key as part of the data already digested. - */ -CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { - SFTK_FIPSCHECK(); - CHECK_FORK(); - - rv = NSC_DigestKey(hSession,hKey); - if (sftk_audit_enabled) { - sftk_AuditDigestKey(hSession,hKey,rv); - } - return rv; -} - - -CK_RV FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, - CK_VOID_PTR pReserved) -{ - CHECK_FORK(); - - return NSC_WaitForSlotEvent(flags, pSlot, pReserved); -} diff --git a/security/nss/lib/softoken/legacydb/Makefile b/security/nss/lib/softoken/legacydb/Makefile deleted file mode 100644 index 78a7c78c7..000000000 --- a/security/nss/lib/softoken/legacydb/Makefile +++ /dev/null @@ -1,82 +0,0 @@ -#! gmake -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -####################################################################### -# (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 - -# indicates dependency on freebl static lib -$(SHARED_LIBRARY): $(CRYPTOLIB) diff --git a/security/nss/lib/softoken/legacydb/cdbhdl.h b/security/nss/lib/softoken/legacydb/cdbhdl.h deleted file mode 100644 index aec617b73..000000000 --- a/security/nss/lib/softoken/legacydb/cdbhdl.h +++ /dev/null @@ -1,85 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * cdbhdl.h - certificate database handle - * private to the certdb module - * - * $Id$ - */ -#ifndef _CDBHDL_H_ -#define _CDBHDL_H_ - -#include "nspr.h" -#include "mcom_db.h" -#include "pcertt.h" -#include "prtypes.h" - -/* - * Handle structure for open certificate databases - */ -struct NSSLOWCERTCertDBHandleStr { - DB *permCertDB; - PZMonitor *dbMon; - PRBool dbVerify; - PRInt32 ref; /* reference count */ -}; - -#ifdef DBM_USING_NSPR -#define NO_RDONLY PR_RDONLY -#define NO_RDWR PR_RDWR -#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE) -#else -#define NO_RDONLY O_RDONLY -#define NO_RDWR O_RDWR -#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC) -#endif - -typedef DB * (*rdbfunc)(const char *appName, const char *prefix, - const char *type, int flags); -typedef int (*rdbstatusfunc)(void); - -#define RDB_FAIL 1 -#define RDB_RETRY 2 - -DB * rdbopen(const char *appName, const char *prefix, - const char *type, int flags, int *status); - -DB *dbsopen (const char *dbname , int flags, int mode, DBTYPE type, - const void * appData); -SECStatus db_Copy(DB *dest,DB *src); -int db_InitComplete(DB *db); - -#endif diff --git a/security/nss/lib/softoken/legacydb/config.mk b/security/nss/lib/softoken/legacydb/config.mk deleted file mode 100644 index 1d541b8b1..000000000 --- a/security/nss/lib/softoken/legacydb/config.mk +++ /dev/null @@ -1,113 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS) -CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) -CRYPTODIR=../freebl -ifdef MOZILLA_SECURITY_BUILD - CRYPTOLIB=$(DIST)/lib/$(LIB_PREFIX)crypto.$(LIB_SUFFIX) - CRYPTODIR=../crypto -endif - -EXTRA_LIBS += $(CRYPTOLIB) - -ifndef NSS_DISABLE_DBM -EXTRA_LIBS += $(DIST)/lib/$(LIB_PREFIX)dbm.$(LIB_SUFFIX) -endif - -# can't do this in manifest.mn because OS_TARGET isn't defined there. -ifeq (,$(filter-out WIN%,$(OS_TARGET))) - -# don't want the 32 in the shared library name -SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) -IMPORT_LIBRARY = $(OBJDIR)/$(IMPORT_LIB_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(IMPORT_LIB_SUFFIX) - -RES = $(OBJDIR)/$(LIBRARY_NAME).res -RESNAME = $(LIBRARY_NAME).rc - -ifdef NS_USE_GCC -EXTRA_SHARED_LIBS += \ - -L$(DIST)/lib \ - -lnssutil3 \ - -L$(NSPR_LIB_DIR) \ - -lplc4 \ - -lplds4 \ - -lnspr4 \ - $(NULL) -else # ! NS_USE_GCC - -EXTRA_SHARED_LIBS += \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \ - $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \ - $(DIST)/lib/nssutil3.lib \ - $(NULL) -endif # NS_USE_GCC - -else - -# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS) -# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX. -EXTRA_SHARED_LIBS += \ - -L$(DIST)/lib \ - -lnssutil3 \ - -L$(NSPR_LIB_DIR) \ - -lplc4 \ - -lplds4 \ - -lnspr4 \ - $(NULL) -endif - -ifeq ($(OS_TARGET),SunOS) -# The -R '$ORIGIN' linker option instructs this library to search for its -# dependencies in the same directory where it resides. -MKSHLIB += -R '$$ORIGIN' -OS_LIBS += -lbsm -endif - -ifeq ($(OS_ARCH), HP-UX) -ifneq ($(OS_TEST), ia64) -# pa-risc -ifeq ($(USE_64), 1) -MKSHLIB += +b '$$ORIGIN' -endif -endif -endif - -ifeq ($(OS_TARGET),WINCE) -DEFINES += -DDBM_USING_NSPR -endif diff --git a/security/nss/lib/softoken/legacydb/dbmshim.c b/security/nss/lib/softoken/legacydb/dbmshim.c deleted file mode 100644 index 9d512ac41..000000000 --- a/security/nss/lib/softoken/legacydb/dbmshim.c +++ /dev/null @@ -1,647 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Berkeley DB 1.85 Shim code to handle blobs. - * - * $Id$ - */ -#include "mcom_db.h" -#include "secitem.h" -#include "nssb64.h" -#include "blapi.h" -#include "secerr.h" - -#include "lgdb.h" - -/* - * Blob block: - * Byte 0 CERTDB Version -+ -+ - * Byte 1 certDBEntryTypeBlob | BLOB_HEAD_LEN | - * Byte 2 flags (always '0'); | | - * Byte 3 reserved (always '0'); -+ | - * Byte 4 LSB length | <--BLOB_LENGTH_START | BLOB_BUF_LEN - * Byte 5 . | | - * Byte 6 . | BLOB_LENGTH_LEN | - * Byte 7 MSB length | | - * Byte 8 blob_filename -+ -+ <-- BLOB_NAME_START | - * Byte 9 . | BLOB_NAME_LEN | - * . . | | - * Byte 37 . -+ -+ - */ -#define DBS_BLOCK_SIZE (16*1024) /* 16 k */ -#define DBS_MAX_ENTRY_SIZE (DBS_BLOCK_SIZE - (2048)) /* 14 k */ -#define DBS_CACHE_SIZE DBS_BLOCK_SIZE*8 -#define ROUNDDIV(x,y) (x+(y-1))/y -#define BLOB_HEAD_LEN 4 -#define BLOB_LENGTH_START BLOB_HEAD_LEN -#define BLOB_LENGTH_LEN 4 -#define BLOB_NAME_START BLOB_LENGTH_START+BLOB_LENGTH_LEN -#define BLOB_NAME_LEN 1+ROUNDDIV(SHA1_LENGTH,3)*4+1 -#define BLOB_BUF_LEN BLOB_HEAD_LEN+BLOB_LENGTH_LEN+BLOB_NAME_LEN - -/* a Shim data structure. This data structure has a db built into it. */ -typedef struct DBSStr DBS; - -struct DBSStr { - DB db; - char *blobdir; - int mode; - PRBool readOnly; - PRFileMap *dbs_mapfile; - unsigned char *dbs_addr; - PRUint32 dbs_len; - char staticBlobArea[BLOB_BUF_LEN]; -}; - - - -/* - * return true if the Datablock contains a blobtype - */ -static PRBool -dbs_IsBlob(DBT *blobData) -{ - unsigned char *addr = (unsigned char *)blobData->data; - if (blobData->size < BLOB_BUF_LEN) { - return PR_FALSE; - } - return addr && ((certDBEntryType) addr[1] == certDBEntryTypeBlob); -} - -/* - * extract the filename in the blob of the real data set. - * This value is not malloced (does not need to be freed by the caller. - */ -static const char * -dbs_getBlobFileName(DBT *blobData) -{ - char *addr = (char *)blobData->data; - - return &addr[BLOB_NAME_START]; -} - -/* - * extract the size of the actual blob from the blob record - */ -static PRUint32 -dbs_getBlobSize(DBT *blobData) -{ - unsigned char *addr = (unsigned char *)blobData->data; - - return (PRUint32)(addr[BLOB_LENGTH_START+3] << 24) | - (addr[BLOB_LENGTH_START+2] << 16) | - (addr[BLOB_LENGTH_START+1] << 8) | - addr[BLOB_LENGTH_START]; -} - - -/* We are using base64 data for the filename, but base64 data can include a - * '/' which is interpreted as a path separator on many platforms. Replace it - * with an inocuous '-'. We don't need to convert back because we never actual - * decode the filename. - */ - -static void -dbs_replaceSlash(char *cp, int len) -{ - while (len--) { - if (*cp == '/') *cp = '-'; - cp++; - } -} - -/* - * create a blob record from a key, data and return it in blobData. - * NOTE: The data element is static data (keeping with the dbm model). - */ -static void -dbs_mkBlob(DBS *dbsp,const DBT *key, const DBT *data, DBT *blobData) -{ - unsigned char sha1_data[SHA1_LENGTH]; - char *b = dbsp->staticBlobArea; - PRUint32 length = data->size; - SECItem sha1Item; - - b[0] = CERT_DB_FILE_VERSION; /* certdb version number */ - b[1] = (char) certDBEntryTypeBlob; /* type */ - b[2] = 0; /* flags */ - b[3] = 0; /* reserved */ - b[BLOB_LENGTH_START] = length & 0xff; - b[BLOB_LENGTH_START+1] = (length >> 8) & 0xff; - b[BLOB_LENGTH_START+2] = (length >> 16) & 0xff; - b[BLOB_LENGTH_START+3] = (length >> 24) & 0xff; - sha1Item.data = sha1_data; - sha1Item.len = SHA1_LENGTH; - SHA1_HashBuf(sha1_data,key->data,key->size); - b[BLOB_NAME_START]='b'; /* Make sure we start with a alpha */ - NSSBase64_EncodeItem(NULL,&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1,&sha1Item); - b[BLOB_BUF_LEN-1] = 0; - dbs_replaceSlash(&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1); - blobData->data = b; - blobData->size = BLOB_BUF_LEN; - return; -} - - -/* - * construct a path to the actual blob. The string returned must be - * freed by the caller with PR_smprintf_free. - * - * Note: this file does lots of consistancy checks on the DBT. The - * routines that call this depend on these checks, so they don't worry - * about them (success of this routine implies a good blobdata record). - */ -static char * -dbs_getBlobFilePath(char *blobdir,DBT *blobData) -{ - const char *name; - - if (blobdir == NULL) { - PR_SetError(SEC_ERROR_BAD_DATABASE,0); - return NULL; - } - if (!dbs_IsBlob(blobData)) { - PR_SetError(SEC_ERROR_BAD_DATABASE,0); - return NULL; - } - name = dbs_getBlobFileName(blobData); - if (!name || *name == 0) { - PR_SetError(SEC_ERROR_BAD_DATABASE,0); - return NULL; - } - return PR_smprintf("%s" PATH_SEPARATOR "%s", blobdir, name); -} - -/* - * Delete a blob file pointed to by the blob record. - */ -static void -dbs_removeBlob(DBS *dbsp, DBT *blobData) -{ - char *file; - - file = dbs_getBlobFilePath(dbsp->blobdir, blobData); - if (!file) { - return; - } - PR_Delete(file); - PR_smprintf_free(file); -} - -/* - * Directory modes are slightly different, the 'x' bit needs to be on to - * access them. Copy all the read bits to 'x' bits - */ -static int -dbs_DirMode(int mode) -{ - int x_bits = (mode >> 2) & 0111; - return mode | x_bits; -} - -/* - * write a data blob to it's file. blobdData is the blob record that will be - * stored in the database. data is the actual data to go out on disk. - */ -static int -dbs_writeBlob(DBS *dbsp, int mode, DBT *blobData, const DBT *data) -{ - char *file = NULL; - PRFileDesc *filed; - PRStatus status; - int len; - int error = 0; - - file = dbs_getBlobFilePath(dbsp->blobdir, blobData); - if (!file) { - goto loser; - } - if (PR_Access(dbsp->blobdir, PR_ACCESS_EXISTS) != PR_SUCCESS) { - status = PR_MkDir(dbsp->blobdir,dbs_DirMode(mode)); - if (status != PR_SUCCESS) { - goto loser; - } - } - filed = PR_OpenFile(file,PR_CREATE_FILE|PR_TRUNCATE|PR_WRONLY, mode); - if (filed == NULL) { - error = PR_GetError(); - goto loser; - } - len = PR_Write(filed,data->data,data->size); - error = PR_GetError(); - PR_Close(filed); - if (len < (int)data->size) { - goto loser; - } - PR_smprintf_free(file); - return 0; - -loser: - if (file) { - PR_Delete(file); - PR_smprintf_free(file); - } - /* don't let close or delete reset the error */ - PR_SetError(error,0); - return -1; -} - - -/* - * we need to keep a address map in memory between calls to DBM. - * remember what we have mapped can close it when we get another dbm - * call. - * - * NOTE: Not all platforms support mapped files. This code is designed to - * detect this at runtime. If map files aren't supported the OS will indicate - * this by failing the PR_Memmap call. In this case we emulate mapped files - * by just reading in the file into regular memory. We signal this state by - * making dbs_mapfile NULL and dbs_addr non-NULL. - */ - -static void -dbs_freemap(DBS *dbsp) -{ - if (dbsp->dbs_mapfile) { - PR_MemUnmap(dbsp->dbs_addr,dbsp->dbs_len); - PR_CloseFileMap(dbsp->dbs_mapfile); - dbsp->dbs_mapfile = NULL; - dbsp->dbs_addr = NULL; - dbsp->dbs_len = 0; - } else if (dbsp->dbs_addr) { - PORT_Free(dbsp->dbs_addr); - dbsp->dbs_addr = NULL; - dbsp->dbs_len = 0; - } - return; -} - -static void -dbs_setmap(DBS *dbsp, PRFileMap *mapfile, unsigned char *addr, PRUint32 len) -{ - dbsp->dbs_mapfile = mapfile; - dbsp->dbs_addr = addr; - dbsp->dbs_len = len; -} - -/* - * platforms that cannot map the file need to read it into a temp buffer. - */ -static unsigned char * -dbs_EmulateMap(PRFileDesc *filed, int len) -{ - unsigned char *addr; - PRInt32 dataRead; - - addr = PORT_Alloc(len); - if (addr == NULL) { - return NULL; - } - - dataRead = PR_Read(filed,addr,len); - if (dataRead != len) { - PORT_Free(addr); - if (dataRead > 0) { - /* PR_Read didn't set an error, we need to */ - PR_SetError(SEC_ERROR_BAD_DATABASE,0); - } - return NULL; - } - - return addr; -} - - -/* - * pull a database record off the disk - * data points to the blob record on input and the real record (if we could - * read it) on output. if there is an error data is not modified. - */ -static int -dbs_readBlob(DBS *dbsp, DBT *data) -{ - char *file = NULL; - PRFileDesc *filed = NULL; - PRFileMap *mapfile = NULL; - unsigned char *addr = NULL; - int error; - int len = -1; - - file = dbs_getBlobFilePath(dbsp->blobdir, data); - if (!file) { - goto loser; - } - filed = PR_OpenFile(file,PR_RDONLY,0); - PR_smprintf_free(file); file = NULL; - if (filed == NULL) { - goto loser; - } - - len = dbs_getBlobSize(data); - mapfile = PR_CreateFileMap(filed, len, PR_PROT_READONLY); - if (mapfile == NULL) { - /* USE PR_GetError instead of PORT_GetError here - * because we are getting the error from PR_xxx - * function */ - if (PR_GetError() != PR_NOT_IMPLEMENTED_ERROR) { - goto loser; - } - addr = dbs_EmulateMap(filed, len); - } else { - addr = PR_MemMap(mapfile, 0, len); - } - if (addr == NULL) { - goto loser; - } - PR_Close(filed); - dbs_setmap(dbsp,mapfile,addr,len); - - data->data = addr; - data->size = len; - return 0; - -loser: - /* preserve the error code */ - error = PR_GetError(); - if (mapfile) { - PR_CloseFileMap(mapfile); - } - if (filed) { - PR_Close(filed); - } - PR_SetError(error,0); - return -1; -} - -/* - * actual DBM shims - */ -static int -dbs_get(const DB *dbs, const DBT *key, DBT *data, unsigned int flags) -{ - int ret; - DBS *dbsp = (DBS *)dbs; - DB *db = (DB *)dbs->internal; - - - dbs_freemap(dbsp); - - ret = (* db->get)(db, key, data, flags); - if ((ret == 0) && dbs_IsBlob(data)) { - ret = dbs_readBlob(dbsp,data); - } - - return(ret); -} - -static int -dbs_put(const DB *dbs, DBT *key, const DBT *data, unsigned int flags) -{ - DBT blob; - int ret = 0; - DBS *dbsp = (DBS *)dbs; - DB *db = (DB *)dbs->internal; - - dbs_freemap(dbsp); - - /* If the db is readonly, just pass the data down to rdb and let it fail */ - if (!dbsp->readOnly) { - DBT oldData; - int ret1; - - /* make sure the current record is deleted if it's a blob */ - ret1 = (*db->get)(db,key,&oldData,0); - if ((ret1 == 0) && flags == R_NOOVERWRITE) { - /* let DBM return the error to maintain consistancy */ - return (* db->put)(db, key, data, flags); - } - if ((ret1 == 0) && dbs_IsBlob(&oldData)) { - dbs_removeBlob(dbsp, &oldData); - } - - if (data->size > DBS_MAX_ENTRY_SIZE) { - dbs_mkBlob(dbsp,key,data,&blob); - ret = dbs_writeBlob(dbsp, dbsp->mode, &blob, data); - data = &blob; - } - } - - if (ret == 0) { - ret = (* db->put)(db, key, data, flags); - } - return(ret); -} - -static int -dbs_sync(const DB *dbs, unsigned int flags) -{ - DB *db = (DB *)dbs->internal; - DBS *dbsp = (DBS *)dbs; - - dbs_freemap(dbsp); - - return (* db->sync)(db, flags); -} - -static int -dbs_del(const DB *dbs, const DBT *key, unsigned int flags) -{ - int ret; - DBS *dbsp = (DBS *)dbs; - DB *db = (DB *)dbs->internal; - - dbs_freemap(dbsp); - - if (!dbsp->readOnly) { - DBT oldData; - ret = (*db->get)(db,key,&oldData,0); - if ((ret == 0) && dbs_IsBlob(&oldData)) { - dbs_removeBlob(dbsp,&oldData); - } - } - - return (* db->del)(db, key, flags); -} - -static int -dbs_seq(const DB *dbs, DBT *key, DBT *data, unsigned int flags) -{ - int ret; - DBS *dbsp = (DBS *)dbs; - DB *db = (DB *)dbs->internal; - - dbs_freemap(dbsp); - - ret = (* db->seq)(db, key, data, flags); - if ((ret == 0) && dbs_IsBlob(data)) { - /* don't return a blob read as an error so traversals keep going */ - (void) dbs_readBlob(dbsp,data); - } - - return(ret); -} - -static int -dbs_close(DB *dbs) -{ - DBS *dbsp = (DBS *)dbs; - DB *db = (DB *)dbs->internal; - int ret; - - dbs_freemap(dbsp); - ret = (* db->close)(db); - PORT_Free(dbsp->blobdir); - PORT_Free(dbsp); - return ret; -} - -static int -dbs_fd(const DB *dbs) -{ - DB *db = (DB *)dbs->internal; - - return (* db->fd)(db); -} - -/* - * the naming convention we use is - * change the .xxx into .dir. (for nss it's always .db); - * if no .extension exists or is equal to .dir, add a .dir - * the returned data must be freed. - */ -#define DIRSUFFIX ".dir" -static char * -dbs_mkBlobDirName(const char *dbname) -{ - int dbname_len = PORT_Strlen(dbname); - int dbname_end = dbname_len; - const char *cp; - char *blobDir = NULL; - - /* scan back from the end looking for either a directory separator, a '.', - * or the end of the string. NOTE: Windows should check for both separators - * here. For now this is safe because we know NSS always uses a '.' - */ - for (cp = &dbname[dbname_len]; - (cp > dbname) && (*cp != '.') && (*cp != *PATH_SEPARATOR) ; - cp--) - /* Empty */ ; - if (*cp == '.') { - dbname_end = cp - dbname; - if (PORT_Strcmp(cp,DIRSUFFIX) == 0) { - dbname_end = dbname_len; - } - } - blobDir = PORT_ZAlloc(dbname_end+sizeof(DIRSUFFIX)); - if (blobDir == NULL) { - return NULL; - } - PORT_Memcpy(blobDir,dbname,dbname_end); - PORT_Memcpy(&blobDir[dbname_end],DIRSUFFIX,sizeof(DIRSUFFIX)); - return blobDir; -} - -#define DBM_DEFAULT 0 -static const HASHINFO dbs_hashInfo = { - DBS_BLOCK_SIZE, /* bucket size, must be greater than = to - * or maximum entry size (+ header) - * we allow before blobing */ - DBM_DEFAULT, /* Fill Factor */ - DBM_DEFAULT, /* number of elements */ - DBS_CACHE_SIZE, /* cache size */ - DBM_DEFAULT, /* hash function */ - DBM_DEFAULT, /* byte order */ -}; - -/* - * the open function. NOTE: this is the only exposed function in this file. - * everything else is called through the function table pointer. - */ -DB * -dbsopen(const char *dbname, int flags, int mode, DBTYPE type, - const void *userData) -{ - DB *db = NULL,*dbs = NULL; - DBS *dbsp = NULL; - - /* NOTE: we are overriding userData with dbs_hashInfo. since all known - * callers pass 0, this is ok, otherwise we should merge the two */ - - dbsp = (DBS *)PORT_ZAlloc(sizeof(DBS)); - if (!dbsp) { - return NULL; - } - dbs = &dbsp->db; - - dbsp->blobdir=dbs_mkBlobDirName(dbname); - if (dbsp->blobdir == NULL) { - goto loser; - } - dbsp->mode = mode; - dbsp->readOnly = (PRBool)(flags == NO_RDONLY); - dbsp->dbs_mapfile = NULL; - dbsp->dbs_addr = NULL; - dbsp->dbs_len = 0; - - /* the real dbm call */ - db = dbopen(dbname, flags, mode, type, &dbs_hashInfo); - if (db == NULL) { - goto loser; - } - dbs->internal = (void *) db; - dbs->type = type; - dbs->close = dbs_close; - dbs->get = dbs_get; - dbs->del = dbs_del; - dbs->put = dbs_put; - dbs->seq = dbs_seq; - dbs->sync = dbs_sync; - dbs->fd = dbs_fd; - - return dbs; -loser: - if (db) { - (*db->close)(db); - } - if (dbsp) { - if (dbsp->blobdir) { - PORT_Free(dbsp->blobdir); - } - PORT_Free(dbsp); - } - return NULL; -} diff --git a/security/nss/lib/softoken/legacydb/keydb.c b/security/nss/lib/softoken/legacydb/keydb.c deleted file mode 100644 index 28542025b..000000000 --- a/security/nss/lib/softoken/legacydb/keydb.c +++ /dev/null @@ -1,2277 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#include "lowkeyi.h" -#include "secasn1.h" -#include "secder.h" -#include "secoid.h" -#include "blapi.h" -#include "secitem.h" -#include "pcert.h" -#include "mcom_db.h" -#include "secerr.h" - -#include "keydbi.h" -#include "lgdb.h" - -/* - * Record keys for keydb - */ -#define SALT_STRING "global-salt" -#define VERSION_STRING "Version" -#define KEYDB_PW_CHECK_STRING "password-check" -#define KEYDB_PW_CHECK_LEN 14 -#define KEYDB_FAKE_PW_CHECK_STRING "fake-password-check" -#define KEYDB_FAKE_PW_CHECK_LEN 19 - -/* Size of the global salt for key database */ -#define SALT_LENGTH 16 - -SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) - -const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSLOWKEYEncryptedPrivateKeyInfo) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,algorithm), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSLOWKEYEncryptedPrivateKeyInfo,encryptedData) }, - { 0 } -}; - -const SEC_ASN1Template nsslowkey_PointerToEncryptedPrivateKeyInfoTemplate[] = { - { SEC_ASN1_POINTER, 0, nsslowkey_EncryptedPrivateKeyInfoTemplate } -}; - - -/* ====== Default key databse encryption algorithm ====== */ -static void -sec_destroy_dbkey(NSSLOWKEYDBKey *dbkey) -{ - if ( dbkey && dbkey->arena ) { - PORT_FreeArena(dbkey->arena, PR_FALSE); - } -} - -static void -free_dbt(DBT *dbt) -{ - if ( dbt ) { - PORT_Free(dbt->data); - PORT_Free(dbt); - } - - return; -} - -static int keydb_Get(NSSLOWKEYDBHandle *db, DBT *key, DBT *data, - unsigned int flags); -static int keydb_Put(NSSLOWKEYDBHandle *db, DBT *key, DBT *data, - unsigned int flags); -static int keydb_Sync(NSSLOWKEYDBHandle *db, unsigned int flags); -static int keydb_Del(NSSLOWKEYDBHandle *db, DBT *key, unsigned int flags); -static int keydb_Seq(NSSLOWKEYDBHandle *db, DBT *key, DBT *data, - unsigned int flags); -static void keydb_Close(NSSLOWKEYDBHandle *db); - -/* - * format of key database entries for version 3 of database: - * byte offset field - * ----------- ----- - * 0 version - * 1 salt-len - * 2 nn-len - * 3.. salt-data - * ... nickname - * ... encrypted-key-data - */ -static DBT * -encode_dbkey(NSSLOWKEYDBKey *dbkey,unsigned char version) -{ - DBT *bufitem = NULL; - unsigned char *buf; - int nnlen; - char *nn; - - bufitem = (DBT *)PORT_ZAlloc(sizeof(DBT)); - if ( bufitem == NULL ) { - goto loser; - } - - if ( dbkey->nickname ) { - nn = dbkey->nickname; - nnlen = PORT_Strlen(nn) + 1; - } else { - nn = ""; - nnlen = 1; - } - - /* compute the length of the record */ - /* 1 + 1 + 1 == version number header + salt length + nn len */ - bufitem->size = dbkey->salt.len + nnlen + dbkey->derPK.len + 1 + 1 + 1; - - bufitem->data = (void *)PORT_ZAlloc(bufitem->size); - if ( bufitem->data == NULL ) { - goto loser; - } - - buf = (unsigned char *)bufitem->data; - - /* set version number */ - buf[0] = version; - - /* set length of salt */ - PORT_Assert(dbkey->salt.len < 256); - buf[1] = dbkey->salt.len; - - /* set length of nickname */ - PORT_Assert(nnlen < 256); - buf[2] = nnlen; - - /* copy salt */ - PORT_Memcpy(&buf[3], dbkey->salt.data, dbkey->salt.len); - - /* copy nickname */ - PORT_Memcpy(&buf[3 + dbkey->salt.len], nn, nnlen); - - /* copy encrypted key */ - PORT_Memcpy(&buf[3 + dbkey->salt.len + nnlen], dbkey->derPK.data, - dbkey->derPK.len); - - return(bufitem); - -loser: - if ( bufitem ) { - free_dbt(bufitem); - } - - return(NULL); -} - -static NSSLOWKEYDBKey * -decode_dbkey(DBT *bufitem, int expectedVersion) -{ - NSSLOWKEYDBKey *dbkey; - PLArenaPool *arena = NULL; - unsigned char *buf; - int version; - int keyoff; - int nnlen; - int saltoff; - - buf = (unsigned char *)bufitem->data; - - version = buf[0]; - - if ( version != expectedVersion ) { - goto loser; - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey)); - if ( dbkey == NULL ) { - goto loser; - } - - dbkey->arena = arena; - dbkey->salt.data = NULL; - dbkey->derPK.data = NULL; - - dbkey->salt.len = buf[1]; - dbkey->salt.data = (unsigned char *)PORT_ArenaZAlloc(arena, dbkey->salt.len); - if ( dbkey->salt.data == NULL ) { - goto loser; - } - - saltoff = 2; - keyoff = 2 + dbkey->salt.len; - - if ( expectedVersion >= 3 ) { - nnlen = buf[2]; - if ( nnlen ) { - dbkey->nickname = (char *)PORT_ArenaZAlloc(arena, nnlen + 1); - if ( dbkey->nickname ) { - PORT_Memcpy(dbkey->nickname, &buf[keyoff+1], nnlen); - } - } - keyoff += ( nnlen + 1 ); - saltoff = 3; - } - - PORT_Memcpy(dbkey->salt.data, &buf[saltoff], dbkey->salt.len); - - dbkey->derPK.len = bufitem->size - keyoff; - dbkey->derPK.data = (unsigned char *)PORT_ArenaZAlloc(arena,dbkey->derPK.len); - if ( dbkey->derPK.data == NULL ) { - goto loser; - } - - PORT_Memcpy(dbkey->derPK.data, &buf[keyoff], dbkey->derPK.len); - - return(dbkey); - -loser: - - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -static NSSLOWKEYDBKey * -get_dbkey(NSSLOWKEYDBHandle *handle, DBT *index) -{ - NSSLOWKEYDBKey *dbkey; - DBT entry; - int ret; - - /* get it from the database */ - ret = keydb_Get(handle, index, &entry, 0); - if ( ret ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return NULL; - } - - /* set up dbkey struct */ - - dbkey = decode_dbkey(&entry, handle->version); - - return(dbkey); -} - -static SECStatus -put_dbkey(NSSLOWKEYDBHandle *handle, DBT *index, NSSLOWKEYDBKey *dbkey, PRBool update) -{ - DBT *keydata = NULL; - int status; - - keydata = encode_dbkey(dbkey, handle->version); - if ( keydata == NULL ) { - goto loser; - } - - /* put it in the database */ - if ( update ) { - status = keydb_Put(handle, index, keydata, 0); - } else { - status = keydb_Put(handle, index, keydata, R_NOOVERWRITE); - } - - if ( status ) { - goto loser; - } - - /* sync the database */ - status = keydb_Sync(handle, 0); - if ( status ) { - goto loser; - } - - free_dbt(keydata); - return(SECSuccess); - -loser: - if ( keydata ) { - free_dbt(keydata); - } - - return(SECFailure); -} - -SECStatus -nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle, - SECStatus (* keyfunc)(DBT *k, DBT *d, void *pdata), - void *udata ) -{ - DBT data; - DBT key; - SECStatus status; - int ret; - - if (handle == NULL) { - return(SECFailure); - } - - ret = keydb_Seq(handle, &key, &data, R_FIRST); - if ( ret ) { - return(SECFailure); - } - - do { - /* skip version record */ - if ( data.size > 1 ) { - if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) { - if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) { - continue; - } - } - - /* skip password check */ - if ( key.size == KEYDB_PW_CHECK_LEN ) { - if ( PORT_Memcmp(key.data, KEYDB_PW_CHECK_STRING, - KEYDB_PW_CHECK_LEN) == 0 ) { - continue; - } - } - - status = (* keyfunc)(&key, &data, udata); - if (status != SECSuccess) { - return(status); - } - } - } while ( keydb_Seq(handle, &key, &data, R_NEXT) == 0 ); - - return(SECSuccess); -} - -#ifdef notdef -typedef struct keyNode { - struct keyNode *next; - DBT key; -} keyNode; - -typedef struct { - PLArenaPool *arena; - keyNode *head; -} keyList; - -static SECStatus -sec_add_key_to_list(DBT *key, DBT *data, void *arg) -{ - keyList *keylist; - keyNode *node; - void *keydata; - - keylist = (keyList *)arg; - - /* allocate the node struct */ - node = (keyNode*)PORT_ArenaZAlloc(keylist->arena, sizeof(keyNode)); - if ( node == NULL ) { - return(SECFailure); - } - - /* allocate room for key data */ - keydata = PORT_ArenaZAlloc(keylist->arena, key->size); - if ( keydata == NULL ) { - return(SECFailure); - } - - /* link node into list */ - node->next = keylist->head; - keylist->head = node; - - /* copy key into node */ - PORT_Memcpy(keydata, key->data, key->size); - node->key.size = key->size; - node->key.data = keydata; - - return(SECSuccess); -} -#endif - -static SECItem * -decodeKeyDBGlobalSalt(DBT *saltData) -{ - SECItem *saltitem; - - saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if ( saltitem == NULL ) { - return(NULL); - } - - saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size); - if ( saltitem->data == NULL ) { - PORT_Free(saltitem); - return(NULL); - } - - saltitem->len = saltData->size; - PORT_Memcpy(saltitem->data, saltData->data, saltitem->len); - - return(saltitem); -} - -static SECItem * -GetKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle) -{ - DBT saltKey; - DBT saltData; - int ret; - - saltKey.data = SALT_STRING; - saltKey.size = sizeof(SALT_STRING) - 1; - - ret = keydb_Get(handle, &saltKey, &saltData, 0); - if ( ret ) { - return(NULL); - } - - return(decodeKeyDBGlobalSalt(&saltData)); -} - -static SECStatus -StoreKeyDBGlobalSalt(NSSLOWKEYDBHandle *handle, SECItem *salt) -{ - DBT saltKey; - DBT saltData; - int status; - - saltKey.data = SALT_STRING; - saltKey.size = sizeof(SALT_STRING) - 1; - - saltData.data = (void *)salt->data; - saltData.size = salt->len; - - /* put global salt into the database now */ - status = keydb_Put(handle, &saltKey, &saltData, 0); - if ( status ) { - return(SECFailure); - } - - return(SECSuccess); -} - -static SECStatus -makeGlobalVersion(NSSLOWKEYDBHandle *handle) -{ - unsigned char version; - DBT versionData; - DBT versionKey; - int status; - - version = NSSLOWKEY_DB_FILE_VERSION; - versionData.data = &version; - versionData.size = 1; - versionKey.data = VERSION_STRING; - versionKey.size = sizeof(VERSION_STRING)-1; - - /* put version string into the database now */ - status = keydb_Put(handle, &versionKey, &versionData, 0); - if ( status ) { - return(SECFailure); - } - handle->version = version; - - return(SECSuccess); -} - - -static SECStatus -makeGlobalSalt(NSSLOWKEYDBHandle *handle) -{ - DBT saltKey; - DBT saltData; - unsigned char saltbuf[16]; - int status; - - saltKey.data = SALT_STRING; - saltKey.size = sizeof(SALT_STRING) - 1; - - saltData.data = (void *)saltbuf; - saltData.size = sizeof(saltbuf); - RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf)); - - /* put global salt into the database now */ - status = keydb_Put(handle, &saltKey, &saltData, 0); - if ( status ) { - return(SECFailure); - } - - return(SECSuccess); -} - -static SECStatus -encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg, - SECItem *encCheck); - -static unsigned char -nsslowkey_version(NSSLOWKEYDBHandle *handle) -{ - DBT versionKey; - DBT versionData; - int ret; - versionKey.data = VERSION_STRING; - versionKey.size = sizeof(VERSION_STRING)-1; - - if (handle->db == NULL) { - return 255; - } - - /* lookup version string in database */ - ret = keydb_Get( handle, &versionKey, &versionData, 0 ); - - /* error accessing the database */ - if ( ret < 0 ) { - return 255; - } - - if ( ret >= 1 ) { - return 0; - } - return *( (unsigned char *)versionData.data); -} - -static PRBool -seckey_HasAServerKey(NSSLOWKEYDBHandle *handle) -{ - DBT key; - DBT data; - int ret; - PRBool found = PR_FALSE; - - ret = keydb_Seq(handle, &key, &data, R_FIRST); - if ( ret ) { - return PR_FALSE; - } - - do { - /* skip version record */ - if ( data.size > 1 ) { - /* skip salt */ - if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) { - if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) { - continue; - } - } - /* skip pw check entry */ - if ( key.size == KEYDB_PW_CHECK_LEN ) { - if ( PORT_Memcmp(key.data, KEYDB_PW_CHECK_STRING, - KEYDB_PW_CHECK_LEN) == 0 ) { - continue; - } - } - - /* keys stored by nickname will have 0 as the last byte of the - * db key. Other keys must be stored by modulus. We will not - * update those because they are left over from a keygen that - * never resulted in a cert. - */ - if ( ((unsigned char *)key.data)[key.size-1] != 0 ) { - continue; - } - - if (PORT_Strcmp(key.data,"Server-Key") == 0) { - found = PR_TRUE; - break; - } - - } - } while ( keydb_Seq(handle, &key, &data, R_NEXT) == 0 ); - - return found; -} - -/* forward declare local create function */ -static NSSLOWKEYDBHandle * nsslowkey_NewHandle(DB *dbHandle); - -/* - * currently updates key database from v2 to v3 - */ -static SECStatus -nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle) -{ - SECStatus rv; - DBT checkKey; - DBT checkData; - DBT saltKey; - DBT saltData; - DBT key; - DBT data; - unsigned char version; - NSSLOWKEYDBKey *dbkey = NULL; - NSSLOWKEYDBHandle *update = NULL; - SECItem *oldSalt = NULL; - int ret; - SECItem checkitem; - - if ( handle->updatedb == NULL ) { - return SECSuccess; - } - - /* create a full DB Handle for our update so we - * can use the correct locks for the db primatives */ - update = nsslowkey_NewHandle(handle->updatedb); - if ( update == NULL) { - return SECSuccess; - } - - /* update has now inherited the database handle */ - handle->updatedb = NULL; - - /* - * check the version record - */ - version = nsslowkey_version(update); - if (version != 2) { - goto done; - } - - saltKey.data = SALT_STRING; - saltKey.size = sizeof(SALT_STRING) - 1; - - ret = keydb_Get(update, &saltKey, &saltData, 0); - if ( ret ) { - /* no salt in old db, so it is corrupted */ - goto done; - } - - oldSalt = decodeKeyDBGlobalSalt(&saltData); - if ( oldSalt == NULL ) { - /* bad salt in old db, so it is corrupted */ - goto done; - } - - /* - * look for a pw check entry - */ - checkKey.data = KEYDB_PW_CHECK_STRING; - checkKey.size = KEYDB_PW_CHECK_LEN; - - ret = keydb_Get(update, &checkKey, &checkData, 0 ); - if (ret) { - /* - * if we have a key, but no KEYDB_PW_CHECK_STRING, then this must - * be an old server database, and it does have a password associated - * with it. Put a fake entry in so we can identify this db when we do - * get the password for it. - */ - if (seckey_HasAServerKey(update)) { - DBT fcheckKey; - DBT fcheckData; - - /* - * include a fake string - */ - fcheckKey.data = KEYDB_FAKE_PW_CHECK_STRING; - fcheckKey.size = KEYDB_FAKE_PW_CHECK_LEN; - fcheckData.data = "1"; - fcheckData.size = 1; - /* put global salt into the new database now */ - ret = keydb_Put( handle, &saltKey, &saltData, 0); - if ( ret ) { - goto done; - } - ret = keydb_Put( handle, &fcheckKey, &fcheckData, 0); - if ( ret ) { - goto done; - } - } else { - goto done; - } - } else { - /* put global salt into the new database now */ - ret = keydb_Put( handle, &saltKey, &saltData, 0); - if ( ret ) { - goto done; - } - - dbkey = decode_dbkey(&checkData, 2); - if ( dbkey == NULL ) { - goto done; - } - checkitem = dbkey->derPK; - dbkey->derPK.data = NULL; - - /* format the new pw check entry */ - rv = encodePWCheckEntry(NULL, &dbkey->derPK, SEC_OID_RC4, &checkitem); - if ( rv != SECSuccess ) { - goto done; - } - - rv = put_dbkey(handle, &checkKey, dbkey, PR_TRUE); - if ( rv != SECSuccess ) { - goto done; - } - - /* free the dbkey */ - sec_destroy_dbkey(dbkey); - dbkey = NULL; - } - - - /* now traverse the database */ - ret = keydb_Seq(update, &key, &data, R_FIRST); - if ( ret ) { - goto done; - } - - do { - /* skip version record */ - if ( data.size > 1 ) { - /* skip salt */ - if ( key.size == ( sizeof(SALT_STRING) - 1 ) ) { - if ( PORT_Memcmp(key.data, SALT_STRING, key.size) == 0 ) { - continue; - } - } - /* skip pw check entry */ - if ( key.size == checkKey.size ) { - if ( PORT_Memcmp(key.data, checkKey.data, key.size) == 0 ) { - continue; - } - } - - /* keys stored by nickname will have 0 as the last byte of the - * db key. Other keys must be stored by modulus. We will not - * update those because they are left over from a keygen that - * never resulted in a cert. - */ - if ( ((unsigned char *)key.data)[key.size-1] != 0 ) { - continue; - } - - dbkey = decode_dbkey(&data, 2); - if ( dbkey == NULL ) { - continue; - } - - /* This puts the key into the new database with the same - * index (nickname) that it had before. The second pass - * of the update will have the password. It will decrypt - * and re-encrypt the entries using a new algorithm. - */ - dbkey->nickname = (char *)key.data; - rv = put_dbkey(handle, &key, dbkey, PR_FALSE); - dbkey->nickname = NULL; - - sec_destroy_dbkey(dbkey); - } - } while ( keydb_Seq(update, &key, &data, R_NEXT) == 0 ); - - dbkey = NULL; - -done: - /* sync the database */ - ret = keydb_Sync(handle, 0); - - nsslowkey_CloseKeyDB(update); - - if ( oldSalt ) { - SECITEM_FreeItem(oldSalt, PR_TRUE); - } - - if ( dbkey ) { - sec_destroy_dbkey(dbkey); - } - - return(SECSuccess); -} - -static SECStatus -openNewDB(const char *appName, const char *prefix, const char *dbname, - NSSLOWKEYDBHandle *handle, NSSLOWKEYDBNameFunc namecb, void *cbarg) -{ - SECStatus rv = SECFailure; - int status = RDB_FAIL; - char *updname = NULL; - DB *updatedb = NULL; - PRBool updated = PR_FALSE; - int ret; - - if (appName) { - handle->db = rdbopen( appName, prefix, "key", NO_CREATE, &status); - } else { - handle->db = dbopen( dbname, NO_CREATE, 0600, DB_HASH, 0 ); - } - /* if create fails then we lose */ - if ( handle->db == NULL ) { - return (status == RDB_RETRY) ? SECWouldBlock: SECFailure; - } - - /* force a transactional read, which will verify that one and only one - * process attempts the update. */ - if (nsslowkey_version(handle) == NSSLOWKEY_DB_FILE_VERSION) { - /* someone else has already updated the database for us */ - db_InitComplete(handle->db); - return SECSuccess; - } - - /* - * if we are creating a multiaccess database, see if there is a - * local database we can update from. - */ - if (appName) { - NSSLOWKEYDBHandle *updateHandle; - updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 ); - if (!updatedb) { - goto noupdate; - } - - /* nsslowkey_version needs a full handle because it calls - * the kdb_Get() function, which needs to lock. - */ - updateHandle = nsslowkey_NewHandle(updatedb); - if (!updateHandle) { - updatedb->close(updatedb); - goto noupdate; - } - - handle->version = nsslowkey_version(updateHandle); - if (handle->version != NSSLOWKEY_DB_FILE_VERSION) { - nsslowkey_CloseKeyDB(updateHandle); - goto noupdate; - } - - /* copy the new DB from the old one */ - db_Copy(handle->db, updatedb); - nsslowkey_CloseKeyDB(updateHandle); - db_InitComplete(handle->db); - return SECSuccess; - } -noupdate: - - /* update the version number */ - rv = makeGlobalVersion(handle); - if ( rv != SECSuccess ) { - goto loser; - } - - /* - * try to update from v2 db - */ - updname = (*namecb)(cbarg, 2); - if ( updname != NULL ) { - handle->updatedb = dbopen( updname, NO_RDONLY, 0600, DB_HASH, 0 ); - PORT_Free( updname ); - - if ( handle->updatedb ) { - /* - * Try to update the db using a null password. If the db - * doesn't have a password, then this will work. If it does - * have a password, then this will fail and we will do the - * update later - */ - rv = nsslowkey_UpdateKeyDBPass1(handle); - if ( rv == SECSuccess ) { - updated = PR_TRUE; - } - } - - } - - /* we are using the old salt if we updated from an old db */ - if ( ! updated ) { - rv = makeGlobalSalt(handle); - if ( rv != SECSuccess ) { - goto loser; - } - } - - /* sync the database */ - ret = keydb_Sync(handle, 0); - if ( ret ) { - rv = SECFailure; - goto loser; - } - rv = SECSuccess; - -loser: - db_InitComplete(handle->db); - return rv; -} - - -static DB * -openOldDB(const char *appName, const char *prefix, const char *dbname, - PRBool openflags) { - DB *db = NULL; - - if (appName) { - db = rdbopen( appName, prefix, "key", openflags, NULL); - } else { - db = dbopen( dbname, openflags, 0600, DB_HASH, 0 ); - } - - return db; -} - -/* check for correct version number */ -static PRBool -verifyVersion(NSSLOWKEYDBHandle *handle) -{ - int version = nsslowkey_version(handle); - - handle->version = version; - if (version != NSSLOWKEY_DB_FILE_VERSION ) { - if (handle->db) { - keydb_Close(handle); - handle->db = NULL; - } - } - return handle->db != NULL; -} - -static NSSLOWKEYDBHandle * -nsslowkey_NewHandle(DB *dbHandle) -{ - NSSLOWKEYDBHandle *handle; - handle = (NSSLOWKEYDBHandle *)PORT_ZAlloc (sizeof(NSSLOWKEYDBHandle)); - if (handle == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - handle->appname = NULL; - handle->dbname = NULL; - handle->global_salt = NULL; - handle->updatedb = NULL; - handle->db = dbHandle; - handle->ref = 1; - handle->lock = PZ_NewLock(nssILockKeyDB); - - return handle; -} - -NSSLOWKEYDBHandle * -nsslowkey_OpenKeyDB(PRBool readOnly, const char *appName, const char *prefix, - NSSLOWKEYDBNameFunc namecb, void *cbarg) -{ - NSSLOWKEYDBHandle *handle = NULL; - SECStatus rv; - int openflags; - char *dbname = NULL; - - - handle = nsslowkey_NewHandle(NULL); - - openflags = readOnly ? NO_RDONLY : NO_RDWR; - - - dbname = (*namecb)(cbarg, NSSLOWKEY_DB_FILE_VERSION); - if ( dbname == NULL ) { - goto loser; - } - handle->appname = appName ? PORT_Strdup(appName) : NULL ; - handle->dbname = (appName == NULL) ? PORT_Strdup(dbname) : - (prefix ? PORT_Strdup(prefix) : NULL); - handle->readOnly = readOnly; - - - - handle->db = openOldDB(appName, prefix, dbname, openflags); - if (handle->db) { - verifyVersion(handle); - if (handle->version == 255) { - goto loser; - } - } - - /* if first open fails, try to create a new DB */ - if ( handle->db == NULL ) { - if ( readOnly ) { - goto loser; - } - - rv = openNewDB(appName, prefix, dbname, handle, namecb, cbarg); - /* two processes started to initialize the database at the same time. - * The multiprocess code blocked the second one, then had it retry to - * see if it can just open the database normally */ - if (rv == SECWouldBlock) { - handle->db = openOldDB(appName,prefix,dbname, openflags); - verifyVersion(handle); - if (handle->db == NULL) { - goto loser; - } - } else if (rv != SECSuccess) { - goto loser; - } - } - - handle->global_salt = GetKeyDBGlobalSalt(handle); - if ( dbname ) - PORT_Free( dbname ); - return handle; - -loser: - - if ( dbname ) - PORT_Free( dbname ); - PORT_SetError(SEC_ERROR_BAD_DATABASE); - nsslowkey_CloseKeyDB(handle); - return NULL; -} - -/* - * Close the database - */ -void -nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle) -{ - if (handle != NULL) { - if (handle->db != NULL) { - keydb_Close(handle); - } - if (handle->updatedb) { - handle->updatedb->close(handle->updatedb); - } - if (handle->dbname) PORT_Free(handle->dbname); - if (handle->appname) PORT_Free(handle->appname); - if (handle->global_salt) { - SECITEM_FreeItem(handle->global_salt,PR_TRUE); - } - if (handle->lock != NULL) { - SKIP_AFTER_FORK(PZ_DestroyLock(handle->lock)); - } - - PORT_Free(handle); - } -} - -/* Get the key database version */ -int -nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle) -{ - PORT_Assert(handle != NULL); - - return handle->version; -} - -/* - * Delete a private key that was stored in the database - */ -SECStatus -nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, const SECItem *pubkey) -{ - DBT namekey; - int ret; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(SECFailure); - } - - /* set up db key and data */ - namekey.data = pubkey->data; - namekey.size = pubkey->len; - - /* delete it from the database */ - ret = keydb_Del(handle, &namekey, 0); - if ( ret ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(SECFailure); - } - - /* sync the database */ - ret = keydb_Sync(handle, 0); - if ( ret ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(SECFailure); - } - - return(SECSuccess); -} - -/* - * Store a key in the database, indexed by its public key modulus.(value!) - */ -SECStatus -nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle, - NSSLOWKEYPrivateKey *privkey, - SECItem *pubKeyData, - char *nickname, - SDB *sdb) -{ - return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData, - nickname, sdb, PR_FALSE); -} - -SECStatus -nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle, - NSSLOWKEYPrivateKey *privkey, - SECItem *pubKeyData, - char *nickname, - SDB *sdb) -{ - return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData, - nickname, sdb, PR_TRUE); -} - -/* see if the symetric CKA_ID already Exists. - */ -PRBool -nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id) -{ - DBT namekey; - DBT dummy; - int status; - - namekey.data = (char *)id->data; - namekey.size = id->len; - status = keydb_Get(handle, &namekey, &dummy, 0); - if ( status ) { - return PR_FALSE; - } - - return PR_TRUE; -} - -/* see if the public key for this cert is in the database filed - * by modulus - */ -PRBool -nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cert) -{ - NSSLOWKEYPublicKey *pubkey = NULL; - DBT namekey; - DBT dummy; - int status; - - /* get cert's public key */ - pubkey = nsslowcert_ExtractPublicKey(cert); - if ( pubkey == NULL ) { - return PR_FALSE; - } - - /* TNH - make key from NSSLOWKEYPublicKey */ - switch (pubkey->keyType) { - case NSSLOWKEYRSAKey: - namekey.data = pubkey->u.rsa.modulus.data; - namekey.size = pubkey->u.rsa.modulus.len; - break; - case NSSLOWKEYDSAKey: - namekey.data = pubkey->u.dsa.publicValue.data; - namekey.size = pubkey->u.dsa.publicValue.len; - break; - case NSSLOWKEYDHKey: - namekey.data = pubkey->u.dh.publicValue.data; - namekey.size = pubkey->u.dh.publicValue.len; - break; -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - namekey.data = pubkey->u.ec.publicValue.data; - namekey.size = pubkey->u.ec.publicValue.len; - break; -#endif /* NSS_ENABLE_ECC */ - default: - /* XXX We don't do Fortezza or DH yet. */ - return PR_FALSE; - } - - if (handle->version != 3) { - unsigned char buf[SHA1_LENGTH]; - SHA1_HashBuf(buf,namekey.data,namekey.size); - /* NOTE: don't use pubkey after this! it's now thrashed */ - PORT_Memcpy(namekey.data,buf,sizeof(buf)); - namekey.size = sizeof(buf); - } - - status = keydb_Get(handle, &namekey, &dummy, 0); - /* some databases have the key stored as a signed value */ - if (status) { - unsigned char *buf = (unsigned char *)PORT_Alloc(namekey.size+1); - if (buf) { - PORT_Memcpy(&buf[1], namekey.data, namekey.size); - buf[0] = 0; - namekey.data = buf; - namekey.size ++; - status = keydb_Get(handle, &namekey, &dummy, 0); - PORT_Free(buf); - } - } - nsslowkey_DestroyPublicKey(pubkey); - if ( status ) { - return PR_FALSE; - } - - return PR_TRUE; -} - -typedef struct NSSLowPasswordDataParamStr { - SECItem salt; - SECItem iter; -} NSSLowPasswordDataParam; - -static const SEC_ASN1Template NSSLOWPasswordParamTemplate[] = -{ - {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLowPasswordDataParam) }, - {SEC_ASN1_OCTET_STRING, offsetof(NSSLowPasswordDataParam, salt) }, - {SEC_ASN1_INTEGER, offsetof(NSSLowPasswordDataParam, iter) }, - {0} -}; -struct LGEncryptedDataInfoStr { - SECAlgorithmID algorithm; - SECItem encryptedData; -}; -typedef struct LGEncryptedDataInfoStr LGEncryptedDataInfo; - -const SEC_ASN1Template lg_EncryptedDataInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(LGEncryptedDataInfo) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(LGEncryptedDataInfo,algorithm), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(LGEncryptedDataInfo,encryptedData) }, - { 0 } -}; -static const unsigned char def_iter_data[] = { SEC_ASN1_INTEGER, 0x01, 0x01 }; -static const SECItem def_iter = { siBuffer , - (unsigned char *)def_iter_data, - sizeof(def_iter_data) }; - -static SECItem * -nsslowkey_EncodePW(SECOidTag alg, const SECItem *salt, SECItem *data) -{ - NSSLowPasswordDataParam param; - LGEncryptedDataInfo edi; - PLArenaPool *arena; - unsigned char one = 1; - SECItem *epw = NULL; - SECItem *encParam; - SECStatus rv; - - param.salt = *salt; - param.iter.data = &one; - param.iter.len = 1; - edi.encryptedData = *data; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - return NULL; - } - - encParam = SEC_ASN1EncodeItem(arena, NULL, ¶m, - NSSLOWPasswordParamTemplate); - if (encParam == NULL) { - goto loser; - } - rv = SECOID_SetAlgorithmID(arena, &edi.algorithm, alg, encParam); - if (rv != SECSuccess) { - goto loser; - } - epw = SEC_ASN1EncodeItem(NULL, NULL, &edi, lg_EncryptedDataInfoTemplate); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return epw; -} - -static SECItem * -nsslowkey_DecodePW(const SECItem *derData, SECOidTag *alg, SECItem *salt) -{ - NSSLowPasswordDataParam param; - LGEncryptedDataInfo edi; - PLArenaPool *arena; - SECItem *pwe = NULL; - SECStatus rv; - - salt->data = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - return NULL; - } - - rv = SEC_QuickDERDecodeItem(arena, &edi, lg_EncryptedDataInfoTemplate, - derData); - if (rv != SECSuccess) { - goto loser; - } - *alg = SECOID_GetAlgorithmTag(&edi.algorithm); - rv = SEC_QuickDERDecodeItem(arena, ¶m, NSSLOWPasswordParamTemplate, - &edi.algorithm.parameters); - if (rv != SECSuccess) { - goto loser; - } - if (SECITEM_ItemsAreEqual(¶m.iter, &def_iter) ) { - goto loser; - } - rv = SECITEM_CopyItem(NULL, salt, ¶m.salt); - if (rv != SECSuccess) { - goto loser; - } - pwe = SECITEM_DupItem(&edi.encryptedData); - -loser: - if (!pwe && salt->data) { - PORT_Free(salt->data); - salt->data = NULL; - } - PORT_FreeArena(arena, PR_FALSE); - return pwe; -} - - -/* - * check to see if the user has a password - */ -static SECStatus -nsslowkey_GetPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entry) -{ - DBT checkkey; /*, checkdata; */ - NSSLOWKEYDBKey *dbkey = NULL; - SECItem *global_salt = NULL; - SECItem *item = NULL; - SECItem entryData, oid; - SECItem none = { siBuffer, NULL, 0 }; - SECStatus rv = SECFailure; - SECOidTag algorithm; - - if (handle == NULL) { - /* PORT_SetError */ - return(SECFailure); - } - - global_salt = GetKeyDBGlobalSalt(handle); - if (!global_salt) { - global_salt = &none; - } - if (global_salt->len > sizeof(entry->data)) { - /* PORT_SetError */ - goto loser; - } - - PORT_Memcpy(entry->data, global_salt->data, global_salt->len); - entry->salt.data = entry->data; - entry->salt.len = global_salt->len; - entry->value.data = &entry->data[entry->salt.len]; - - checkkey.data = KEYDB_PW_CHECK_STRING; - checkkey.size = KEYDB_PW_CHECK_LEN; - dbkey = get_dbkey(handle, &checkkey); - if (dbkey == NULL) { - /* handle 'FAKE' check here */ - goto loser; - } - - oid.len = dbkey->derPK.data[0]; - oid.data = &dbkey->derPK.data[1]; - - if (dbkey->derPK.len < (KEYDB_PW_CHECK_LEN + 1 +oid.len)) { - goto loser; - } - algorithm = SECOID_FindOIDTag(&oid); - entryData.type = siBuffer; - entryData.len = dbkey->derPK.len - (oid.len+1); - entryData.data = &dbkey->derPK.data[oid.len+1]; - - item = nsslowkey_EncodePW(algorithm, &dbkey->salt, &entryData); - if (!item || (item->len + entry->salt.len) > sizeof(entry->data)) { - goto loser; - } - PORT_Memcpy(entry->value.data, item->data, item->len); - entry->value.len = item->len; - rv = SECSuccess; - -loser: - if (item) { - SECITEM_FreeItem(item, PR_TRUE); - } - if (dbkey) { - sec_destroy_dbkey(dbkey); - } - if (global_salt && global_salt != &none) { - SECITEM_FreeItem(global_salt,PR_TRUE); - } - return rv; -} - -/* - * check to see if the user has a password - */ -static SECStatus -nsslowkey_PutPWCheckEntry(NSSLOWKEYDBHandle *handle,NSSLOWKEYPasswordEntry *entry) -{ - DBT checkkey; - NSSLOWKEYDBKey *dbkey = NULL; - SECItem *item = NULL; - SECItem salt; - SECOidTag algid; - SECStatus rv = SECFailure; - PLArenaPool *arena; - int ret; - - if (handle == NULL) { - /* PORT_SetError */ - return(SECFailure); - } - - checkkey.data = KEYDB_PW_CHECK_STRING; - checkkey.size = KEYDB_PW_CHECK_LEN; - - salt.data = NULL; - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - return SECFailure; - } - - item = nsslowkey_DecodePW(&entry->value, &algid, &salt); - if (item == NULL) { - goto loser; - } - - dbkey = PORT_ArenaZNew(arena, NSSLOWKEYDBKey); - if (dbkey == NULL) { - goto loser; - } - - dbkey->arena = arena; - - rv = SECITEM_CopyItem(arena, &dbkey->salt, &salt); - if (rv != SECSuccess) { - goto loser; - } - - rv = encodePWCheckEntry(arena, &dbkey->derPK, algid, item); - if (rv != SECSuccess) { - goto loser; - } - - rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE); - if (rv != SECSuccess) { - goto loser; - } - - if (handle->global_salt) { - SECITEM_FreeItem(handle->global_salt, PR_TRUE); - handle->global_salt = NULL; - } - rv = StoreKeyDBGlobalSalt(handle, &entry->salt); - if (rv != SECSuccess) { - goto loser; - } - ret = keydb_Sync(handle, 0); - if ( ret ) { - rv = SECFailure; - goto loser; - } - handle->global_salt = GetKeyDBGlobalSalt(handle); - -loser: - if (item) { - SECITEM_FreeItem(item, PR_TRUE); - } - if (arena) { - PORT_FreeArena(arena, PR_TRUE); - } - if (salt.data) { - PORT_Free(salt.data); - } - return rv; -} - -#ifdef EC_DEBUG -#define SEC_PRINT(str1, str2, num, sitem) \ - printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \ - str1, str2, num, sitem->len); \ - for (i = 0; i < sitem->len; i++) { \ - printf("%02x:", sitem->data[i]); \ - } \ - printf("\n") -#else -#define SEC_PRINT(a, b, c, d) -#endif /* EC_DEBUG */ - - -SECStatus -seckey_encrypt_private_key( PLArenaPool *permarena, NSSLOWKEYPrivateKey *pk, - SDB *sdbpw, SECItem *result) -{ - NSSLOWKEYPrivateKeyInfo *pki = NULL; - SECStatus rv = SECFailure; - PLArenaPool *temparena = NULL; - SECItem *der_item = NULL; - SECItem *cipherText = NULL; - SECItem *dummy = NULL; -#ifdef NSS_ENABLE_ECC - SECItem *fordebug = NULL; - int savelen; -#endif - - temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if(temparena == NULL) - goto loser; - - /* allocate structures */ - pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena, - sizeof(NSSLOWKEYPrivateKeyInfo)); - der_item = (SECItem *)PORT_ArenaZAlloc(temparena, sizeof(SECItem)); - if((pki == NULL) || (der_item == NULL)) - goto loser; - - - /* setup private key info */ - dummy = SEC_ASN1EncodeInteger(temparena, &(pki->version), - NSSLOWKEY_PRIVATE_KEY_INFO_VERSION); - if(dummy == NULL) - goto loser; - - /* Encode the key, and set the algorithm (with params) */ - switch (pk->keyType) { - case NSSLOWKEYRSAKey: - prepare_low_rsa_priv_key_for_asn1(pk); - dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk, - nsslowkey_RSAPrivateKeyTemplate); - if (dummy == NULL) { - rv = SECFailure; - goto loser; - } - - rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm), - SEC_OID_PKCS1_RSA_ENCRYPTION, 0); - if (rv == SECFailure) { - goto loser; - } - - break; - case NSSLOWKEYDSAKey: - prepare_low_dsa_priv_key_for_asn1(pk); - dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk, - nsslowkey_DSAPrivateKeyTemplate); - if (dummy == NULL) { - rv = SECFailure; - goto loser; - } - - prepare_low_pqg_params_for_asn1(&pk->u.dsa.params); - dummy = SEC_ASN1EncodeItem(temparena, NULL, &pk->u.dsa.params, - nsslowkey_PQGParamsTemplate); - if (dummy == NULL) { - rv = SECFailure; - goto loser; - } - - rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm), - SEC_OID_ANSIX9_DSA_SIGNATURE, dummy); - if (rv == SECFailure) { - goto loser; - } - - break; - case NSSLOWKEYDHKey: - prepare_low_dh_priv_key_for_asn1(pk); - dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk, - nsslowkey_DHPrivateKeyTemplate); - if (dummy == NULL) { - rv = SECFailure; - goto loser; - } - - rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm), - SEC_OID_X942_DIFFIE_HELMAN_KEY, dummy); - if (rv == SECFailure) { - goto loser; - } - break; -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - prepare_low_ec_priv_key_for_asn1(pk); - /* Public value is encoded as a bit string so adjust length - * to be in bits before ASN encoding and readjust - * immediately after. - * - * Since the SECG specification recommends not including the - * parameters as part of ECPrivateKey, we zero out the curveOID - * length before encoding and restore it later. - */ - pk->u.ec.publicValue.len <<= 3; - savelen = pk->u.ec.ecParams.curveOID.len; - pk->u.ec.ecParams.curveOID.len = 0; - dummy = SEC_ASN1EncodeItem(temparena, &(pki->privateKey), pk, - nsslowkey_ECPrivateKeyTemplate); - pk->u.ec.ecParams.curveOID.len = savelen; - pk->u.ec.publicValue.len >>= 3; - - if (dummy == NULL) { - rv = SECFailure; - goto loser; - } - - dummy = &pk->u.ec.ecParams.DEREncoding; - - /* At this point dummy should contain the encoded params */ - rv = SECOID_SetAlgorithmID(temparena, &(pki->algorithm), - SEC_OID_ANSIX962_EC_PUBLIC_KEY, dummy); - - if (rv == SECFailure) { - goto loser; - } - - fordebug = &(pki->privateKey); - SEC_PRINT("seckey_encrypt_private_key()", "PrivateKey", - pk->keyType, fordebug); - - break; -#endif /* NSS_ENABLE_ECC */ - default: - /* We don't support DH or Fortezza private keys yet */ - PORT_Assert(PR_FALSE); - break; - } - - /* setup encrypted private key info */ - dummy = SEC_ASN1EncodeItem(temparena, der_item, pki, - nsslowkey_PrivateKeyInfoTemplate); - - SEC_PRINT("seckey_encrypt_private_key()", "PrivateKeyInfo", - pk->keyType, der_item); - - if(dummy == NULL) { - rv = SECFailure; - goto loser; - } - - rv = lg_util_encrypt(temparena, sdbpw, dummy, &cipherText); - if (rv != SECSuccess) { - goto loser; - } - - rv = SECITEM_CopyItem ( permarena, result, cipherText); - -loser: - - if(temparena != NULL) - PORT_FreeArena(temparena, PR_TRUE); - - return rv; -} - -static SECStatus -seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SDB *sdbpw, - NSSLOWKEYPrivateKey *pk, char *nickname, PRBool update) -{ - NSSLOWKEYDBKey *dbkey = NULL; - PLArenaPool *arena = NULL; - SECStatus rv = SECFailure; - - if((keydb == NULL) || (index == NULL) || (sdbpw == NULL) || - (pk == NULL)) - return SECFailure; - - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if(arena == NULL) - return SECFailure; - - dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey)); - if(dbkey == NULL) - goto loser; - dbkey->arena = arena; - dbkey->nickname = nickname; - - rv = seckey_encrypt_private_key(arena, pk, sdbpw, &dbkey->derPK); - if(rv != SECSuccess) - goto loser; - - rv = put_dbkey(keydb, index, dbkey, update); - - /* let success fall through */ -loser: - if(arena != NULL) - PORT_FreeArena(arena, PR_TRUE); - - return rv; -} - -/* - * Store a key in the database, indexed by its public key modulus. - * Note that the nickname is optional. It was only used by keyutil. - */ -SECStatus -nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle, - NSSLOWKEYPrivateKey *privkey, - SECItem *pubKeyData, - char *nickname, - SDB *sdbpw, - PRBool update) -{ - DBT namekey; - SECStatus rv; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(SECFailure); - } - - /* set up db key and data */ - namekey.data = pubKeyData->data; - namekey.size = pubKeyData->len; - - /* encrypt the private key */ - rv = seckey_put_private_key(handle, &namekey, sdbpw, privkey, nickname, - update); - - return(rv); -} - -static NSSLOWKEYPrivateKey * -seckey_decrypt_private_key(SECItem*epki, - SDB *sdbpw) -{ - NSSLOWKEYPrivateKey *pk = NULL; - NSSLOWKEYPrivateKeyInfo *pki = NULL; - SECStatus rv = SECFailure; - PLArenaPool *temparena = NULL, *permarena = NULL; - SECItem *dest = NULL; -#ifdef NSS_ENABLE_ECC - SECItem *fordebug = NULL; -#endif - - if((epki == NULL) || (sdbpw == NULL)) - goto loser; - - temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if((temparena == NULL) || (permarena == NULL)) - goto loser; - - /* allocate temporary items */ - pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(temparena, - sizeof(NSSLOWKEYPrivateKeyInfo)); - - /* allocate permanent arena items */ - pk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(permarena, - sizeof(NSSLOWKEYPrivateKey)); - - if((pk == NULL) || (pki == NULL)) - goto loser; - - pk->arena = permarena; - - rv = lg_util_decrypt(sdbpw, epki, &dest); - if (rv != SECSuccess) { - goto loser; - } - - if(dest != NULL) - { - SECItem newPrivateKey; - SECItem newAlgParms; - - SEC_PRINT("seckey_decrypt_private_key()", "PrivateKeyInfo", -1, - dest); - - rv = SEC_QuickDERDecodeItem(temparena, pki, - nsslowkey_PrivateKeyInfoTemplate, dest); - if(rv == SECSuccess) - { - switch(SECOID_GetAlgorithmTag(&pki->algorithm)) { - case SEC_OID_X500_RSA_ENCRYPTION: - case SEC_OID_PKCS1_RSA_ENCRYPTION: - pk->keyType = NSSLOWKEYRSAKey; - prepare_low_rsa_priv_key_for_asn1(pk); - if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey, - &pki->privateKey) ) break; - rv = SEC_QuickDERDecodeItem(permarena, pk, - nsslowkey_RSAPrivateKeyTemplate, - &newPrivateKey); - break; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - pk->keyType = NSSLOWKEYDSAKey; - prepare_low_dsa_priv_key_for_asn1(pk); - if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey, - &pki->privateKey) ) break; - rv = SEC_QuickDERDecodeItem(permarena, pk, - nsslowkey_DSAPrivateKeyTemplate, - &newPrivateKey); - if (rv != SECSuccess) - goto loser; - prepare_low_pqg_params_for_asn1(&pk->u.dsa.params); - if (SECSuccess != SECITEM_CopyItem(permarena, &newAlgParms, - &pki->algorithm.parameters) ) break; - rv = SEC_QuickDERDecodeItem(permarena, &pk->u.dsa.params, - nsslowkey_PQGParamsTemplate, - &newAlgParms); - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: - pk->keyType = NSSLOWKEYDHKey; - prepare_low_dh_priv_key_for_asn1(pk); - if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey, - &pki->privateKey) ) break; - rv = SEC_QuickDERDecodeItem(permarena, pk, - nsslowkey_DHPrivateKeyTemplate, - &newPrivateKey); - break; -#ifdef NSS_ENABLE_ECC - case SEC_OID_ANSIX962_EC_PUBLIC_KEY: - pk->keyType = NSSLOWKEYECKey; - prepare_low_ec_priv_key_for_asn1(pk); - - fordebug = &pki->privateKey; - SEC_PRINT("seckey_decrypt_private_key()", "PrivateKey", - pk->keyType, fordebug); - if (SECSuccess != SECITEM_CopyItem(permarena, &newPrivateKey, - &pki->privateKey) ) break; - rv = SEC_QuickDERDecodeItem(permarena, pk, - nsslowkey_ECPrivateKeyTemplate, - &newPrivateKey); - if (rv != SECSuccess) - goto loser; - - prepare_low_ecparams_for_asn1(&pk->u.ec.ecParams); - - rv = SECITEM_CopyItem(permarena, - &pk->u.ec.ecParams.DEREncoding, - &pki->algorithm.parameters); - - if (rv != SECSuccess) - goto loser; - - /* Fill out the rest of EC params */ - rv = LGEC_FillParams(permarena, &pk->u.ec.ecParams.DEREncoding, - &pk->u.ec.ecParams); - - if (rv != SECSuccess) - goto loser; - - if (pk->u.ec.publicValue.len != 0) { - pk->u.ec.publicValue.len >>= 3; - } - - break; -#endif /* NSS_ENABLE_ECC */ - default: - rv = SECFailure; - break; - } - } - else if(PORT_GetError() == SEC_ERROR_BAD_DER) - { - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - goto loser; - } - } - - /* let success fall through */ -loser: - if(temparena != NULL) - PORT_FreeArena(temparena, PR_TRUE); - if(dest != NULL) - SECITEM_ZfreeItem(dest, PR_TRUE); - - if(rv != SECSuccess) - { - if(permarena != NULL) - PORT_FreeArena(permarena, PR_TRUE); - pk = NULL; - } - - return pk; -} - -static NSSLOWKEYPrivateKey * -seckey_decode_encrypted_private_key(NSSLOWKEYDBKey *dbkey, SDB *sdbpw) -{ - if( ( dbkey == NULL ) || ( sdbpw == NULL ) ) { - return NULL; - } - - return seckey_decrypt_private_key(&(dbkey->derPK), sdbpw); -} - -static NSSLOWKEYPrivateKey * -seckey_get_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, char **nickname, - SDB *sdbpw) -{ - NSSLOWKEYDBKey *dbkey = NULL; - NSSLOWKEYPrivateKey *pk = NULL; - - if( ( keydb == NULL ) || ( index == NULL ) || ( sdbpw == NULL ) ) { - return NULL; - } - - dbkey = get_dbkey(keydb, index); - if(dbkey == NULL) { - goto loser; - } - - if ( nickname ) { - if ( dbkey->nickname && ( dbkey->nickname[0] != 0 ) ) { - *nickname = PORT_Strdup(dbkey->nickname); - } else { - *nickname = NULL; - } - } - - pk = seckey_decode_encrypted_private_key(dbkey, sdbpw); - - /* let success fall through */ -loser: - - if ( dbkey != NULL ) { - sec_destroy_dbkey(dbkey); - } - - return pk; -} - -/* - * Find a key in the database, indexed by its public key modulus - * This is used to find keys that have been stored before their - * certificate arrives. Once the certificate arrives the key - * is looked up by the public modulus in the certificate, and the - * re-stored by its nickname. - */ -NSSLOWKEYPrivateKey * -nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus, - SDB *sdbpw) -{ - DBT namekey; - NSSLOWKEYPrivateKey *pk = NULL; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return NULL; - } - - /* set up db key */ - namekey.data = modulus->data; - namekey.size = modulus->len; - - pk = seckey_get_private_key(handle, &namekey, NULL, sdbpw); - - /* no need to free dbkey, since its on the stack, and the data it - * points to is owned by the database - */ - return(pk); -} - -char * -nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle, - SECItem *modulus, SDB *sdbpw) -{ - DBT namekey; - NSSLOWKEYPrivateKey *pk = NULL; - char *nickname = NULL; - - if (handle == NULL) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return NULL; - } - - /* set up db key */ - namekey.data = modulus->data; - namekey.size = modulus->len; - - pk = seckey_get_private_key(handle, &namekey, &nickname, sdbpw); - if (pk) { - nsslowkey_DestroyPrivateKey(pk); - } - - /* no need to free dbkey, since its on the stack, and the data it - * points to is owned by the database - */ - return(nickname); -} -/* ===== ENCODING ROUTINES ===== */ - -static SECStatus -encodePWCheckEntry(PLArenaPool *arena, SECItem *entry, SECOidTag alg, - SECItem *encCheck) -{ - SECOidData *oidData; - SECStatus rv; - - oidData = SECOID_FindOIDByTag(alg); - if ( oidData == NULL ) { - rv = SECFailure; - goto loser; - } - - entry->len = 1 + oidData->oid.len + encCheck->len; - if ( arena ) { - entry->data = (unsigned char *)PORT_ArenaAlloc(arena, entry->len); - } else { - entry->data = (unsigned char *)PORT_Alloc(entry->len); - } - - if ( entry->data == NULL ) { - goto loser; - } - - /* first length of oid */ - entry->data[0] = (unsigned char)oidData->oid.len; - /* next oid itself */ - PORT_Memcpy(&entry->data[1], oidData->oid.data, oidData->oid.len); - /* finally the encrypted check string */ - PORT_Memcpy(&entry->data[1+oidData->oid.len], encCheck->data, - encCheck->len); - - return(SECSuccess); - -loser: - return(SECFailure); -} - - -#define MAX_DB_SIZE 0xffff -/* - * Clear out all the keys in the existing database - */ -static SECStatus -nsslowkey_ResetKeyDB(NSSLOWKEYDBHandle *handle) -{ - SECStatus rv; - int ret; - int errors = 0; - - if ( handle->db == NULL ) { - return(SECSuccess); - } - - if (handle->readOnly) { - /* set an error code */ - return SECFailure; - } - - if (handle->appname == NULL && handle->dbname == NULL) { - return SECFailure; - } - - keydb_Close(handle); - if (handle->appname) { - handle->db= - rdbopen(handle->appname, handle->dbname, "key", NO_CREATE, NULL); - } else { - handle->db = dbopen( handle->dbname, NO_CREATE, 0600, DB_HASH, 0 ); - } - if (handle->db == NULL) { - /* set an error code */ - return SECFailure; - } - - rv = makeGlobalVersion(handle); - if ( rv != SECSuccess ) { - errors++; - goto done; - } - - if (handle->global_salt) { - rv = StoreKeyDBGlobalSalt(handle, handle->global_salt); - } else { - rv = makeGlobalSalt(handle); - if ( rv == SECSuccess ) { - handle->global_salt = GetKeyDBGlobalSalt(handle); - } - } - if ( rv != SECSuccess ) { - errors++; - } - -done: - /* sync the database */ - ret = keydb_Sync(handle, 0); - db_InitComplete(handle->db); - - return (errors == 0 ? SECSuccess : SECFailure); -} - -static int -keydb_Get(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret; - PRLock *kdbLock = kdb->lock; - DB *db = kdb->db; - - PORT_Assert(kdbLock != NULL); - PZ_Lock(kdbLock); - - ret = (* db->get)(db, key, data, flags); - - prstat = PZ_Unlock(kdbLock); - - return(ret); -} - -static int -keydb_Put(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret = 0; - PRLock *kdbLock = kdb->lock; - DB *db = kdb->db; - - PORT_Assert(kdbLock != NULL); - PZ_Lock(kdbLock); - - ret = (* db->put)(db, key, data, flags); - - prstat = PZ_Unlock(kdbLock); - - return(ret); -} - -static int -keydb_Sync(NSSLOWKEYDBHandle *kdb, unsigned int flags) -{ - PRStatus prstat; - int ret; - PRLock *kdbLock = kdb->lock; - DB *db = kdb->db; - - PORT_Assert(kdbLock != NULL); - PZ_Lock(kdbLock); - - ret = (* db->sync)(db, flags); - - prstat = PZ_Unlock(kdbLock); - - return(ret); -} - -static int -keydb_Del(NSSLOWKEYDBHandle *kdb, DBT *key, unsigned int flags) -{ - PRStatus prstat; - int ret; - PRLock *kdbLock = kdb->lock; - DB *db = kdb->db; - - PORT_Assert(kdbLock != NULL); - PZ_Lock(kdbLock); - - ret = (* db->del)(db, key, flags); - - prstat = PZ_Unlock(kdbLock); - - return(ret); -} - -static int -keydb_Seq(NSSLOWKEYDBHandle *kdb, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret; - PRLock *kdbLock = kdb->lock; - DB *db = kdb->db; - - PORT_Assert(kdbLock != NULL); - PZ_Lock(kdbLock); - - ret = (* db->seq)(db, key, data, flags); - - prstat = PZ_Unlock(kdbLock); - - return(ret); -} - -static void -keydb_Close(NSSLOWKEYDBHandle *kdb) -{ - PRStatus prstat; - PRLock *kdbLock = kdb->lock; - DB *db = kdb->db; - - PORT_Assert(kdbLock != NULL); - SKIP_AFTER_FORK(PZ_Lock(kdbLock)); - - (* db->close)(db); - - SKIP_AFTER_FORK(prstat = PZ_Unlock(kdbLock)); - - return; -} - -/* - * SDB Entry Points for the Key DB - */ - -CK_RV -lg_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2) -{ - NSSLOWKEYDBHandle *keydb; - NSSLOWKEYPasswordEntry entry; - SECStatus rv; - - keydb = lg_getKeyDB(sdb); - if (keydb == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - if (PORT_Strcmp(id,"password") != 0) { - /* shouldn't happen */ - return CKR_GENERAL_ERROR; /* no extra data stored */ - } - rv = nsslowkey_GetPWCheckEntry(keydb, &entry); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - item1->len = entry.salt.len; - PORT_Memcpy(item1->data, entry.salt.data, item1->len); - item2->len = entry.value.len; - PORT_Memcpy(item2->data, entry.value.data, item2->len); - return CKR_OK; -} - -CK_RV -lg_PutMetaData(SDB *sdb, const char *id, - const SECItem *item1, const SECItem *item2) -{ - NSSLOWKEYDBHandle *keydb; - NSSLOWKEYPasswordEntry entry; - SECStatus rv; - - keydb = lg_getKeyDB(sdb); - if (keydb == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - if (PORT_Strcmp(id,"password") != 0) { - /* shouldn't happen */ - return CKR_GENERAL_ERROR; /* no extra data stored */ - } - entry.salt = *item1; - entry.value = *item2; - rv = nsslowkey_PutPWCheckEntry(keydb, &entry); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - return CKR_OK; -} - -CK_RV -lg_Reset(SDB *sdb) -{ - NSSLOWKEYDBHandle *keydb; - SECStatus rv; - - keydb = lg_getKeyDB(sdb); - if (keydb == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - rv = nsslowkey_ResetKeyDB(keydb); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - return CKR_OK; -} - diff --git a/security/nss/lib/softoken/legacydb/keydbi.h b/security/nss/lib/softoken/legacydb/keydbi.h deleted file mode 100644 index f7f427266..000000000 --- a/security/nss/lib/softoken/legacydb/keydbi.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * private.h - Private data structures for the software token library - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#ifndef _KEYDBI_H_ -#define _KEYDBI_H_ - -#include "nspr.h" -#include "seccomon.h" -#include "mcom_db.h" - -/* - * Handle structure for open key databases - */ -struct NSSLOWKEYDBHandleStr { - DB *db; - DB *updatedb; /* used when updating an old version */ - SECItem *global_salt; /* password hashing salt for this db */ - int version; /* version of the database */ - char *appname; /* multiaccess app name */ - char *dbname; /* name of the openned DB */ - PRBool readOnly; /* is the DB read only */ - PRLock *lock; - PRInt32 ref; /* reference count */ -}; - -/* -** Typedef for callback for traversing key database. -** "key" is the key used to index the data in the database (nickname) -** "data" is the key data -** "pdata" is the user's data -*/ -typedef SECStatus (* NSSLOWKEYTraverseKeysFunc)(DBT *key, DBT *data, void *pdata); - - -SEC_BEGIN_PROTOS - -/* -** Traverse the entire key database, and pass the nicknames and keys to a -** user supplied function. -** "f" is the user function to call for each key -** "udata" is the user's data, which is passed through to "f" -*/ -extern SECStatus nsslowkey_TraverseKeys(NSSLOWKEYDBHandle *handle, - NSSLOWKEYTraverseKeysFunc f, - void *udata); - -SEC_END_PROTOS - -#endif /* _KEYDBI_H_ */ diff --git a/security/nss/lib/softoken/legacydb/lgattr.c b/security/nss/lib/softoken/legacydb/lgattr.c deleted file mode 100644 index 344644888..000000000 --- a/security/nss/lib/softoken/legacydb/lgattr.c +++ /dev/null @@ -1,1824 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * Internal PKCS #11 functions. Should only be called by pkcs11.c - */ -#include "pkcs11.h" -#include "lgdb.h" - -#include "pcertt.h" -#include "lowkeyi.h" -#include "pcert.h" -#include "blapi.h" -#include "secerr.h" -#include "secasn1.h" - -/* - * Cache the object we are working on during Set's and Get's - */ -typedef struct LGObjectCacheStr { - CK_OBJECT_CLASS objclass; - CK_OBJECT_HANDLE handle; - SDB *sdb; - void *objectInfo; - LGFreeFunc infoFree; - SECItem dbKey; -} LGObjectCache; - -static const CK_OBJECT_HANDLE lg_classArray[] = { - 0, CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_SECRET_KEY, - CKO_NETSCAPE_TRUST, CKO_NETSCAPE_CRL, CKO_NETSCAPE_SMIME, - CKO_CERTIFICATE }; - -#define handleToClass(handle) \ - lg_classArray[((handle & LG_TOKEN_TYPE_MASK))>>LG_TOKEN_TYPE_SHIFT] - - -static void lg_DestroyObjectCache(LGObjectCache *obj); - -static LGObjectCache * -lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle) -{ - LGObjectCache *obj = NULL; - SECStatus rv; - - obj = PORT_New(LGObjectCache); - if (obj == NULL) { - return NULL; - } - - obj->objclass = handleToClass(handle); - obj->handle = handle; - obj->sdb = sdb; - obj->objectInfo = NULL; - obj->infoFree = NULL; - obj->dbKey.data = NULL; - obj->dbKey.len = 0; - lg_DBLock(sdb); - if (dbKey == NULL) { - dbKey = lg_lookupTokenKeyByHandle(sdb,handle); - } - if (dbKey == NULL) { - lg_DBUnlock(sdb); - goto loser; - } - rv = SECITEM_CopyItem(NULL,&obj->dbKey,dbKey); - lg_DBUnlock(sdb); - if (rv != SECSuccess) { - goto loser; - } - - return obj; -loser: - if (obj) { - (void) lg_DestroyObjectCache(obj); - } - return NULL; - -} - -/* - * free all the data associated with an object. Object reference count must - * be 'zero'. - */ -static void -lg_DestroyObjectCache(LGObjectCache *obj) -{ - if (obj->dbKey.data) { - PORT_Free(obj->dbKey.data); - obj->dbKey.data = NULL; - } - if (obj->objectInfo) { - (*obj->infoFree)(obj->objectInfo); - obj->objectInfo = NULL; - obj->infoFree = NULL; - } - PORT_Free(obj); -} -/* - * ******************** Attribute Utilities ******************************* - */ - -static CK_RV -lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value) -{ - unsigned char *data; - int i; - - if (attr->pValue == NULL) { - attr->ulValueLen = 4; - return CKR_OK; - } - if (attr->ulValueLen < 4) { - attr->ulValueLen = (CK_ULONG) -1; - return CKR_BUFFER_TOO_SMALL; - } - - data = (unsigned char *)attr->pValue; - for (i=0; i < 4; i++) { - data[i] = (value >> ((3-i)*8)) & 0xff; - } - attr->ulValueLen = 4; - return CKR_OK; -} - -static CK_RV -lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, - CK_VOID_PTR value, CK_ULONG len) -{ - - if (attr->pValue == NULL) { - attr->ulValueLen = len; - return CKR_OK; - } - if (attr->ulValueLen < len) { - attr->ulValueLen = (CK_ULONG) -1; - return CKR_BUFFER_TOO_SMALL; - } - PORT_Memcpy(attr->pValue,value,len); - attr->ulValueLen = len; - return CKR_OK; -} - -static CK_RV -lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, - void *value, CK_ULONG len) -{ - unsigned char * dval = (unsigned char *)value; - if (*dval == 0) { - dval++; - len--; - } - return lg_CopyAttribute(attribute,type,dval,len); -} - -static CK_RV -lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, - void *value, CK_ULONG len, SDB *sdbpw) -{ - SECItem plainText, *cipherText = NULL; - CK_RV crv = CKR_USER_NOT_LOGGED_IN; - SECStatus rv; - - plainText.data = value; - plainText.len = len; - rv = lg_util_encrypt(NULL, sdbpw, &plainText, &cipherText); - if (rv != SECSuccess) { - goto loser; - } - crv = lg_CopyAttribute(attribute,type,cipherText->data,cipherText->len); -loser: - if (cipherText) { - SECITEM_FreeItem(cipherText,PR_TRUE); - } - return crv; -} - -static CK_RV -lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, - void *value, CK_ULONG len, SDB *sdbpw) -{ - unsigned char * dval = (unsigned char *)value; - - if (*dval == 0) { - dval++; - len--; - } - return lg_CopyPrivAttribute(attribute,type,dval,len,sdbpw); -} - -static CK_RV -lg_invalidAttribute(CK_ATTRIBUTE *attr) -{ - attr->ulValueLen = (CK_ULONG) -1; - return CKR_ATTRIBUTE_TYPE_INVALID; -} - - -#define LG_DEF_ATTRIBUTE(value,len) \ - { 0, value, len } - -#define LG_CLONE_ATTR(attribute, type, staticAttr) \ - lg_CopyAttribute(attribute, type, staticAttr.pValue, staticAttr.ulValueLen) - -CK_BBOOL lg_staticTrueValue = CK_TRUE; -CK_BBOOL lg_staticFalseValue = CK_FALSE; -static const CK_ATTRIBUTE lg_StaticTrueAttr = - LG_DEF_ATTRIBUTE(&lg_staticTrueValue,sizeof(lg_staticTrueValue)); -static const CK_ATTRIBUTE lg_StaticFalseAttr = - LG_DEF_ATTRIBUTE(&lg_staticFalseValue,sizeof(lg_staticFalseValue)); -static const CK_ATTRIBUTE lg_StaticNullAttr = LG_DEF_ATTRIBUTE(NULL,0); -char lg_StaticOneValue = 1; -static const CK_ATTRIBUTE lg_StaticOneAttr = - LG_DEF_ATTRIBUTE(&lg_StaticOneValue,sizeof(lg_StaticOneValue)); - -/* - * helper functions which get the database and call the underlying - * low level database function. - */ -static char * -lg_FindKeyNicknameByPublicKey(SDB *sdb, SECItem *dbKey) -{ - NSSLOWKEYDBHandle *keyHandle; - char * label; - - keyHandle = lg_getKeyDB(sdb); - if (!keyHandle) { - return NULL; - } - - label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey, - sdb); - return label; -} - - -NSSLOWKEYPrivateKey * -lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey) -{ - NSSLOWKEYPrivateKey *privKey; - NSSLOWKEYDBHandle *keyHandle; - - keyHandle = lg_getKeyDB(sdb); - if (keyHandle == NULL) { - return NULL; - } - privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb); - if (privKey == NULL) { - return NULL; - } - return privKey; -} - -static certDBEntrySMime * -lg_getSMime(LGObjectCache *obj) -{ - certDBEntrySMime *entry; - NSSLOWCERTCertDBHandle *certHandle; - - if (obj->objclass != CKO_NETSCAPE_SMIME) { - return NULL; - } - if (obj->objectInfo) { - return (certDBEntrySMime *)obj->objectInfo; - } - - certHandle = lg_getCertDB(obj->sdb); - if (!certHandle) { - return NULL; - } - entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data); - obj->objectInfo = (void *)entry; - obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry; - return entry; -} - -static certDBEntryRevocation * -lg_getCrl(LGObjectCache *obj) -{ - certDBEntryRevocation *crl; - PRBool isKrl; - NSSLOWCERTCertDBHandle *certHandle; - - if (obj->objclass != CKO_NETSCAPE_CRL) { - return NULL; - } - if (obj->objectInfo) { - return (certDBEntryRevocation *)obj->objectInfo; - } - - isKrl = (PRBool) (obj->handle == LG_TOKEN_KRL_HANDLE); - certHandle = lg_getCertDB(obj->sdb); - if (!certHandle) { - return NULL; - } - - crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl); - obj->objectInfo = (void *)crl; - obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry; - return crl; -} - -static NSSLOWCERTCertificate * -lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle) -{ - NSSLOWCERTCertificate *cert; - CK_OBJECT_CLASS objClass = obj->objclass; - - if ((objClass != CKO_CERTIFICATE) && (objClass != CKO_NETSCAPE_TRUST)) { - return NULL; - } - if (objClass == CKO_CERTIFICATE && obj->objectInfo) { - return (NSSLOWCERTCertificate *)obj->objectInfo; - } - cert = nsslowcert_FindCertByKey(certHandle, &obj->dbKey); - if (objClass == CKO_CERTIFICATE) { - obj->objectInfo = (void *)cert; - obj->infoFree = (LGFreeFunc) nsslowcert_DestroyCertificate ; - } - return cert; -} - -static NSSLOWCERTTrust * -lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle) -{ - NSSLOWCERTTrust *trust; - - if (obj->objclass != CKO_NETSCAPE_TRUST) { - return NULL; - } - if (obj->objectInfo) { - return (NSSLOWCERTTrust *)obj->objectInfo; - } - trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey); - obj->objectInfo = (void *)trust; - obj->infoFree = (LGFreeFunc) nsslowcert_DestroyTrust ; - return trust; -} - -static NSSLOWKEYPublicKey * -lg_GetPublicKey(LGObjectCache *obj) -{ - NSSLOWKEYPublicKey *pubKey; - NSSLOWKEYPrivateKey *privKey; - - if (obj->objclass != CKO_PUBLIC_KEY) { - return NULL; - } - if (obj->objectInfo) { - return (NSSLOWKEYPublicKey *)obj->objectInfo; - } - privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey); - if (privKey == NULL) { - return NULL; - } - pubKey = nsslowkey_ConvertToPublicKey(privKey); - nsslowkey_DestroyPrivateKey(privKey); - obj->objectInfo = (void *) pubKey; - obj->infoFree = (LGFreeFunc) nsslowkey_DestroyPublicKey ; - return pubKey; -} - -/* - * we need two versions of lg_GetPrivateKey. One version that takes the - * DB handle so we can pass the handle we have already acquired in, - * rather than going through the 'getKeyDB' code again, - * which may fail the second time and another which just aquires - * the key handle from the sdb (where we don't already have a key handle. - * This version does the former. - */ -static NSSLOWKEYPrivateKey * -lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle) -{ - NSSLOWKEYPrivateKey *privKey; - - if ((obj->objclass != CKO_PRIVATE_KEY) && - (obj->objclass != CKO_SECRET_KEY)) { - return NULL; - } - if (obj->objectInfo) { - return (NSSLOWKEYPrivateKey *)obj->objectInfo; - } - privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb); - if (privKey == NULL) { - return NULL; - } - obj->objectInfo = (void *) privKey; - obj->infoFree = (LGFreeFunc) nsslowkey_DestroyPrivateKey ; - return privKey; -} - -/* this version does the latter */ -static NSSLOWKEYPrivateKey * -lg_GetPrivateKey(LGObjectCache *obj) -{ - NSSLOWKEYDBHandle *keyHandle; - NSSLOWKEYPrivateKey *privKey; - - keyHandle = lg_getKeyDB(obj->sdb); - if (!keyHandle) { - return NULL; - } - privKey = lg_GetPrivateKeyWithDB(obj, keyHandle); - return privKey; -} - -/* lg_GetPubItem returns data associated with the public key. - * one only needs to free the public key. This comment is here - * because this sematic would be non-obvious otherwise. All callers - * should include this comment. - */ -static SECItem * -lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) { - SECItem *pubItem = NULL; - /* get value to compare from the cert's public key */ - switch ( pubKey->keyType ) { - case NSSLOWKEYRSAKey: - pubItem = &pubKey->u.rsa.modulus; - break; - case NSSLOWKEYDSAKey: - pubItem = &pubKey->u.dsa.publicValue; - break; - case NSSLOWKEYDHKey: - pubItem = &pubKey->u.dh.publicValue; - break; -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - pubItem = &pubKey->u.ec.publicValue; - break; -#endif /* NSS_ENABLE_ECC */ - default: - break; - } - return pubItem; -} - -static const SEC_ASN1Template lg_SerialTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) }, - { 0 } -}; - -static CK_RV -lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_RSA; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_ENCRYPT: - case CKA_VERIFY: - case CKA_VERIFY_RECOVER: - case CKA_WRAP: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_MODULUS: - return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data, - key->u.rsa.modulus.len); - case CKA_PUBLIC_EXPONENT: - return lg_CopyAttributeSigned(attribute, type, - key->u.rsa.publicExponent.data, - key->u.rsa.publicExponent.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_DSA; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash,key->u.dsa.publicValue.data, - key->u.dsa.publicValue.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - case CKA_ENCRYPT: - case CKA_VERIFY_RECOVER: - case CKA_WRAP: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_VERIFY: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_VALUE: - return lg_CopyAttributeSigned(attribute,type, - key->u.dsa.publicValue.data, - key->u.dsa.publicValue.len); - case CKA_PRIME: - return lg_CopyAttributeSigned(attribute,type, - key->u.dsa.params.prime.data, - key->u.dsa.params.prime.len); - case CKA_SUBPRIME: - return lg_CopyAttributeSigned(attribute,type, - key->u.dsa.params.subPrime.data, - key->u.dsa.params.subPrime.len); - case CKA_BASE: - return lg_CopyAttributeSigned(attribute,type, - key->u.dsa.params.base.data, - key->u.dsa.params.base.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_DH; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_ENCRYPT: - case CKA_VERIFY: - case CKA_VERIFY_RECOVER: - case CKA_WRAP: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_VALUE: - return lg_CopyAttributeSigned(attribute,type, - key->u.dh.publicValue.data, - key->u.dh.publicValue.len); - case CKA_PRIME: - return lg_CopyAttributeSigned(attribute,type,key->u.dh.prime.data, - key->u.dh.prime.len); - case CKA_BASE: - return lg_CopyAttributeSigned(attribute,type,key->u.dh.base.data, - key->u.dh.base.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -#ifdef NSS_ENABLE_ECC -static CK_RV -lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_EC; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash, key->u.ec.publicValue.data, - key->u.ec.publicValue.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - case CKA_VERIFY: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_ENCRYPT: - case CKA_VERIFY_RECOVER: - case CKA_WRAP: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_EC_PARAMS: - return lg_CopyAttributeSigned(attribute,type, - key->u.ec.ecParams.DEREncoding.data, - key->u.ec.ecParams.DEREncoding.len); - case CKA_EC_POINT: - if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) { - return lg_CopyAttributeSigned(attribute, type, - key->u.ec.publicValue.data, - key->u.ec.publicValue.len); - } else { - SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, - &(key->u.ec.publicValue), - SEC_ASN1_GET(SEC_OctetStringTemplate)); - CK_RV crv; - if (!pubValue) { - return CKR_HOST_MEMORY; - } - crv = lg_CopyAttributeSigned(attribute, type, - pubValue->data, - pubValue->len); - SECITEM_FreeItem(pubValue, PR_TRUE); - return crv; - } - default: - break; - } - return lg_invalidAttribute(attribute); -} -#endif /* NSS_ENABLE_ECC */ - - -static CK_RV -lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - NSSLOWKEYPublicKey *key; - CK_RV crv; - char *label; - - switch (type) { - case CKA_PRIVATE: - case CKA_SENSITIVE: - case CKA_ALWAYS_SENSITIVE: - case CKA_NEVER_EXTRACTABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_MODIFIABLE: - case CKA_EXTRACTABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_SUBJECT: - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - case CKA_START_DATE: - case CKA_END_DATE: - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - case CKA_LABEL: - label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); - if (label == NULL) { - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - } - crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label)); - PORT_Free(label); - return crv; - default: - break; - } - - key = lg_GetPublicKey(obj); - if (key == NULL) { - if (type == CKA_ID) { - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - } - return CKR_OBJECT_HANDLE_INVALID; - } - - switch (key->keyType) { - case NSSLOWKEYRSAKey: - return lg_FindRSAPublicKeyAttribute(key,type,attribute); - case NSSLOWKEYDSAKey: - return lg_FindDSAPublicKeyAttribute(key,type,attribute); - case NSSLOWKEYDHKey: - return lg_FindDHPublicKeyAttribute(key,type,attribute); -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - return lg_FindECPublicKeyAttribute(key,type,attribute); -#endif /* NSS_ENABLE_ECC */ - default: - break; - } - - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - NSSLOWKEYPrivateKey *key; - char *label; - unsigned char *keyString; - CK_RV crv; - int keyTypeLen; - CK_ULONG keyLen; - CK_KEY_TYPE keyType; - PRUint32 keyTypeStorage; - - switch (type) { - case CKA_PRIVATE: - case CKA_SENSITIVE: - case CKA_ALWAYS_SENSITIVE: - case CKA_EXTRACTABLE: - case CKA_DERIVE: - case CKA_ENCRYPT: - case CKA_DECRYPT: - case CKA_SIGN: - case CKA_VERIFY: - case CKA_WRAP: - case CKA_UNWRAP: - case CKA_MODIFIABLE: - case CKA_LOCAL: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_NEVER_EXTRACTABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_START_DATE: - case CKA_END_DATE: - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - case CKA_LABEL: - label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); - if (label == NULL) { - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - } - crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label)); - PORT_Free(label); - return crv; - case CKA_ID: - return lg_CopyAttribute(attribute,type,obj->dbKey.data, - obj->dbKey.len); - case CKA_KEY_TYPE: - case CKA_VALUE_LEN: - case CKA_VALUE: - break; - default: - return lg_invalidAttribute(attribute); - } - - key = lg_GetPrivateKey(obj); - if (key == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - switch (type) { - case CKA_KEY_TYPE: - /* handle legacy databases. In legacy databases key_type was stored - * in host order, with any leading zeros stripped off. Only key types - * under 0x1f (AES) were stored. We assume that any values which are - * either 1 byte long (big endian), or have byte[0] between 0 and - * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other - * values are assumed to be from the new database, which is always 4 - * bytes in network order */ - keyType=0; - keyString = key->u.rsa.coefficient.data; - keyTypeLen = key->u.rsa.coefficient.len; - - - /* - * Because of various endian and word lengths The database may have - * stored the keyType value in one of the following formats: - * (kt) <= 0x1f - * length data - * Big Endian, pre-3.9, all lengths: 1 (kt) - * Little Endian, pre-3.9, 32 bits: 4 (kt) 0 0 0 - * Little Endian, pre-3.9, 64 bits: 8 (kt) 0 0 0 0 0 0 0 - * All platforms, 3.9, 32 bits: 4 0 0 0 (kt) - * Big Endian, 3.9, 64 bits: 8 0 0 0 (kt) 0 0 0 0 - * Little Endian, 3.9, 64 bits: 8 0 0 0 0 0 0 0 (kt) - * All platforms, >= 3.9.1, all lengths: 4 (a) k1 k2 k3 - * where (a) is 0 or >= 0x80. currently (a) can only be 0. - */ - /* - * this key was written on a 64 bit platform with a using NSS 3.9 - * or earlier. Reduce the 64 bit possibilities above. When we are - * through, we will only have: - * - * Big Endian, pre-3.9, all lengths: 1 (kt) - * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 - * All platforms, 3.9, all lengths: 4 0 0 0 (kt) - * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3 - */ - if (keyTypeLen == 8) { - keyTypeStorage = *(PRUint32 *) keyString; - if (keyTypeStorage == 0) { - keyString += sizeof(PRUint32); - } - keyTypeLen = 4; - } - /* - * Now Handle: - * - * All platforms, 3.9, all lengths: 4 0 0 0 (kt) - * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3 - * - * NOTE: if kt == 0 or ak1k2k3 == 0, the test fails and - * we handle it as: - * - * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 - */ - if (keyTypeLen == sizeof(keyTypeStorage) && - (((keyString[0] & 0x80) == 0x80) || - !((keyString[1] == 0) && (keyString[2] == 0) - && (keyString[3] == 0))) ) { - PORT_Memcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage)); - keyType = (CK_KEY_TYPE) PR_ntohl(keyTypeStorage); - } else { - /* - * Now Handle: - * - * Big Endian, pre-3.9, all lengths: 1 (kt) - * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 - * -- KeyType == 0 all other cases ---: 4 0 0 0 0 - */ - keyType = (CK_KEY_TYPE) keyString[0] ; - } - return lg_ULongAttribute(attribute, type, keyType); - case CKA_VALUE: - return lg_CopyPrivAttribute(attribute,type,key->u.rsa.privateExponent.data, - key->u.rsa.privateExponent.len, obj->sdb); - case CKA_VALUE_LEN: - keyLen=key->u.rsa.privateExponent.len; - return lg_ULongAttribute(attribute,type, keyLen); - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute, SDB *sdbpw) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_RSA; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_DECRYPT: - case CKA_SIGN: - case CKA_SIGN_RECOVER: - case CKA_UNWRAP: - return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr); - case CKA_MODULUS: - return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data, - key->u.rsa.modulus.len); - case CKA_PUBLIC_EXPONENT: - return lg_CopyAttributeSigned(attribute, type, - key->u.rsa.publicExponent.data, - key->u.rsa.publicExponent.len); - case CKA_PRIVATE_EXPONENT: - return lg_CopyPrivAttrSigned(attribute,type, - key->u.rsa.privateExponent.data, - key->u.rsa.privateExponent.len, sdbpw); - case CKA_PRIME_1: - return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime1.data, - key->u.rsa.prime1.len, sdbpw); - case CKA_PRIME_2: - return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime2.data, - key->u.rsa.prime2.len, sdbpw); - case CKA_EXPONENT_1: - return lg_CopyPrivAttrSigned(attribute, type, - key->u.rsa.exponent1.data, - key->u.rsa.exponent1.len, sdbpw); - case CKA_EXPONENT_2: - return lg_CopyPrivAttrSigned(attribute, type, - key->u.rsa.exponent2.data, - key->u.rsa.exponent2.len, sdbpw); - case CKA_COEFFICIENT: - return lg_CopyPrivAttrSigned(attribute, type, - key->u.rsa.coefficient.data, - key->u.rsa.coefficient.len, sdbpw); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute, SDB *sdbpw) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_DSA; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash,key->u.dsa.publicValue.data, - key->u.dsa.publicValue.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - case CKA_DECRYPT: - case CKA_SIGN_RECOVER: - case CKA_UNWRAP: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_SIGN: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_VALUE: - return lg_CopyPrivAttrSigned(attribute, type, - key->u.dsa.privateValue.data, - key->u.dsa.privateValue.len, sdbpw); - case CKA_PRIME: - return lg_CopyAttributeSigned(attribute, type, - key->u.dsa.params.prime.data, - key->u.dsa.params.prime.len); - case CKA_SUBPRIME: - return lg_CopyAttributeSigned(attribute, type, - key->u.dsa.params.subPrime.data, - key->u.dsa.params.subPrime.len); - case CKA_BASE: - return lg_CopyAttributeSigned(attribute, type, - key->u.dsa.params.base.data, - key->u.dsa.params.base.len); - case CKA_NETSCAPE_DB: - return lg_CopyAttributeSigned(attribute, type, - key->u.dsa.publicValue.data, - key->u.dsa.publicValue.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute, SDB *sdbpw) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_DH; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_DECRYPT: - case CKA_SIGN: - case CKA_SIGN_RECOVER: - case CKA_UNWRAP: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_VALUE: - return lg_CopyPrivAttrSigned(attribute, type, - key->u.dh.privateValue.data, - key->u.dh.privateValue.len, sdbpw); - case CKA_PRIME: - return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data, - key->u.dh.prime.len); - case CKA_BASE: - return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data, - key->u.dh.base.len); - case CKA_NETSCAPE_DB: - return lg_CopyAttributeSigned(attribute, type, - key->u.dh.publicValue.data, - key->u.dh.publicValue.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -#ifdef NSS_ENABLE_ECC -static CK_RV -lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute, SDB *sdbpw) -{ - unsigned char hash[SHA1_LENGTH]; - CK_KEY_TYPE keyType = CKK_EC; - - switch (type) { - case CKA_KEY_TYPE: - return lg_ULongAttribute(attribute, type, keyType); - case CKA_ID: - SHA1_HashBuf(hash,key->u.ec.publicValue.data,key->u.ec.publicValue.len); - return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); - case CKA_DERIVE: - case CKA_SIGN: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_DECRYPT: - case CKA_SIGN_RECOVER: - case CKA_UNWRAP: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_VALUE: - return lg_CopyPrivAttrSigned(attribute, type, - key->u.ec.privateValue.data, - key->u.ec.privateValue.len, sdbpw); - case CKA_EC_PARAMS: - return lg_CopyAttributeSigned(attribute, type, - key->u.ec.ecParams.DEREncoding.data, - key->u.ec.ecParams.DEREncoding.len); - case CKA_NETSCAPE_DB: - return lg_CopyAttributeSigned(attribute, type, - key->u.ec.publicValue.data, - key->u.ec.publicValue.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} -#endif /* NSS_ENABLE_ECC */ - -static CK_RV -lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - NSSLOWKEYPrivateKey *key; - char *label; - CK_RV crv; - - switch (type) { - case CKA_PRIVATE: - case CKA_SENSITIVE: - case CKA_ALWAYS_SENSITIVE: - case CKA_EXTRACTABLE: - case CKA_MODIFIABLE: - case CKA_LOCAL: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_NEVER_EXTRACTABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_SUBJECT: - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - case CKA_START_DATE: - case CKA_END_DATE: - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - case CKA_LABEL: - label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); - if (label == NULL) { - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - } - crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label)); - PORT_Free(label); - return crv; - default: - break; - } - key = lg_GetPrivateKey(obj); - if (key == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - switch (key->keyType) { - case NSSLOWKEYRSAKey: - return lg_FindRSAPrivateKeyAttribute(key,type,attribute,obj->sdb); - case NSSLOWKEYDSAKey: - return lg_FindDSAPrivateKeyAttribute(key,type,attribute,obj->sdb); - case NSSLOWKEYDHKey: - return lg_FindDHPrivateKeyAttribute(key,type,attribute,obj->sdb); -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - return lg_FindECPrivateKeyAttribute(key,type,attribute,obj->sdb); -#endif /* NSS_ENABLE_ECC */ - default: - break; - } - - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - certDBEntrySMime *entry; - switch (type) { - case CKA_PRIVATE: - case CKA_MODIFIABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_NETSCAPE_EMAIL: - return lg_CopyAttribute(attribute,type,obj->dbKey.data, - obj->dbKey.len-1); - case CKA_NETSCAPE_SMIME_TIMESTAMP: - case CKA_SUBJECT: - case CKA_VALUE: - break; - default: - return lg_invalidAttribute(attribute); - } - entry = lg_getSMime(obj); - if (entry == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - switch (type) { - case CKA_NETSCAPE_SMIME_TIMESTAMP: - return lg_CopyAttribute(attribute,type,entry->optionsDate.data, - entry->optionsDate.len); - case CKA_SUBJECT: - return lg_CopyAttribute(attribute,type,entry->subjectName.data, - entry->subjectName.len); - case CKA_VALUE: - return lg_CopyAttribute(attribute,type,entry->smimeOptions.data, - entry->smimeOptions.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - NSSLOWCERTTrust *trust; - NSSLOWCERTCertDBHandle *certHandle; - NSSLOWCERTCertificate *cert; - unsigned char hash[SHA1_LENGTH]; - unsigned int trustFlags; - CK_RV crv; - - switch (type) { - case CKA_PRIVATE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_MODIFIABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_CERT_SHA1_HASH: - case CKA_CERT_MD5_HASH: - case CKA_TRUST_CLIENT_AUTH: - case CKA_TRUST_SERVER_AUTH: - case CKA_TRUST_EMAIL_PROTECTION: - case CKA_TRUST_CODE_SIGNING: - case CKA_TRUST_STEP_UP_APPROVED: - case CKA_ISSUER: - case CKA_SERIAL_NUMBER: - break; - default: - return lg_invalidAttribute(attribute); - } - certHandle = lg_getCertDB(obj->sdb); - if (!certHandle) { - return CKR_OBJECT_HANDLE_INVALID; - } - trust = lg_getTrust(obj, certHandle); - if (trust == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - switch (type) { - case CKA_CERT_SHA1_HASH: - SHA1_HashBuf(hash,trust->derCert->data,trust->derCert->len); - return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH); - case CKA_CERT_MD5_HASH: - MD5_HashBuf(hash,trust->derCert->data,trust->derCert->len); - return lg_CopyAttribute(attribute, type, hash, MD5_LENGTH); - case CKA_TRUST_CLIENT_AUTH: - trustFlags = trust->trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ? - trust->trust->sslFlags | CERTDB_TRUSTED_CA : 0 ; - goto trust; - case CKA_TRUST_SERVER_AUTH: - trustFlags = trust->trust->sslFlags; - goto trust; - case CKA_TRUST_EMAIL_PROTECTION: - trustFlags = trust->trust->emailFlags; - goto trust; - case CKA_TRUST_CODE_SIGNING: - trustFlags = trust->trust->objectSigningFlags; -trust: - if (trustFlags & CERTDB_TRUSTED_CA ) { - return lg_ULongAttribute(attribute, type, - CKT_NETSCAPE_TRUSTED_DELEGATOR); - } - if (trustFlags & CERTDB_TRUSTED) { - return lg_ULongAttribute(attribute, type, CKT_NETSCAPE_TRUSTED); - } - if (trustFlags & CERTDB_NOT_TRUSTED) { - return lg_ULongAttribute(attribute, type, CKT_NETSCAPE_UNTRUSTED); - } - if (trustFlags & CERTDB_TRUSTED_UNKNOWN) { - return lg_ULongAttribute(attribute, type, - CKT_NETSCAPE_TRUST_UNKNOWN); - } - if (trustFlags & CERTDB_VALID_CA) { - return lg_ULongAttribute(attribute, type, - CKT_NETSCAPE_VALID_DELEGATOR); - } - if (trustFlags & CERTDB_VALID_PEER) { - return lg_ULongAttribute(attribute, type, CKT_NETSCAPE_VALID); - } - return lg_ULongAttribute(attribute, type, CKT_NETSCAPE_MUST_VERIFY); - case CKA_TRUST_STEP_UP_APPROVED: - if (trust->trust->sslFlags & CERTDB_GOVT_APPROVED_CA) { - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - } else { - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - } - default: - break; - } - - - switch (type) { - case CKA_ISSUER: - cert = lg_getCert(obj, certHandle); - if (cert == NULL) break; - crv = lg_CopyAttribute(attribute,type,cert->derIssuer.data, - cert->derIssuer.len); - break; - case CKA_SERIAL_NUMBER: - cert = lg_getCert(obj, certHandle); - if (cert == NULL) break; - crv = lg_CopyAttribute(attribute,type,cert->derSN.data, - cert->derSN.len); - break; - default: - cert = NULL; - break; - } - if (cert) { - nsslowcert_DestroyCertificate(cert); - return crv; - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - certDBEntryRevocation *crl; - - switch (type) { - case CKA_PRIVATE: - case CKA_MODIFIABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_NETSCAPE_KRL: - return ((obj->handle == LG_TOKEN_KRL_HANDLE) - ? LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr) - : LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr)); - case CKA_SUBJECT: - return lg_CopyAttribute(attribute,type,obj->dbKey.data, - obj->dbKey.len); - case CKA_NETSCAPE_URL: - case CKA_VALUE: - break; - default: - return lg_invalidAttribute(attribute); - } - crl = lg_getCrl(obj); - if (!crl) { - return CKR_OBJECT_HANDLE_INVALID; - } - switch (type) { - case CKA_NETSCAPE_URL: - if (crl->url == NULL) { - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - } - return lg_CopyAttribute(attribute, type, crl->url, - PORT_Strlen(crl->url)+1); - case CKA_VALUE: - return lg_CopyAttribute(attribute, type, crl->derCrl.data, - crl->derCrl.len); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -static CK_RV -lg_FindCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *attribute) -{ - NSSLOWCERTCertificate *cert; - NSSLOWCERTCertDBHandle *certHandle; - NSSLOWKEYPublicKey *pubKey; - unsigned char hash[SHA1_LENGTH]; - SECItem *item; - - switch (type) { - case CKA_PRIVATE: - return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); - case CKA_MODIFIABLE: - return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); - case CKA_CERTIFICATE_TYPE: - /* hardcoding X.509 into here */ - return lg_ULongAttribute(attribute, type, CKC_X_509); - case CKA_VALUE: - case CKA_ID: - case CKA_LABEL: - case CKA_SUBJECT: - case CKA_ISSUER: - case CKA_SERIAL_NUMBER: - case CKA_NETSCAPE_EMAIL: - break; - default: - return lg_invalidAttribute(attribute); - } - - certHandle = lg_getCertDB(obj->sdb); - if (certHandle == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - - cert = lg_getCert(obj, certHandle); - if (cert == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - switch (type) { - case CKA_VALUE: - return lg_CopyAttribute(attribute,type,cert->derCert.data, - cert->derCert.len); - case CKA_ID: - if (((cert->trust->sslFlags & CERTDB_USER) == 0) && - ((cert->trust->emailFlags & CERTDB_USER) == 0) && - ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) { - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - } - pubKey = nsslowcert_ExtractPublicKey(cert); - if (pubKey == NULL) break; - item = lg_GetPubItem(pubKey); - if (item == NULL) { - nsslowkey_DestroyPublicKey(pubKey); - break; - } - SHA1_HashBuf(hash,item->data,item->len); - /* item is imbedded in pubKey, just free the key */ - nsslowkey_DestroyPublicKey(pubKey); - return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH); - case CKA_LABEL: - return cert->nickname - ? lg_CopyAttribute(attribute, type, cert->nickname, - PORT_Strlen(cert->nickname)) - : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - case CKA_SUBJECT: - return lg_CopyAttribute(attribute,type,cert->derSubject.data, - cert->derSubject.len); - case CKA_ISSUER: - return lg_CopyAttribute(attribute,type,cert->derIssuer.data, - cert->derIssuer.len); - case CKA_SERIAL_NUMBER: - return lg_CopyAttribute(attribute,type,cert->derSN.data, - cert->derSN.len); - case CKA_NETSCAPE_EMAIL: - return (cert->emailAddr && cert->emailAddr[0]) - ? lg_CopyAttribute(attribute, type, cert->emailAddr, - PORT_Strlen(cert->emailAddr)) - : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -CK_RV -lg_GetSingleAttribute(LGObjectCache *obj, CK_ATTRIBUTE *attribute) -{ - /* handle the common ones */ - CK_ATTRIBUTE_TYPE type = attribute->type; - switch (type) { - case CKA_CLASS: - return lg_ULongAttribute(attribute,type,obj->objclass); - case CKA_TOKEN: - return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr); - case CKA_LABEL: - if ( (obj->objclass == CKO_CERTIFICATE) - || (obj->objclass == CKO_PRIVATE_KEY) - || (obj->objclass == CKO_PUBLIC_KEY) - || (obj->objclass == CKO_SECRET_KEY)) { - break; - } - return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); - default: - break; - } - switch (obj->objclass) { - case CKO_CERTIFICATE: - return lg_FindCertAttribute(obj,type,attribute); - case CKO_NETSCAPE_CRL: - return lg_FindCrlAttribute(obj,type,attribute); - case CKO_NETSCAPE_TRUST: - return lg_FindTrustAttribute(obj,type,attribute); - case CKO_NETSCAPE_SMIME: - return lg_FindSMIMEAttribute(obj,type,attribute); - case CKO_PUBLIC_KEY: - return lg_FindPublicKeyAttribute(obj,type,attribute); - case CKO_PRIVATE_KEY: - return lg_FindPrivateKeyAttribute(obj,type,attribute); - case CKO_SECRET_KEY: - return lg_FindSecretKeyAttribute(obj,type,attribute); - default: - break; - } - return lg_invalidAttribute(attribute); -} - -/* - * Fill in the attribute template based on the data in the database. - */ -CK_RV -lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *templ, - CK_ULONG count) -{ - LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK); - CK_RV crv, crvCollect = CKR_OK; - int i; - - if (obj == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - - for (i=0; i < count; i++) { - crv = lg_GetSingleAttribute(obj, &templ[i]); - if (crvCollect == CKR_OK) crvCollect = crv; - } - - lg_DestroyObjectCache(obj); - return crvCollect; -} - -PRBool -lg_cmpAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attribute) -{ - unsigned char buf[LG_BUF_SPACE]; - CK_ATTRIBUTE testAttr; - unsigned char *tempBuf = NULL; - PRBool match = PR_TRUE; - CK_RV crv; - - /* we're going to compare 'attribute' with the actual attribute from - * the object. We'll use the length of 'attribute' to decide how much - * space we need to read the test attribute. If 'attribute' doesn't give - * enough space, then we know the values don't match and that will - * show up as ckr != CKR_OK */ - testAttr = *attribute; - testAttr.pValue = buf; - - /* if we don't have enough space, malloc it */ - if (attribute->ulValueLen > LG_BUF_SPACE) { - tempBuf = PORT_Alloc(attribute->ulValueLen); - if (!tempBuf) { - return PR_FALSE; - } - testAttr.pValue = tempBuf; - } - - /* get the attribute */ - crv = lg_GetSingleAttribute(obj, &testAttr); - /* if the attribute was read OK, compare it */ - if ((crv != CKR_OK) || (attribute->ulValueLen != testAttr.ulValueLen) || - (PORT_Memcmp(attribute->pValue,testAttr.pValue,testAttr.ulValueLen)!= 0)){ - /* something didn't match, this isn't the object we are looking for */ - match = PR_FALSE; - } - /* free the buffer we may have allocated */ - if (tempBuf) { - PORT_Free(tempBuf); - } - return match; -} - -PRBool -lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class, - const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - PRBool match = PR_TRUE; - LGObjectCache *obj = lg_NewObjectCache(sdb, dbKey, class); - int i; - - if (obj == NULL) { - return PR_FALSE; - } - - for (i=0; i < count; i++) { - match = lg_cmpAttribute(obj, &templ[i]); - if (!match) { - break; - } - } - - /* done looking, free up our cache */ - lg_DestroyObjectCache(obj); - - /* if we get through the whole list without finding a mismatched attribute, - * then this object fits the criteria we are matching */ - return match; -} - -static CK_RV -lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - const void *value, unsigned int len) -{ - NSSLOWCERTCertificate *cert; - NSSLOWCERTCertDBHandle *certHandle; - char *nickname = NULL; - SECStatus rv; - CK_RV crv; - - /* we can't change the EMAIL values, but let the - * upper layers feel better about the fact we tried to set these */ - if (type == CKA_NETSCAPE_EMAIL) { - return CKR_OK; - } - - certHandle = lg_getCertDB(obj->sdb); - if (certHandle == NULL) { - crv = CKR_TOKEN_WRITE_PROTECTED; - goto done; - } - - if ((type != CKA_LABEL) && (type != CKA_ID)) { - crv = CKR_ATTRIBUTE_READ_ONLY; - goto done; - } - - cert = lg_getCert(obj, certHandle); - if (cert == NULL) { - crv = CKR_OBJECT_HANDLE_INVALID; - goto done; - } - - /* if the app is trying to set CKA_ID, it's probably because it just - * imported the key. Look to see if we need to set the CERTDB_USER bits. - */ - if (type == CKA_ID) { - if (((cert->trust->sslFlags & CERTDB_USER) == 0) && - ((cert->trust->emailFlags & CERTDB_USER) == 0) && - ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) { - NSSLOWKEYDBHandle *keyHandle; - - keyHandle = lg_getKeyDB(obj->sdb); - if (keyHandle) { - if (nsslowkey_KeyForCertExists(keyHandle, cert)) { - NSSLOWCERTCertTrust trust = *cert->trust; - trust.sslFlags |= CERTDB_USER; - trust.emailFlags |= CERTDB_USER; - trust.objectSigningFlags |= CERTDB_USER; - nsslowcert_ChangeCertTrust(certHandle,cert,&trust); - } - } - } - crv = CKR_OK; - goto done; - } - - /* must be CKA_LABEL */ - if (value != NULL) { - nickname = PORT_ZAlloc(len+1); - if (nickname == NULL) { - crv = CKR_HOST_MEMORY; - goto done; - } - PORT_Memcpy(nickname,value,len); - nickname[len] = 0; - } - rv = nsslowcert_AddPermNickname(certHandle, cert, nickname); - crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; - -done: - if (nickname) { - PORT_Free(nickname); - } - return crv; -} - -static CK_RV -lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - const void *value, unsigned int len, - PRBool *writePrivate) -{ - NSSLOWKEYPrivateKey *privKey; - NSSLOWKEYDBHandle *keyHandle; - char *nickname = NULL; - SECStatus rv; - CK_RV crv; - - /* we can't change the ID and we don't store the subject, but let the - * upper layers feel better about the fact we tried to set these */ - if ((type == CKA_ID) || (type == CKA_SUBJECT) || - (type == CKA_LOCAL) || (type == CKA_NEVER_EXTRACTABLE) || - (type == CKA_ALWAYS_SENSITIVE)) { - return CKR_OK; - } - - keyHandle = lg_getKeyDB(obj->sdb); - if (keyHandle == NULL) { - crv = CKR_TOKEN_WRITE_PROTECTED; - goto done; - } - - privKey = lg_GetPrivateKeyWithDB(obj, keyHandle); - if (privKey == NULL) { - crv = CKR_OBJECT_HANDLE_INVALID; - goto done; - } - - crv = CKR_ATTRIBUTE_READ_ONLY; - switch(type) { - case CKA_LABEL: - if (value != NULL) { - nickname = PORT_ZAlloc(len+1); - if (nickname == NULL) { - crv = CKR_HOST_MEMORY; - goto done; - } - PORT_Memcpy(nickname,value,len); - nickname[len] = 0; - } - rv = nsslowkey_UpdateNickname(keyHandle, privKey, &obj->dbKey, - nickname, obj->sdb); - crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; - break; - case CKA_UNWRAP: - case CKA_SIGN: - case CKA_DERIVE: - case CKA_SIGN_RECOVER: - case CKA_DECRYPT: - /* ignore attempts to change restrict these. - * legacyDB ignore these flags and always presents all of them - * that are valid as true. - * NOTE: We only get here if the current value and the new value do - * not match. */ - if (*(char *)value == 0) { - crv = CKR_OK; - } - break; - case CKA_VALUE: - case CKA_PRIVATE_EXPONENT: - case CKA_PRIME_1: - case CKA_PRIME_2: - case CKA_EXPONENT_1: - case CKA_EXPONENT_2: - case CKA_COEFFICIENT: - /* We aren't really changing these values, we are just triggering - * the database to update it's entry */ - *writePrivate = PR_TRUE; - crv = CKR_OK; - break; - default: - crv = CKR_ATTRIBUTE_READ_ONLY; - break; - } -done: - if (nickname) { - PORT_Free(nickname); - } - return crv; -} - -static CK_RV -lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, - const void *value, unsigned int len, - PRBool *writePrivate) -{ - /* we can't change the ID and we don't store the subject, but let the - * upper layers feel better about the fact we tried to set these */ - if ((type == CKA_ID) || (type == CKA_SUBJECT) || (type == CKA_LABEL)) { - return CKR_OK; - } - return CKR_ATTRIBUTE_READ_ONLY; -} - -static CK_RV -lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr) -{ - unsigned int flags; - CK_TRUST trust; - NSSLOWCERTCertificate *cert; - NSSLOWCERTCertDBHandle *certHandle; - NSSLOWCERTCertTrust dbTrust; - SECStatus rv; - CK_RV crv; - - if (attr->type == CKA_LABEL) { - return CKR_OK; - } - - crv = lg_GetULongAttribute(attr->type, attr, 1, &trust); - if (crv != CKR_OK) { - return crv; - } - flags = lg_MapTrust(trust, (PRBool) (attr->type == CKA_TRUST_CLIENT_AUTH)); - - certHandle = lg_getCertDB(obj->sdb); - - if (certHandle == NULL) { - crv = CKR_TOKEN_WRITE_PROTECTED; - goto done; - } - - cert = lg_getCert(obj, certHandle); - if (cert == NULL) { - crv = CKR_OBJECT_HANDLE_INVALID; - goto done; - } - dbTrust = *cert->trust; - - switch (attr->type) { - case CKA_TRUST_EMAIL_PROTECTION: - dbTrust.emailFlags = flags | - (cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS); - break; - case CKA_TRUST_CODE_SIGNING: - dbTrust.objectSigningFlags = flags | - (cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS); - break; - case CKA_TRUST_CLIENT_AUTH: - dbTrust.sslFlags = flags | (cert->trust->sslFlags & - (CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CA)); - break; - case CKA_TRUST_SERVER_AUTH: - dbTrust.sslFlags = flags | (cert->trust->sslFlags & - (CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CLIENT_CA)); - break; - default: - crv = CKR_ATTRIBUTE_READ_ONLY; - goto done; - } - - rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust); - crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; -done: - return crv; -} - -static CK_RV -lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr, - PRBool *writePrivate) -{ - CK_ATTRIBUTE attribLocal; - CK_RV crv; - - if ((attr->type == CKA_NETSCAPE_DB) && (obj->objclass == CKO_PRIVATE_KEY)) { - *writePrivate = PR_TRUE; - return CKR_OK; - } - - /* Make sure the attribute exists first */ - attribLocal.type = attr->type; - attribLocal.pValue = NULL; - attribLocal.ulValueLen = 0; - crv = lg_GetSingleAttribute(obj, &attribLocal); - if (crv != CKR_OK) { - return crv; - } - - /* if we are just setting it to the value we already have, - * allow it to happen. Let label setting go through so - * we have the opportunity to repair any database corruption. */ - if (attr->type != CKA_LABEL) { - if (lg_cmpAttribute(obj,attr)) { - return CKR_OK; - } - } - - crv = CKR_ATTRIBUTE_READ_ONLY; - switch (obj->objclass) { - case CKO_CERTIFICATE: - /* change NICKNAME, EMAIL, */ - crv = lg_SetCertAttribute(obj,attr->type, - attr->pValue,attr->ulValueLen); - break; - case CKO_NETSCAPE_CRL: - /* change URL */ - break; - case CKO_NETSCAPE_TRUST: - crv = lg_SetTrustAttribute(obj,attr); - break; - case CKO_PRIVATE_KEY: - case CKO_SECRET_KEY: - crv = lg_SetPrivateKeyAttribute(obj,attr->type, - attr->pValue,attr->ulValueLen, writePrivate); - break; - case CKO_PUBLIC_KEY: - crv = lg_SetPublicKeyAttribute(obj,attr->type, - attr->pValue,attr->ulValueLen, writePrivate); - break; - } - return crv; -} - -/* - * Fill in the attribute template based on the data in the database. - */ -CK_RV -lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, - const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK); - CK_RV crv, crvCollect = CKR_OK; - PRBool writePrivate = PR_FALSE; - int i; - - if (obj == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - - for (i=0; i < count; i++) { - crv = lg_SetSingleAttribute(obj, &templ[i], &writePrivate); - if (crvCollect == CKR_OK) crvCollect = crv; - } - - /* Write any collected changes out for private and secret keys. - * don't do the write for just the label */ - if (writePrivate) { - NSSLOWKEYPrivateKey *privKey = lg_GetPrivateKey(obj); - SECStatus rv = SECFailure; - char * label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); - - if (privKey) { - rv = nsslowkey_StoreKeyByPublicKeyAlg(lg_getKeyDB(sdb), privKey, - &obj->dbKey, label, sdb, PR_TRUE ); - } - if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - } - } - - lg_DestroyObjectCache(obj); - return crvCollect; -} diff --git a/security/nss/lib/softoken/legacydb/lgcreate.c b/security/nss/lib/softoken/legacydb/lgcreate.c deleted file mode 100644 index ab6c652f7..000000000 --- a/security/nss/lib/softoken/legacydb/lgcreate.c +++ /dev/null @@ -1,1011 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "secitem.h" -#include "pkcs11.h" -#include "lgdb.h" -#include "pcert.h" -#include "lowkeyi.h" -#include "blapi.h" -#include "secder.h" -#include "secasn1.h" - -#include "keydbi.h" - -/* - * ******************** Object Creation Utilities *************************** - */ - -/* - * check the consistancy and initialize a Certificate Object - */ -static CK_RV -lg_createCertObject(SDB *sdb, CK_OBJECT_HANDLE *handle, - const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - SECItem derCert; - NSSLOWCERTCertificate *cert; - NSSLOWCERTCertTrust *trust = NULL; - NSSLOWCERTCertTrust userTrust = - { CERTDB_USER, CERTDB_USER, CERTDB_USER }; - NSSLOWCERTCertTrust defTrust = - { CERTDB_TRUSTED_UNKNOWN, - CERTDB_TRUSTED_UNKNOWN, CERTDB_TRUSTED_UNKNOWN }; - char *label = NULL; - char *email = NULL; - SECStatus rv; - CK_RV crv; - PRBool inDB = PR_TRUE; - NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb); - NSSLOWKEYDBHandle *keyHandle = NULL; - CK_CERTIFICATE_TYPE type; - const CK_ATTRIBUTE *attribute; - - /* we can't store any certs private */ - if (lg_isTrue(CKA_PRIVATE, templ, count)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* We only support X.509 Certs for now */ - crv = lg_GetULongAttribute(CKA_CERTIFICATE_TYPE, templ, count, &type); - if (crv != CKR_OK) { - return crv; - } - - if (type != CKC_X_509) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* X.509 Certificate */ - - - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - /* get the der cert */ - attribute = lg_FindAttribute(CKA_VALUE, templ, count); - if (!attribute) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - derCert.type = 0; - derCert.data = (unsigned char *)attribute->pValue; - derCert.len = attribute->ulValueLen ; - - label = lg_getString(CKA_LABEL, templ, count); - - cert = nsslowcert_FindCertByDERCert(certHandle, &derCert); - if (cert == NULL) { - cert = nsslowcert_DecodeDERCertificate(&derCert, label); - inDB = PR_FALSE; - } - if (cert == NULL) { - if (label) PORT_Free(label); - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - keyHandle = lg_getKeyDB(sdb); - if (keyHandle) { - if (nsslowkey_KeyForCertExists(keyHandle,cert)) { - trust = &userTrust; - } - } - - if (!inDB) { - if (!trust) trust = &defTrust; - rv = nsslowcert_AddPermCert(certHandle, cert, label, trust); - } else { - rv = trust ? nsslowcert_ChangeCertTrust(certHandle,cert,trust) : - SECSuccess; - } - - if (label) PORT_Free(label); - - if (rv != SECSuccess) { - nsslowcert_DestroyCertificate(cert); - return CKR_DEVICE_ERROR; - } - - /* - * Add a NULL S/MIME profile if necessary. - */ - email = lg_getString(CKA_NETSCAPE_EMAIL, templ, count); - if (email) { - certDBEntrySMime *entry; - - entry = nsslowcert_ReadDBSMimeEntry(certHandle,email); - if (!entry) { - nsslowcert_SaveSMimeProfile(certHandle, email, - &cert->derSubject, NULL, NULL); - } else { - nsslowcert_DestroyDBEntry((certDBEntry *)entry); - } - PORT_Free(email); - } - *handle=lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_CERT); - nsslowcert_DestroyCertificate(cert); - - return CKR_OK; -} - -unsigned int -lg_MapTrust(CK_TRUST trust, PRBool clientAuth) -{ - unsigned int trustCA = clientAuth ? CERTDB_TRUSTED_CLIENT_CA : - CERTDB_TRUSTED_CA; - switch (trust) { - case CKT_NETSCAPE_TRUSTED: - return CERTDB_VALID_PEER|CERTDB_TRUSTED; - case CKT_NETSCAPE_TRUSTED_DELEGATOR: - return CERTDB_VALID_CA|trustCA; - case CKT_NETSCAPE_UNTRUSTED: - return CERTDB_NOT_TRUSTED; - case CKT_NETSCAPE_MUST_VERIFY: - return 0; - case CKT_NETSCAPE_VALID: /* implies must verify */ - return CERTDB_VALID_PEER; - case CKT_NETSCAPE_VALID_DELEGATOR: /* implies must verify */ - return CERTDB_VALID_CA; - default: - break; - } - return CERTDB_TRUSTED_UNKNOWN; -} - - -/* - * check the consistancy and initialize a Trust Object - */ -static CK_RV -lg_createTrustObject(SDB *sdb, CK_OBJECT_HANDLE *handle, - const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - const CK_ATTRIBUTE *issuer = NULL; - const CK_ATTRIBUTE *serial = NULL; - NSSLOWCERTCertificate *cert = NULL; - const CK_ATTRIBUTE *trust; - CK_TRUST sslTrust = CKT_NETSCAPE_TRUST_UNKNOWN; - CK_TRUST clientTrust = CKT_NETSCAPE_TRUST_UNKNOWN; - CK_TRUST emailTrust = CKT_NETSCAPE_TRUST_UNKNOWN; - CK_TRUST signTrust = CKT_NETSCAPE_TRUST_UNKNOWN; - CK_BBOOL stepUp; - NSSLOWCERTCertTrust dbTrust = { 0 }; - SECStatus rv; - NSSLOWCERTCertDBHandle *certHandle = lg_getCertDB(sdb); - NSSLOWCERTIssuerAndSN issuerSN; - - /* we can't store any certs private */ - if (lg_isTrue(CKA_PRIVATE, templ, count)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - issuer = lg_FindAttribute(CKA_ISSUER, templ, count); - serial = lg_FindAttribute(CKA_SERIAL_NUMBER, templ, count); - - if (issuer && serial) { - issuerSN.derIssuer.data = (unsigned char *)issuer->pValue; - issuerSN.derIssuer.len = issuer->ulValueLen ; - - issuerSN.serialNumber.data = (unsigned char *)serial->pValue; - issuerSN.serialNumber.len = serial->ulValueLen ; - - cert = nsslowcert_FindCertByIssuerAndSN(certHandle,&issuerSN); - } - - if (cert == NULL) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - lg_GetULongAttribute(CKA_TRUST_SERVER_AUTH, templ, count, &sslTrust); - lg_GetULongAttribute(CKA_TRUST_CLIENT_AUTH, templ, count, &clientTrust); - lg_GetULongAttribute(CKA_TRUST_EMAIL_PROTECTION, templ, count, &emailTrust); - lg_GetULongAttribute(CKA_TRUST_CODE_SIGNING, templ, count, &signTrust); - stepUp = CK_FALSE; - trust = lg_FindAttribute(CKA_TRUST_STEP_UP_APPROVED, templ, count); - if (trust) { - if (trust->ulValueLen == sizeof(CK_BBOOL)) { - stepUp = *(CK_BBOOL*)trust->pValue; - } - } - - /* preserve certain old fields */ - if (cert->trust) { - dbTrust.sslFlags = cert->trust->sslFlags & CERTDB_PRESERVE_TRUST_BITS; - dbTrust.emailFlags= - cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS; - dbTrust.objectSigningFlags = - cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS; - } - - dbTrust.sslFlags |= lg_MapTrust(sslTrust,PR_FALSE); - dbTrust.sslFlags |= lg_MapTrust(clientTrust,PR_TRUE); - dbTrust.emailFlags |= lg_MapTrust(emailTrust,PR_FALSE); - dbTrust.objectSigningFlags |= lg_MapTrust(signTrust,PR_FALSE); - if (stepUp) { - dbTrust.sslFlags |= CERTDB_GOVT_APPROVED_CA; - } - - rv = nsslowcert_ChangeCertTrust(certHandle,cert,&dbTrust); - *handle=lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_TRUST); - nsslowcert_DestroyCertificate(cert); - if (rv != SECSuccess) { - return CKR_DEVICE_ERROR; - } - - return CKR_OK; -} - -/* - * check the consistancy and initialize a Trust Object - */ -static CK_RV -lg_createSMimeObject(SDB *sdb, CK_OBJECT_HANDLE *handle, - const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - SECItem derSubj,rawProfile,rawTime,emailKey; - SECItem *pRawProfile = NULL; - SECItem *pRawTime = NULL; - char *email = NULL; - const CK_ATTRIBUTE *subject = NULL, - *profile = NULL, - *time = NULL; - SECStatus rv; - NSSLOWCERTCertDBHandle *certHandle; - CK_RV ck_rv = CKR_OK; - - /* we can't store any certs private */ - if (lg_isTrue(CKA_PRIVATE,templ,count)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - certHandle = lg_getCertDB(sdb); - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - /* lookup SUBJECT */ - subject = lg_FindAttribute(CKA_SUBJECT,templ,count); - PORT_Assert(subject); - if (!subject) { - ck_rv = CKR_ATTRIBUTE_VALUE_INVALID; - goto loser; - } - - derSubj.data = (unsigned char *)subject->pValue; - derSubj.len = subject->ulValueLen ; - derSubj.type = 0; - - /* lookup VALUE */ - profile = lg_FindAttribute(CKA_VALUE,templ,count); - if (profile) { - rawProfile.data = (unsigned char *)profile->pValue; - rawProfile.len = profile->ulValueLen ; - rawProfile.type = siBuffer; - pRawProfile = &rawProfile; - } - - /* lookup Time */ - time = lg_FindAttribute(CKA_NETSCAPE_SMIME_TIMESTAMP,templ,count); - if (time) { - rawTime.data = (unsigned char *)time->pValue; - rawTime.len = time->ulValueLen ; - rawTime.type = siBuffer; - pRawTime = &rawTime; - } - - - email = lg_getString(CKA_NETSCAPE_EMAIL,templ,count); - if (!email) { - ck_rv = CKR_ATTRIBUTE_VALUE_INVALID; - goto loser; - } - - /* Store S/MIME Profile by SUBJECT */ - rv = nsslowcert_SaveSMimeProfile(certHandle, email, &derSubj, - pRawProfile,pRawTime); - if (rv != SECSuccess) { - ck_rv = CKR_DEVICE_ERROR; - goto loser; - } - emailKey.data = (unsigned char *)email; - emailKey.len = PORT_Strlen(email)+1; - - *handle = lg_mkHandle(sdb, &emailKey, LG_TOKEN_TYPE_SMIME); - -loser: - if (email) PORT_Free(email); - - return ck_rv; -} - -/* - * check the consistancy and initialize a Trust Object - */ -static CK_RV -lg_createCrlObject(SDB *sdb, CK_OBJECT_HANDLE *handle, - const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - PRBool isKRL = PR_FALSE; - SECItem derSubj,derCrl; - char *url = NULL; - const CK_ATTRIBUTE *subject,*crl; - SECStatus rv; - NSSLOWCERTCertDBHandle *certHandle; - - certHandle = lg_getCertDB(sdb); - - /* we can't store any private crls */ - if (lg_isTrue(CKA_PRIVATE,templ,count)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - /* lookup SUBJECT */ - subject = lg_FindAttribute(CKA_SUBJECT,templ,count); - if (!subject) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - derSubj.data = (unsigned char *)subject->pValue; - derSubj.len = subject->ulValueLen ; - - /* lookup VALUE */ - crl = lg_FindAttribute(CKA_VALUE,templ,count); - PORT_Assert(crl); - if (!crl) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - derCrl.data = (unsigned char *)crl->pValue; - derCrl.len = crl->ulValueLen ; - - url = lg_getString(CKA_NETSCAPE_URL,templ,count); - isKRL = lg_isTrue(CKA_NETSCAPE_KRL,templ,count); - - /* Store CRL by SUBJECT */ - rv = nsslowcert_AddCrl(certHandle, &derCrl, &derSubj, url, isKRL); - - if (url) { - PORT_Free(url); - } - if (rv != SECSuccess) { - return CKR_DEVICE_ERROR; - } - - /* if we overwrote the existing CRL, poison the handle entry so we get - * a new object handle */ - (void) lg_poisonHandle(sdb, &derSubj, - isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL); - *handle = lg_mkHandle(sdb, &derSubj, - isKRL ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL); - - return CKR_OK; -} - -/* - * check the consistancy and initialize a Public Key Object - */ -static CK_RV -lg_createPublicKeyObject(SDB *sdb, CK_KEY_TYPE key_type, - CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE; - CK_RV crv = CKR_OK; - NSSLOWKEYPrivateKey *priv; - SECItem pubKeySpace = {siBuffer, NULL, 0}; - SECItem *pubKey; -#ifdef NSS_ENABLE_ECC - SECItem pubKey2Space = {siBuffer, NULL, 0}; - PRArenaPool *arena = NULL; -#endif /* NSS_ENABLE_ECC */ - NSSLOWKEYDBHandle *keyHandle = NULL; - - - switch (key_type) { - case CKK_RSA: - pubKeyAttr = CKA_MODULUS; - break; -#ifdef NSS_ENABLE_ECC - case CKK_EC: - pubKeyAttr = CKA_EC_POINT; - break; -#endif /* NSS_ENABLE_ECC */ - case CKK_DSA: - case CKK_DH: - break; - default: - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - - pubKey = &pubKeySpace; - crv = lg_Attribute2SSecItem(NULL,pubKeyAttr,templ,count,pubKey); - if (crv != CKR_OK) return crv; - -#ifdef NSS_ENABLE_ECC - if (key_type == CKK_EC) { - SECStatus rv; - /* - * for ECC, use the decoded key first. - */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - crv = CKR_HOST_MEMORY; - goto done; - } - rv= SEC_QuickDERDecodeItem(arena, &pubKey2Space, - SEC_ASN1_GET(SEC_OctetStringTemplate), - pubKey); - if (rv != SECSuccess) { - /* decode didn't work, just try the pubKey */ - PORT_FreeArena(arena, PR_FALSE); - arena = NULL; - } else { - /* try the decoded pub key first */ - pubKey = &pubKey2Space; - } - } -#endif /* NSS_ENABLE_ECC */ - - PORT_Assert(pubKey->data); - if (pubKey->data == NULL) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - goto done; - } - keyHandle = lg_getKeyDB(sdb); - if (keyHandle == NULL) { - crv = CKR_TOKEN_WRITE_PROTECTED; - goto done; - } - if (keyHandle->version != 3) { - unsigned char buf[SHA1_LENGTH]; - SHA1_HashBuf(buf,pubKey->data,pubKey->len); - PORT_Memcpy(pubKey->data,buf,sizeof(buf)); - pubKey->len = sizeof(buf); - } - /* make sure the associated private key already exists */ - /* only works if we are logged in */ - priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, sdb /*password*/); -#ifdef NSS_ENABLE_ECC - if (priv == NULL && pubKey == &pubKey2Space) { - /* no match on the decoded key, match the original pubkey */ - pubKey = &pubKeySpace; - priv = nsslowkey_FindKeyByPublicKey(keyHandle, pubKey, - sdb /*password*/); - } -#endif - if (priv == NULL) { - /* the legacy database can only 'store' public keys which already - * have their corresponding private keys in the database */ - crv = CKR_ATTRIBUTE_VALUE_INVALID; - goto done; - } - nsslowkey_DestroyPrivateKey(priv); - crv = CKR_OK; - - *handle = lg_mkHandle(sdb, pubKey, LG_TOKEN_TYPE_PUB); - -done: - PORT_Free(pubKeySpace.data); -#ifdef NSS_ENABLE_ECC - if (arena) - PORT_FreeArena(arena, PR_FALSE); -#endif - - return crv; -} - -/* make a private key from a verified object */ -static NSSLOWKEYPrivateKey * -lg_mkPrivKey(SDB *sdb, const CK_ATTRIBUTE *templ, CK_ULONG count, - CK_KEY_TYPE key_type, CK_RV *crvp) -{ - NSSLOWKEYPrivateKey *privKey; - PLArenaPool *arena; - CK_RV crv = CKR_OK; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - *crvp = CKR_HOST_MEMORY; - return NULL; - } - - privKey = (NSSLOWKEYPrivateKey *) - PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey)); - if (privKey == NULL) { - PORT_FreeArena(arena,PR_FALSE); - *crvp = CKR_HOST_MEMORY; - return NULL; - } - - /* in future this would be a switch on key_type */ - privKey->arena = arena; - switch (key_type) { - case CKK_RSA: - privKey->keyType = NSSLOWKEYRSAKey; - crv=lg_Attribute2SSecItem(arena,CKA_MODULUS,templ,count, - &privKey->u.rsa.modulus); - if (crv != CKR_OK) break; - crv=lg_Attribute2SSecItem(arena,CKA_PUBLIC_EXPONENT,templ,count, - &privKey->u.rsa.publicExponent); - if (crv != CKR_OK) break; - crv=lg_PrivAttr2SSecItem(arena,CKA_PRIVATE_EXPONENT,templ,count, - &privKey->u.rsa.privateExponent, sdb); - if (crv != CKR_OK) break; - crv=lg_PrivAttr2SSecItem(arena,CKA_PRIME_1,templ,count, - &privKey->u.rsa.prime1, sdb); - if (crv != CKR_OK) break; - crv=lg_PrivAttr2SSecItem(arena,CKA_PRIME_2,templ,count, - &privKey->u.rsa.prime2, sdb); - if (crv != CKR_OK) break; - crv=lg_PrivAttr2SSecItem(arena,CKA_EXPONENT_1,templ,count, - &privKey->u.rsa.exponent1, sdb); - if (crv != CKR_OK) break; - crv=lg_PrivAttr2SSecItem(arena,CKA_EXPONENT_2,templ,count, - &privKey->u.rsa.exponent2, sdb); - if (crv != CKR_OK) break; - crv=lg_PrivAttr2SSecItem(arena,CKA_COEFFICIENT,templ,count, - &privKey->u.rsa.coefficient, sdb); - if (crv != CKR_OK) break; - rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version, - NSSLOWKEY_VERSION); - if (rv != SECSuccess) crv = CKR_HOST_MEMORY; - break; - - case CKK_DSA: - privKey->keyType = NSSLOWKEYDSAKey; - crv = lg_Attribute2SSecItem(arena,CKA_PRIME,templ,count, - &privKey->u.dsa.params.prime); - if (crv != CKR_OK) break; - crv = lg_Attribute2SSecItem(arena,CKA_SUBPRIME,templ,count, - &privKey->u.dsa.params.subPrime); - if (crv != CKR_OK) break; - crv = lg_Attribute2SSecItem(arena,CKA_BASE,templ,count, - &privKey->u.dsa.params.base); - if (crv != CKR_OK) break; - crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count, - &privKey->u.dsa.privateValue, sdb); - if (crv != CKR_OK) break; - if (lg_hasAttribute(CKA_NETSCAPE_DB, templ,count)) { - crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count, - &privKey->u.dsa.publicValue); - /* privKey was zero'd so public value is already set to NULL, 0 - * if we don't set it explicitly */ - } - break; - - case CKK_DH: - privKey->keyType = NSSLOWKEYDHKey; - crv = lg_Attribute2SSecItem(arena,CKA_PRIME,templ,count, - &privKey->u.dh.prime); - if (crv != CKR_OK) break; - crv = lg_Attribute2SSecItem(arena,CKA_BASE,templ,count, - &privKey->u.dh.base); - if (crv != CKR_OK) break; - crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count, - &privKey->u.dh.privateValue, sdb); - if (crv != CKR_OK) break; - if (lg_hasAttribute(CKA_NETSCAPE_DB, templ, count)) { - crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count, - &privKey->u.dh.publicValue); - /* privKey was zero'd so public value is already set to NULL, 0 - * if we don't set it explicitly */ - } - break; - -#ifdef NSS_ENABLE_ECC - case CKK_EC: - privKey->keyType = NSSLOWKEYECKey; - crv = lg_Attribute2SSecItem(arena, CKA_EC_PARAMS,templ,count, - &privKey->u.ec.ecParams.DEREncoding); - if (crv != CKR_OK) break; - - /* Fill out the rest of the ecParams structure - * based on the encoded params - */ - if (LGEC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding, - &privKey->u.ec.ecParams) != SECSuccess) { - crv = CKR_DOMAIN_PARAMS_INVALID; - break; - } - crv = lg_PrivAttr2SSecItem(arena,CKA_VALUE,templ,count, - &privKey->u.ec.privateValue, sdb); - if (crv != CKR_OK) break; - if (lg_hasAttribute(CKA_NETSCAPE_DB,templ,count)) { - crv = lg_Attribute2SSecItem(arena, CKA_NETSCAPE_DB,templ,count, - &privKey->u.ec.publicValue); - if (crv != CKR_OK) break; - /* privKey was zero'd so public value is already set to NULL, 0 - * if we don't set it explicitly */ - } - rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version, - NSSLOWKEY_EC_PRIVATE_KEY_VERSION); - if (rv != SECSuccess) crv = CKR_HOST_MEMORY; - break; -#endif /* NSS_ENABLE_ECC */ - - default: - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - *crvp = crv; - if (crv != CKR_OK) { - PORT_FreeArena(arena,PR_FALSE); - return NULL; - } - return privKey; -} - -/* - * check the consistancy and initialize a Private Key Object - */ -static CK_RV -lg_createPrivateKeyObject(SDB *sdb, CK_KEY_TYPE key_type, - CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - NSSLOWKEYPrivateKey *privKey; - char *label; - SECStatus rv = SECSuccess; - CK_RV crv = CKR_DEVICE_ERROR; - SECItem pubKey; - NSSLOWKEYDBHandle *keyHandle = lg_getKeyDB(sdb); - - if (keyHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - privKey=lg_mkPrivKey(sdb, templ,count,key_type,&crv); - if (privKey == NULL) return crv; - label = lg_getString(CKA_LABEL,templ,count); - - crv = lg_Attribute2SSecItem(NULL,CKA_NETSCAPE_DB,templ,count,&pubKey); - if (crv != CKR_OK) { - crv = CKR_TEMPLATE_INCOMPLETE; - rv = SECFailure; - goto fail; - } -#ifdef notdef - if (keyHandle->version != 3) { - unsigned char buf[SHA1_LENGTH]; - SHA1_HashBuf(buf,pubKey.data,pubKey.len); - PORT_Memcpy(pubKey.data,buf,sizeof(buf)); - pubKey.len = sizeof(buf); - } -#endif - /* get the key type */ - if (key_type == CKK_RSA) { - rv = RSA_PrivateKeyCheck(&privKey->u.rsa); - if (rv == SECFailure) { - goto fail; - } - } - rv = nsslowkey_StoreKeyByPublicKey(keyHandle, privKey, &pubKey, - label, sdb /*->password*/); - -fail: - if (label) PORT_Free(label); - *handle = lg_mkHandle(sdb,&pubKey,LG_TOKEN_TYPE_PRIV); - if (pubKey.data) PORT_Free(pubKey.data); - nsslowkey_DestroyPrivateKey(privKey); - if (rv != SECSuccess) return crv; - - return CKR_OK; -} - - -#define LG_KEY_MAX_RETRIES 10 /* don't hang if we are having problems with the rng */ -#define LG_KEY_ID_SIZE 18 /* don't use either SHA1 or MD5 sizes */ -/* - * Secret keys must have a CKA_ID value to be stored in the database. This code - * will generate one if there wasn't one already. - */ -static CK_RV -lg_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label) -{ - unsigned int retries; - SECStatus rv = SECSuccess; - CK_RV crv = CKR_OK; - - id->data = NULL; - if (label) { - id->data = (unsigned char *)PORT_Strdup(label); - if (id->data == NULL) { - return CKR_HOST_MEMORY; - } - id->len = PORT_Strlen(label)+1; - if (!nsslowkey_KeyForIDExists(handle,id)) { - return CKR_OK; - } - PORT_Free(id->data); - id->data = NULL; - id->len = 0; - } - id->data = (unsigned char *)PORT_Alloc(LG_KEY_ID_SIZE); - if (id->data == NULL) { - return CKR_HOST_MEMORY; - } - id->len = LG_KEY_ID_SIZE; - - retries = 0; - do { - rv = RNG_GenerateGlobalRandomBytes(id->data,id->len); - } while (rv == SECSuccess && nsslowkey_KeyForIDExists(handle,id) && - (++retries <= LG_KEY_MAX_RETRIES)); - - if ((rv != SECSuccess) || (retries > LG_KEY_MAX_RETRIES)) { - crv = CKR_DEVICE_ERROR; /* random number generator is bad */ - PORT_Free(id->data); - id->data = NULL; - id->len = 0; - } - return crv; -} - - -static NSSLOWKEYPrivateKey *lg_mkSecretKeyRep(const CK_ATTRIBUTE *templ, - CK_ULONG count, CK_KEY_TYPE key_type, - SECItem *pubkey, SDB *sdbpw) -{ - NSSLOWKEYPrivateKey *privKey = 0; - PLArenaPool *arena = 0; - CK_KEY_TYPE keyType; - PRUint32 keyTypeStorage; - SECItem keyTypeItem; - CK_RV crv; - SECStatus rv; - static unsigned char derZero[1] = { 0 }; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { crv = CKR_HOST_MEMORY; goto loser; } - - privKey = (NSSLOWKEYPrivateKey *) - PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey)); - if (privKey == NULL) { crv = CKR_HOST_MEMORY; goto loser; } - - privKey->arena = arena; - - /* Secret keys are represented in the database as "fake" RSA keys. - * The RSA key is marked as a secret key representation by setting the - * public exponent field to 0, which is an invalid RSA exponent. - * The other fields are set as follows: - * modulus - CKA_ID value for the secret key - * private exponent - CKA_VALUE (the key itself) - * coefficient - CKA_KEY_TYPE, which indicates what encryption algorithm - * is used for the key. - * all others - set to integer 0 - */ - privKey->keyType = NSSLOWKEYRSAKey; - - /* The modulus is set to the key id of the symmetric key */ - crv = lg_Attribute2SecItem(arena, CKA_ID, templ, count, - &privKey->u.rsa.modulus); - if (crv != CKR_OK) goto loser; - - /* The public exponent is set to 0 length to indicate a special key */ - privKey->u.rsa.publicExponent.len = sizeof derZero; - privKey->u.rsa.publicExponent.data = derZero; - - /* The private exponent is the actual key value */ - crv = lg_PrivAttr2SecItem(arena, CKA_VALUE, templ, count, - &privKey->u.rsa.privateExponent, sdbpw); - if (crv != CKR_OK) goto loser; - - /* All other fields empty - needs testing */ - privKey->u.rsa.prime1.len = sizeof derZero; - privKey->u.rsa.prime1.data = derZero; - - privKey->u.rsa.prime2.len = sizeof derZero; - privKey->u.rsa.prime2.data = derZero; - - privKey->u.rsa.exponent1.len = sizeof derZero; - privKey->u.rsa.exponent1.data = derZero; - - privKey->u.rsa.exponent2.len = sizeof derZero; - privKey->u.rsa.exponent2.data = derZero; - - /* Coeficient set to KEY_TYPE */ - crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &keyType); - if (crv != CKR_OK) goto loser; - /* on 64 bit platforms, we still want to store 32 bits of keyType (This is - * safe since the PKCS #11 defines for all types are 32 bits or less). */ - keyTypeStorage = (PRUint32) keyType; - keyTypeStorage = PR_htonl(keyTypeStorage); - keyTypeItem.data = (unsigned char *)&keyTypeStorage; - keyTypeItem.len = sizeof (keyTypeStorage); - rv = SECITEM_CopyItem(arena, &privKey->u.rsa.coefficient, &keyTypeItem); - if (rv != SECSuccess) { - crv = CKR_HOST_MEMORY; - goto loser; - } - - /* Private key version field set normally for compatibility */ - rv = DER_SetUInteger(privKey->arena, - &privKey->u.rsa.version, NSSLOWKEY_VERSION); - if (rv != SECSuccess) { crv = CKR_HOST_MEMORY; goto loser; } - -loser: - if (crv != CKR_OK) { - PORT_FreeArena(arena,PR_FALSE); - privKey = 0; - } - - return privKey; -} - -/* - * check the consistancy and initialize a Secret Key Object - */ -static CK_RV -lg_createSecretKeyObject(SDB *sdb, CK_KEY_TYPE key_type, - CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - CK_RV crv; - NSSLOWKEYPrivateKey *privKey = NULL; - NSSLOWKEYDBHandle *keyHandle = NULL; - SECItem pubKey; - char *label = NULL; - SECStatus rv = SECSuccess; - - pubKey.data = 0; - - /* If the object is a TOKEN object, store in the database */ - keyHandle = lg_getKeyDB(sdb); - - if (keyHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - label = lg_getString(CKA_LABEL,templ,count); - - crv = lg_Attribute2SecItem(NULL,CKA_ID,templ,count,&pubKey); - /* Should this be ID? */ - if (crv != CKR_OK) goto loser; - - /* if we don't have an ID, generate one */ - if (pubKey.len == 0) { - if (pubKey.data) { - PORT_Free(pubKey.data); - pubKey.data = NULL; - } - crv = lg_GenerateSecretCKA_ID(keyHandle, &pubKey, label); - if (crv != CKR_OK) goto loser; - } - - privKey = lg_mkSecretKeyRep(templ, count, key_type, &pubKey, sdb); - if (privKey == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - - rv = nsslowkey_StoreKeyByPublicKey(keyHandle, - privKey, &pubKey, label, sdb /*->password*/); - if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - goto loser; - } - - *handle = lg_mkHandle(sdb, &pubKey, LG_TOKEN_TYPE_KEY); - -loser: - if (label) PORT_Free(label); - if (privKey) nsslowkey_DestroyPrivateKey(privKey); - if (pubKey.data) PORT_Free(pubKey.data); - - return crv; -} - -/* - * check the consistancy and initialize a Key Object - */ -static CK_RV -lg_createKeyObject(SDB *sdb, CK_OBJECT_CLASS objclass, - CK_OBJECT_HANDLE *handle, const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - CK_RV crv; - CK_KEY_TYPE key_type; - - /* get the key type */ - crv = lg_GetULongAttribute(CKA_KEY_TYPE, templ, count, &key_type); - if (crv != CKR_OK) { - return crv; - } - - switch (objclass) { - case CKO_PUBLIC_KEY: - return lg_createPublicKeyObject(sdb,key_type,handle,templ,count); - case CKO_PRIVATE_KEY: - return lg_createPrivateKeyObject(sdb,key_type,handle,templ,count); - case CKO_SECRET_KEY: - return lg_createSecretKeyObject(sdb,key_type,handle,templ,count); - default: - break; - } - return CKR_ATTRIBUTE_VALUE_INVALID; -} - -/* - * Parse the template and create an object stored in the DB that reflects. - * the object specified in the database. - */ -CK_RV -lg_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *handle, - const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - CK_RV crv; - CK_OBJECT_CLASS objclass; - - /* get the object class */ - crv = lg_GetULongAttribute(CKA_CLASS, templ, count, &objclass); - if (crv != CKR_OK) { - return crv; - } - - /* Now handle the specific object class. - */ - switch (objclass) { - case CKO_CERTIFICATE: - crv = lg_createCertObject(sdb,handle,templ,count); - break; - case CKO_NETSCAPE_TRUST: - crv = lg_createTrustObject(sdb,handle,templ,count); - break; - case CKO_NETSCAPE_CRL: - crv = lg_createCrlObject(sdb,handle,templ,count); - break; - case CKO_NETSCAPE_SMIME: - crv = lg_createSMimeObject(sdb,handle,templ,count); - break; - case CKO_PRIVATE_KEY: - case CKO_PUBLIC_KEY: - case CKO_SECRET_KEY: - crv = lg_createKeyObject(sdb,objclass,handle,templ,count); - break; - default: - crv = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - - return crv; -} - diff --git a/security/nss/lib/softoken/legacydb/lgdb.h b/security/nss/lib/softoken/legacydb/lgdb.h deleted file mode 100644 index ed6f1298d..000000000 --- a/security/nss/lib/softoken/legacydb/lgdb.h +++ /dev/null @@ -1,216 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * Internal data structures and functions used by pkcs11.c - */ -#ifndef _LGDB_H_ -#define _LGDB_H_ 1 - -#include "nssilock.h" -#include "seccomon.h" -#include "secoidt.h" -#include "lowkeyti.h" -#include "pkcs11t.h" -#include "sdb.h" -#include "cdbhdl.h" - - -#define MULTIACCESS "multiaccess:" - - -/* machine dependent path stuff used by dbinit.c and pk11db.c */ -#ifdef macintosh -#define PATH_SEPARATOR ":" -#define SECMOD_DB "Security Modules" -#define CERT_DB_FMT "%sCertificates%s" -#define KEY_DB_FMT "%sKey Database%s" -#else -#define PATH_SEPARATOR "/" -#define SECMOD_DB "secmod.db" -#define CERT_DB_FMT "%scert%s.db" -#define KEY_DB_FMT "%skey%s.db" -#endif - -SEC_BEGIN_PROTOS - - -/* internal utility functions used by pkcs11.c */ -extern const CK_ATTRIBUTE *lg_FindAttribute(CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count); -extern CK_RV lg_Attribute2SecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item); -extern CK_RV lg_Attribute2SSecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item); -extern CK_RV lg_PrivAttr2SecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item, SDB *sdbpw); -extern CK_RV lg_PrivAttr2SSecItem(PLArenaPool *,CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item, SDB *sdbpw); -extern CK_RV lg_GetULongAttribute(CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - CK_ULONG *out); -extern PRBool lg_hasAttribute(CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count); -extern PRBool lg_isTrue(CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count); -extern PRBool lg_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass); -extern char *lg_getString(CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count); -extern unsigned int lg_MapTrust(CK_TRUST trust, PRBool clientAuth); - -/* clear out all the existing object ID to database key mappings. - * used to reinit a token */ -extern CK_RV lg_ClearTokenKeyHashTable(SDB *sdb); - - -extern void lg_FreeSearch(SDBFind *search); - -NSSLOWCERTCertDBHandle *lg_getCertDB(SDB *sdb); -NSSLOWKEYDBHandle *lg_getKeyDB(SDB *sdb); - -const char *lg_EvaluateConfigDir(const char *configdir, char **domain); - - -/* - * object handle modifiers - */ -#define LG_TOKEN_MASK 0xc0000000L -#define LG_TOKEN_TYPE_MASK 0x38000000L -#define LG_TOKEN_TYPE_SHIFT 27 -/* keydb (high bit == 0) */ -#define LG_TOKEN_TYPE_PRIV 0x08000000L -#define LG_TOKEN_TYPE_PUB 0x10000000L -#define LG_TOKEN_TYPE_KEY 0x18000000L -/* certdb (high bit == 1) */ -#define LG_TOKEN_TYPE_TRUST 0x20000000L -#define LG_TOKEN_TYPE_CRL 0x28000000L -#define LG_TOKEN_TYPE_SMIME 0x30000000L -#define LG_TOKEN_TYPE_CERT 0x38000000L - -#define LG_TOKEN_KRL_HANDLE (LG_TOKEN_TYPE_CRL|1) - -#define LG_SEARCH_BLOCK_SIZE 10 -#define LG_BUF_SPACE 50 -#define LG_STRICT PR_FALSE - -/* - * token object utilities - */ -void lg_addHandle(SDBFind *search, CK_OBJECT_HANDLE handle); -PRBool lg_poisonHandle(SDB *sdb, SECItem *dbkey, CK_OBJECT_HANDLE handle); -PRBool lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class, - const CK_ATTRIBUTE *templ, CK_ULONG count); -const SECItem *lg_lookupTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle); -CK_OBJECT_HANDLE lg_mkHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class); -SECStatus lg_deleteTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle); - -SECStatus lg_util_encrypt(PLArenaPool *arena, SDB *sdbpw, - SECItem *plainText, SECItem **cipherText); -SECStatus lg_util_decrypt(SDB *sdbpw, - SECItem *cipherText, SECItem **plainText); -PLHashTable *lg_GetHashTable(SDB *sdb); -void lg_DBLock(SDB *sdb); -void lg_DBUnlock(SDB *sdb); - -typedef void (*LGFreeFunc)(void *); - - -/* - * database functions - */ - -/* lg_FindObjectsInit initializes a search for token and session objects - * that match a template. */ -CK_RV lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate, - CK_ULONG ulCount, SDBFind **search); -/* lg_FindObjects continues a search for token and session objects - * that match a template, obtaining additional object handles. */ -CK_RV lg_FindObjects(SDB *sdb, SDBFind *search, - CK_OBJECT_HANDLE *phObject,CK_ULONG ulMaxObjectCount, - CK_ULONG *pulObjectCount); - -/* lg_FindObjectsFinal finishes a search for token and session objects. */ -CK_RV lg_FindObjectsFinal(SDB* lgdb, SDBFind *search); - -/* lg_CreateObject parses the template and create an object stored in the - * DB that reflects the object specified in the template. */ -CK_RV lg_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *handle, - const CK_ATTRIBUTE *templ, CK_ULONG count); - -CK_RV lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, - CK_ATTRIBUTE *template, CK_ULONG count); -CK_RV lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, - const CK_ATTRIBUTE *template, CK_ULONG count); -CK_RV lg_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id); - -CK_RV lg_Close(SDB *sdb); -CK_RV lg_Reset(SDB *sdb); - -/* - * The old database doesn't share and doesn't support - * transactions. - */ -CK_RV lg_Begin(SDB *sdb); -CK_RV lg_Commit(SDB *sdb); -CK_RV lg_Abort(SDB *sdb); -CK_RV lg_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2); -CK_RV lg_PutMetaData(SDB *sdb, const char *id, - const SECItem *item1, const SECItem *item2); - -SEC_END_PROTOS - -#ifndef XP_UNIX - -#define NO_CHECK_FORK - -#endif - -#ifndef NO_CHECK_FORK - -extern PRBool parentForkedAfterC_Initialize; -#define SKIP_AFTER_FORK(x) if (!parentForkedAfterC_Initialize) x - -#else - -#define SKIP_AFTER_FORK(x) x - -#endif /* NO_CHECK_FORK */ - -#endif /* _LGDB_H_ */ - diff --git a/security/nss/lib/softoken/legacydb/lgdestroy.c b/security/nss/lib/softoken/legacydb/lgdestroy.c deleted file mode 100644 index 37db2e50e..000000000 --- a/security/nss/lib/softoken/legacydb/lgdestroy.c +++ /dev/null @@ -1,144 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * Internal PKCS #11 functions. Should only be called by pkcs11.c - */ -#include "pkcs11.h" -#include "lgdb.h" -#include "pcert.h" -#include "lowkeyi.h" - -/* - * remove an object. - */ -CK_RV -lg_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id) -{ - CK_RV crv = CKR_OK; - SECStatus rv; - NSSLOWCERTCertificate *cert; - NSSLOWCERTCertTrust tmptrust; - PRBool isKrl; - NSSLOWKEYDBHandle *keyHandle; - NSSLOWCERTCertDBHandle *certHandle; - const SECItem *dbKey; - - object_id &= ~LG_TOKEN_MASK; - dbKey = lg_lookupTokenKeyByHandle(sdb,object_id); - if (dbKey == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - - /* remove the objects from the real data base */ - switch (object_id & LG_TOKEN_TYPE_MASK) { - case LG_TOKEN_TYPE_PRIV: - case LG_TOKEN_TYPE_KEY: - /* KEYID is the public KEY for DSA and DH, and the MODULUS for - * RSA */ - keyHandle = lg_getKeyDB(sdb); - if (!keyHandle) { - crv = CKR_TOKEN_WRITE_PROTECTED; - break; - } - rv = nsslowkey_DeleteKey(keyHandle, dbKey); - if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - } - break; - case LG_TOKEN_TYPE_PUB: - break; /* public keys only exist at the behest of the priv key */ - case LG_TOKEN_TYPE_CERT: - certHandle = lg_getCertDB(sdb); - if (!certHandle) { - crv = CKR_TOKEN_WRITE_PROTECTED; - break; - } - cert = nsslowcert_FindCertByKey(certHandle,dbKey); - if (cert == NULL) { - crv = CKR_DEVICE_ERROR; - break; - } - rv = nsslowcert_DeletePermCertificate(cert); - if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - } - nsslowcert_DestroyCertificate(cert); - break; - case LG_TOKEN_TYPE_CRL: - certHandle = lg_getCertDB(sdb); - if (!certHandle) { - crv = CKR_TOKEN_WRITE_PROTECTED; - break; - } - isKrl = (PRBool) (object_id == LG_TOKEN_KRL_HANDLE); - rv = nsslowcert_DeletePermCRL(certHandle, dbKey, isKrl); - if (rv == SECFailure) crv = CKR_DEVICE_ERROR; - break; - case LG_TOKEN_TYPE_TRUST: - certHandle = lg_getCertDB(sdb); - if (!certHandle) { - crv = CKR_TOKEN_WRITE_PROTECTED; - break; - } - cert = nsslowcert_FindCertByKey(certHandle, dbKey); - if (cert == NULL) { - crv = CKR_DEVICE_ERROR; - break; - } - tmptrust = *cert->trust; - tmptrust.sslFlags &= CERTDB_PRESERVE_TRUST_BITS; - tmptrust.emailFlags &= CERTDB_PRESERVE_TRUST_BITS; - tmptrust.objectSigningFlags &= CERTDB_PRESERVE_TRUST_BITS; - tmptrust.sslFlags |= CERTDB_TRUSTED_UNKNOWN; - tmptrust.emailFlags |= CERTDB_TRUSTED_UNKNOWN; - tmptrust.objectSigningFlags |= CERTDB_TRUSTED_UNKNOWN; - rv = nsslowcert_ChangeCertTrust(certHandle, cert, &tmptrust); - if (rv != SECSuccess) crv = CKR_DEVICE_ERROR; - nsslowcert_DestroyCertificate(cert); - break; - default: - break; - } - lg_DBLock(sdb); - lg_deleteTokenKeyByHandle(sdb,object_id); - lg_DBUnlock(sdb); - - return crv; -} - - - diff --git a/security/nss/lib/softoken/legacydb/lgfind.c b/security/nss/lib/softoken/legacydb/lgfind.c deleted file mode 100644 index b45f0096c..000000000 --- a/security/nss/lib/softoken/legacydb/lgfind.c +++ /dev/null @@ -1,940 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "secitem.h" -#include "pkcs11.h" -#include "lgdb.h" -#include "lowkeyi.h" -#include "pcert.h" -#include "blapi.h" - -#include "keydbi.h" - -/* - * This code maps PKCS #11 Finds to legacy database searches. This code - * was orginally in pkcs11.c in previous versions of NSS. - */ - -struct SDBFindStr { - CK_OBJECT_HANDLE *handles; - int size; - int index; - int array_size; -}; - - -/* - * free a search structure - */ -void -lg_FreeSearch(SDBFind *search) -{ - if (search->handles) { - PORT_Free(search->handles); - } - PORT_Free(search); -} - -void -lg_addHandle(SDBFind *search, CK_OBJECT_HANDLE handle) -{ - if (search->handles == NULL) { - return; - } - if (search->size >= search->array_size) { - search->array_size += LG_SEARCH_BLOCK_SIZE; - search->handles = (CK_OBJECT_HANDLE *) PORT_Realloc(search->handles, - sizeof(CK_OBJECT_HANDLE)* search->array_size); - if (search->handles == NULL) { - return; - } - } - search->handles[search->size] = handle; - search->size++; -} - -/* - * find any certs that may match the template and load them. - */ -#define LG_CERT 0x00000001 -#define LG_TRUST 0x00000002 -#define LG_CRL 0x00000004 -#define LG_SMIME 0x00000008 -#define LG_PRIVATE 0x00000010 -#define LG_PUBLIC 0x00000020 -#define LG_KEY 0x00000040 - -/* - * structure to collect key handles. - */ -typedef struct lgEntryDataStr { - SDB *sdb; - SDBFind *searchHandles; - const CK_ATTRIBUTE *template; - CK_ULONG templ_count; -} lgEntryData; - - -static SECStatus -lg_crl_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg) -{ - lgEntryData *crlData; - CK_OBJECT_HANDLE class_handle; - SDB *sdb; - - crlData = (lgEntryData *)arg; - sdb = crlData->sdb; - - class_handle = (type == certDBEntryTypeRevocation) ? LG_TOKEN_TYPE_CRL : - LG_TOKEN_KRL_HANDLE; - if (lg_tokenMatch(sdb, key, class_handle, - crlData->template, crlData->templ_count)) { - lg_addHandle(crlData->searchHandles, - lg_mkHandle(sdb,key,class_handle)); - } - return(SECSuccess); -} - -static void -lg_searchCrls(SDB *sdb, SECItem *derSubject, PRBool isKrl, - unsigned long classFlags, SDBFind *search, - const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount) -{ - NSSLOWCERTCertDBHandle *certHandle = NULL; - - certHandle = lg_getCertDB(sdb); - if (certHandle == NULL) { - return; - } - if (derSubject->data != NULL) { - certDBEntryRevocation *crl = - nsslowcert_FindCrlByKey(certHandle, derSubject, isKrl); - - if (crl != NULL) { - lg_addHandle(search, lg_mkHandle(sdb, derSubject, - isKrl ? LG_TOKEN_KRL_HANDLE : LG_TOKEN_TYPE_CRL)); - nsslowcert_DestroyDBEntry((certDBEntry *)crl); - } - } else { - lgEntryData crlData; - - /* traverse */ - crlData.sdb = sdb; - crlData.searchHandles = search; - crlData.template = pTemplate; - crlData.templ_count = ulCount; - nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeRevocation, - lg_crl_collect, (void *)&crlData); - nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeKeyRevocation, - lg_crl_collect, (void *)&crlData); - } -} - -/* - * structure to collect key handles. - */ -typedef struct lgKeyDataStr { - SDB *sdb; - NSSLOWKEYDBHandle *keyHandle; - SDBFind *searchHandles; - SECItem *id; - const CK_ATTRIBUTE *template; - CK_ULONG templ_count; - unsigned long classFlags; - PRBool strict; -} lgKeyData; - -static PRBool -isSecretKey(NSSLOWKEYPrivateKey *privKey) -{ - if (privKey->keyType == NSSLOWKEYRSAKey && - privKey->u.rsa.publicExponent.len == 1 && - privKey->u.rsa.publicExponent.data[0] == 0) - return PR_TRUE; - - return PR_FALSE; -} - - - -static SECStatus -lg_key_collect(DBT *key, DBT *data, void *arg) -{ - lgKeyData *keyData; - NSSLOWKEYPrivateKey *privKey = NULL; - SECItem tmpDBKey; - SDB *sdb; - unsigned long classFlags; - - keyData = (lgKeyData *)arg; - sdb = keyData->sdb; - classFlags = keyData->classFlags; - - tmpDBKey.data = key->data; - tmpDBKey.len = key->size; - tmpDBKey.type = siBuffer; - - PORT_Assert(keyData->keyHandle); - if (!keyData->strict && keyData->id && keyData->id->data) { - SECItem result; - PRBool haveMatch= PR_FALSE; - unsigned char hashKey[SHA1_LENGTH]; - result.data = hashKey; - result.len = sizeof(hashKey); - - if (keyData->id->len == 0) { - /* Make sure this isn't a LG_KEY */ - privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle, - &tmpDBKey, keyData->sdb/*->password*/); - if (privKey) { - /* turn off the unneeded class flags */ - classFlags &= isSecretKey(privKey) ? ~(LG_PRIVATE|LG_PUBLIC) : - ~LG_KEY; - haveMatch = (PRBool) - ((classFlags & (LG_KEY|LG_PRIVATE|LG_PUBLIC)) != 0); - nsslowkey_DestroyPrivateKey(privKey); - } - } else { - SHA1_HashBuf( hashKey, key->data, key->size ); /* match id */ - haveMatch = SECITEM_ItemsAreEqual(keyData->id,&result); - if (!haveMatch && ((unsigned char *)key->data)[0] == 0) { - /* This is a fix for backwards compatibility. The key - * database indexes private keys by the public key, and - * versions of NSS prior to 3.4 stored the public key as - * a signed integer. The public key is now treated as an - * unsigned integer, with no leading zero. In order to - * correctly compute the hash of an old key, it is necessary - * to fallback and detect the leading zero. - */ - SHA1_HashBuf(hashKey, - (unsigned char *)key->data + 1, key->size - 1); - haveMatch = SECITEM_ItemsAreEqual(keyData->id,&result); - } - } - if (haveMatch) { - if (classFlags & LG_PRIVATE) { - lg_addHandle(keyData->searchHandles, - lg_mkHandle(sdb,&tmpDBKey,LG_TOKEN_TYPE_PRIV)); - } - if (classFlags & LG_PUBLIC) { - lg_addHandle(keyData->searchHandles, - lg_mkHandle(sdb,&tmpDBKey,LG_TOKEN_TYPE_PUB)); - } - if (classFlags & LG_KEY) { - lg_addHandle(keyData->searchHandles, - lg_mkHandle(sdb,&tmpDBKey,LG_TOKEN_TYPE_KEY)); - } - } - return SECSuccess; - } - - privKey = nsslowkey_FindKeyByPublicKey(keyData->keyHandle, &tmpDBKey, - keyData->sdb/*->password*/); - if ( privKey == NULL ) { - goto loser; - } - - if (isSecretKey(privKey)) { - if ((classFlags & LG_KEY) && - lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_KEY, - keyData->template, keyData->templ_count)) { - lg_addHandle(keyData->searchHandles, - lg_mkHandle(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_KEY)); - } - } else { - if ((classFlags & LG_PRIVATE) && - lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PRIV, - keyData->template, keyData->templ_count)) { - lg_addHandle(keyData->searchHandles, - lg_mkHandle(keyData->sdb,&tmpDBKey,LG_TOKEN_TYPE_PRIV)); - } - if ((classFlags & LG_PUBLIC) && - lg_tokenMatch(keyData->sdb, &tmpDBKey, LG_TOKEN_TYPE_PUB, - keyData->template, keyData->templ_count)) { - lg_addHandle(keyData->searchHandles, - lg_mkHandle(keyData->sdb, &tmpDBKey,LG_TOKEN_TYPE_PUB)); - } - } - -loser: - if ( privKey ) { - nsslowkey_DestroyPrivateKey(privKey); - } - return(SECSuccess); -} - -static void -lg_searchKeys(SDB *sdb, SECItem *key_id, - unsigned long classFlags, SDBFind *search, PRBool mustStrict, - const CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount) -{ - NSSLOWKEYDBHandle *keyHandle = NULL; - NSSLOWKEYPrivateKey *privKey; - lgKeyData keyData; - PRBool found = PR_FALSE; - - keyHandle = lg_getKeyDB(sdb); - if (keyHandle == NULL) { - return; - } - - if (key_id->data) { - privKey = nsslowkey_FindKeyByPublicKey(keyHandle, key_id, sdb); - if (privKey) { - if ((classFlags & LG_KEY) && isSecretKey(privKey)) { - lg_addHandle(search, - lg_mkHandle(sdb,key_id,LG_TOKEN_TYPE_KEY)); - found = PR_TRUE; - } - if ((classFlags & LG_PRIVATE) && !isSecretKey(privKey)) { - lg_addHandle(search, - lg_mkHandle(sdb,key_id,LG_TOKEN_TYPE_PRIV)); - found = PR_TRUE; - } - if ((classFlags & LG_PUBLIC) && !isSecretKey(privKey)) { - lg_addHandle(search, - lg_mkHandle(sdb,key_id,LG_TOKEN_TYPE_PUB)); - found = PR_TRUE; - } - nsslowkey_DestroyPrivateKey(privKey); - } - /* don't do the traversal if we have an up to date db */ - if (keyHandle->version != 3) { - goto loser; - } - /* don't do the traversal if it can't possibly be the correct id */ - /* all soft token id's are SHA1_HASH_LEN's */ - if (key_id->len != SHA1_LENGTH) { - goto loser; - } - if (found) { - /* if we already found some keys, don't do the traversal */ - goto loser; - } - } - keyData.sdb = sdb; - keyData.keyHandle = keyHandle; - keyData.searchHandles = search; - keyData.id = key_id; - keyData.template = pTemplate; - keyData.templ_count = ulCount; - keyData.classFlags = classFlags; - keyData.strict = mustStrict ? mustStrict : LG_STRICT; - - nsslowkey_TraverseKeys(keyHandle, lg_key_collect, &keyData); - -loser: - return; -} - -/* - * structure to collect certs into - */ -typedef struct lgCertDataStr { - SDB *sdb; - int cert_count; - int max_cert_count; - NSSLOWCERTCertificate **certs; - const CK_ATTRIBUTE *template; - CK_ULONG templ_count; - unsigned long classFlags; - PRBool strict; -} lgCertData; - -/* - * collect all the certs from the traverse call. - */ -static SECStatus -lg_cert_collect(NSSLOWCERTCertificate *cert,void *arg) -{ - lgCertData *cd = (lgCertData *)arg; - - if (cert == NULL) { - return SECSuccess; - } - - if (cd->certs == NULL) { - return SECFailure; - } - - if (cd->strict) { - if ((cd->classFlags & LG_CERT) && !lg_tokenMatch(cd->sdb, - &cert->certKey, LG_TOKEN_TYPE_CERT, cd->template,cd->templ_count)) { - return SECSuccess; - } - if ((cd->classFlags & LG_TRUST) && !lg_tokenMatch(cd->sdb, - &cert->certKey, LG_TOKEN_TYPE_TRUST, - cd->template, cd->templ_count)) { - return SECSuccess; - } - } - - /* allocate more space if we need it. This should only happen in - * the general traversal case */ - if (cd->cert_count >= cd->max_cert_count) { - int size; - cd->max_cert_count += LG_SEARCH_BLOCK_SIZE; - size = cd->max_cert_count * sizeof (NSSLOWCERTCertificate *); - cd->certs = (NSSLOWCERTCertificate **)PORT_Realloc(cd->certs,size); - if (cd->certs == NULL) { - return SECFailure; - } - } - - cd->certs[cd->cert_count++] = nsslowcert_DupCertificate(cert); - return SECSuccess; -} - -/* provide impedence matching ... */ -static SECStatus -lg_cert_collect2(NSSLOWCERTCertificate *cert, SECItem *dymmy, void *arg) -{ - return lg_cert_collect(cert, arg); -} - -static void -lg_searchSingleCert(lgCertData *certData,NSSLOWCERTCertificate *cert) -{ - if (cert == NULL) { - return; - } - if (certData->strict && - !lg_tokenMatch(certData->sdb, &cert->certKey, LG_TOKEN_TYPE_CERT, - certData->template,certData->templ_count)) { - nsslowcert_DestroyCertificate(cert); - return; - } - certData->certs = (NSSLOWCERTCertificate **) - PORT_Alloc(sizeof (NSSLOWCERTCertificate *)); - if (certData->certs == NULL) { - nsslowcert_DestroyCertificate(cert); - return; - } - certData->certs[0] = cert; - certData->cert_count = 1; -} - -static void -lg_CertSetupData(lgCertData *certData,int count) -{ - certData->max_cert_count = count; - - if (certData->max_cert_count <= 0) { - return; - } - certData->certs = (NSSLOWCERTCertificate **) - PORT_Alloc( count * sizeof(NSSLOWCERTCertificate *)); - return; -} - -static void -lg_searchCertsAndTrust(SDB *sdb, SECItem *derCert, SECItem *name, - SECItem *derSubject, NSSLOWCERTIssuerAndSN *issuerSN, - SECItem *email, - unsigned long classFlags, SDBFind *handles, - const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) -{ - NSSLOWCERTCertDBHandle *certHandle = NULL; - lgCertData certData; - int i; - - certHandle = lg_getCertDB(sdb); - if (certHandle == NULL) return; - - certData.sdb = sdb; - certData.max_cert_count = 0; - certData.certs = NULL; - certData.cert_count = 0; - certData.template = pTemplate; - certData.templ_count = ulCount; - certData.classFlags = classFlags; - certData.strict = LG_STRICT; - - - /* - * Find the Cert. - */ - if (derCert->data != NULL) { - NSSLOWCERTCertificate *cert = - nsslowcert_FindCertByDERCert(certHandle,derCert); - lg_searchSingleCert(&certData,cert); - } else if (name->data != NULL) { - char *tmp_name = (char*)PORT_Alloc(name->len+1); - int count; - - if (tmp_name == NULL) { - return; - } - PORT_Memcpy(tmp_name,name->data,name->len); - tmp_name[name->len] = 0; - - count= nsslowcert_NumPermCertsForNickname(certHandle,tmp_name); - lg_CertSetupData(&certData,count); - nsslowcert_TraversePermCertsForNickname(certHandle,tmp_name, - lg_cert_collect, &certData); - PORT_Free(tmp_name); - } else if (derSubject->data != NULL) { - int count; - - count = nsslowcert_NumPermCertsForSubject(certHandle,derSubject); - lg_CertSetupData(&certData,count); - nsslowcert_TraversePermCertsForSubject(certHandle,derSubject, - lg_cert_collect, &certData); - } else if ((issuerSN->derIssuer.data != NULL) && - (issuerSN->serialNumber.data != NULL)) { - if (classFlags & LG_CERT) { - NSSLOWCERTCertificate *cert = - nsslowcert_FindCertByIssuerAndSN(certHandle,issuerSN); - - lg_searchSingleCert(&certData,cert); - } - if (classFlags & LG_TRUST) { - NSSLOWCERTTrust *trust = - nsslowcert_FindTrustByIssuerAndSN(certHandle, issuerSN); - - if (trust) { - lg_addHandle(handles, - lg_mkHandle(sdb,&trust->dbKey,LG_TOKEN_TYPE_TRUST)); - nsslowcert_DestroyTrust(trust); - } - } - } else if (email->data != NULL) { - char *tmp_name = (char*)PORT_Alloc(email->len+1); - certDBEntrySMime *entry = NULL; - - if (tmp_name == NULL) { - return; - } - PORT_Memcpy(tmp_name,email->data,email->len); - tmp_name[email->len] = 0; - - entry = nsslowcert_ReadDBSMimeEntry(certHandle,tmp_name); - if (entry) { - int count; - SECItem *subjectName = &entry->subjectName; - - count = nsslowcert_NumPermCertsForSubject(certHandle, subjectName); - lg_CertSetupData(&certData,count); - nsslowcert_TraversePermCertsForSubject(certHandle, subjectName, - lg_cert_collect, &certData); - - nsslowcert_DestroyDBEntry((certDBEntry *)entry); - } - PORT_Free(tmp_name); - } else { - /* we aren't filtering the certs, we are working on all, so turn - * on the strict filters. */ - certData.strict = PR_TRUE; - lg_CertSetupData(&certData,LG_SEARCH_BLOCK_SIZE); - nsslowcert_TraversePermCerts(certHandle, lg_cert_collect2, &certData); - } - - /* - * build the handles - */ - for (i=0 ; i < certData.cert_count ; i++) { - NSSLOWCERTCertificate *cert = certData.certs[i]; - - /* if we filtered it would have been on the stuff above */ - if (classFlags & LG_CERT) { - lg_addHandle(handles, - lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_CERT)); - } - if ((classFlags & LG_TRUST) && nsslowcert_hasTrust(cert->trust)) { - lg_addHandle(handles, - lg_mkHandle(sdb,&cert->certKey,LG_TOKEN_TYPE_TRUST)); - } - nsslowcert_DestroyCertificate(cert); - } - - if (certData.certs) PORT_Free(certData.certs); - return; -} - -static SECStatus -lg_smime_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg) -{ - lgEntryData *smimeData; - SDB *sdb; - - smimeData = (lgEntryData *)arg; - sdb = smimeData->sdb; - - if (lg_tokenMatch(sdb, key, LG_TOKEN_TYPE_SMIME, - smimeData->template, smimeData->templ_count)) { - lg_addHandle(smimeData->searchHandles, - lg_mkHandle(sdb,key,LG_TOKEN_TYPE_SMIME)); - } - return(SECSuccess); -} - -static void -lg_searchSMime(SDB *sdb, SECItem *email, SDBFind *handles, - const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) -{ - NSSLOWCERTCertDBHandle *certHandle = NULL; - certDBEntrySMime *entry; - - certHandle = lg_getCertDB(sdb); - if (certHandle == NULL) return; - - if (email->data != NULL) { - char *tmp_name = (char*)PORT_Alloc(email->len+1); - - if (tmp_name == NULL) { - return; - } - PORT_Memcpy(tmp_name,email->data,email->len); - tmp_name[email->len] = 0; - - entry = nsslowcert_ReadDBSMimeEntry(certHandle,tmp_name); - if (entry) { - SECItem emailKey; - - emailKey.data = (unsigned char *)tmp_name; - emailKey.len = PORT_Strlen(tmp_name)+1; - emailKey.type = 0; - lg_addHandle(handles, - lg_mkHandle(sdb,&emailKey,LG_TOKEN_TYPE_SMIME)); - nsslowcert_DestroyDBEntry((certDBEntry *)entry); - } - PORT_Free(tmp_name); - } else { - /* traverse */ - lgEntryData smimeData; - - /* traverse */ - smimeData.sdb = sdb; - smimeData.searchHandles = handles; - smimeData.template = pTemplate; - smimeData.templ_count = ulCount; - nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeSMimeProfile, - lg_smime_collect, (void *)&smimeData); - } - return; -} - -static CK_RV -lg_searchTokenList(SDB *sdb, SDBFind *search, - const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) -{ - int i; - PRBool isKrl = PR_FALSE; - SECItem derCert = { siBuffer, NULL, 0 }; - SECItem derSubject = { siBuffer, NULL, 0 }; - SECItem name = { siBuffer, NULL, 0 }; - SECItem email = { siBuffer, NULL, 0 }; - SECItem key_id = { siBuffer, NULL, 0 }; - SECItem cert_sha1_hash = { siBuffer, NULL, 0 }; - SECItem cert_md5_hash = { siBuffer, NULL, 0 }; - NSSLOWCERTIssuerAndSN issuerSN = { - { siBuffer, NULL, 0 }, - { siBuffer, NULL, 0 } - }; - SECItem *copy = NULL; - CK_CERTIFICATE_TYPE certType; - CK_OBJECT_CLASS objectClass; - CK_RV crv; - unsigned long classFlags; - - if (lg_getCertDB(sdb) == NULL) { - classFlags = LG_PRIVATE|LG_KEY; - } else { - classFlags = LG_CERT|LG_TRUST|LG_PUBLIC|LG_SMIME|LG_CRL; - } - - /* - * look for things to search on token objects for. If the right options - * are specified, we can use them as direct indeces into the database - * (rather than using linear searches. We can also use the attributes to - * limit the kinds of objects we are searching for. Later we can use this - * array to filter the remaining objects more finely. - */ - for (i=0 ;classFlags && i < (int)ulCount; i++) { - - switch (pTemplate[i].type) { - case CKA_SUBJECT: - copy = &derSubject; - classFlags &= (LG_CERT|LG_PRIVATE|LG_PUBLIC|LG_SMIME|LG_CRL); - break; - case CKA_ISSUER: - copy = &issuerSN.derIssuer; - classFlags &= (LG_CERT|LG_TRUST); - break; - case CKA_SERIAL_NUMBER: - copy = &issuerSN.serialNumber; - classFlags &= (LG_CERT|LG_TRUST); - break; - case CKA_VALUE: - copy = &derCert; - classFlags &= (LG_CERT|LG_CRL|LG_SMIME); - break; - case CKA_LABEL: - copy = &name; - break; - case CKA_NETSCAPE_EMAIL: - copy = &email; - classFlags &= LG_SMIME|LG_CERT; - break; - case CKA_NETSCAPE_SMIME_TIMESTAMP: - classFlags &= LG_SMIME; - break; - case CKA_CLASS: - crv = lg_GetULongAttribute(CKA_CLASS,&pTemplate[i],1, &objectClass); - if (crv != CKR_OK) { - classFlags = 0; - break;; - } - switch (objectClass) { - case CKO_CERTIFICATE: - classFlags &= LG_CERT; - break; - case CKO_NETSCAPE_TRUST: - classFlags &= LG_TRUST; - break; - case CKO_NETSCAPE_CRL: - classFlags &= LG_CRL; - break; - case CKO_NETSCAPE_SMIME: - classFlags &= LG_SMIME; - break; - case CKO_PRIVATE_KEY: - classFlags &= LG_PRIVATE; - break; - case CKO_PUBLIC_KEY: - classFlags &= LG_PUBLIC; - break; - case CKO_SECRET_KEY: - classFlags &= LG_KEY; - break; - default: - classFlags = 0; - break; - } - break; - case CKA_PRIVATE: - if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { - classFlags = 0; - } - if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) { - classFlags &= (LG_PRIVATE|LG_KEY); - } else { - classFlags &= ~(LG_PRIVATE|LG_KEY); - } - break; - case CKA_SENSITIVE: - if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { - classFlags = 0; - } - if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) { - classFlags &= (LG_PRIVATE|LG_KEY); - } else { - classFlags = 0; - } - break; - case CKA_TOKEN: - if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { - classFlags = 0; - } - if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) { - classFlags = 0; - } - break; - case CKA_CERT_SHA1_HASH: - classFlags &= LG_TRUST; - copy = &cert_sha1_hash; break; - case CKA_CERT_MD5_HASH: - classFlags &= LG_TRUST; - copy = &cert_md5_hash; break; - case CKA_CERTIFICATE_TYPE: - crv = lg_GetULongAttribute(CKA_CLASS,&pTemplate[i],1,&certType); - if (crv != CKR_OK) { - classFlags = 0; - } - classFlags &= LG_CERT; - if (certType != CKC_X_509) { - classFlags = 0; - } - break; - case CKA_ID: - copy = &key_id; - classFlags &= (LG_CERT|LG_PRIVATE|LG_KEY|LG_PUBLIC); - break; - case CKA_NETSCAPE_KRL: - if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) { - classFlags = 0; - } - classFlags &= LG_CRL; - isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE); - break; - case CKA_MODIFIABLE: - break; - case CKA_KEY_TYPE: - case CKA_DERIVE: - classFlags &= LG_PUBLIC|LG_PRIVATE|LG_KEY; - break; - case CKA_VERIFY_RECOVER: - classFlags &= LG_PUBLIC; - break; - case CKA_SIGN_RECOVER: - classFlags &= LG_PRIVATE; - break; - case CKA_ENCRYPT: - case CKA_VERIFY: - case CKA_WRAP: - classFlags &= LG_PUBLIC|LG_KEY; - break; - case CKA_DECRYPT: - case CKA_SIGN: - case CKA_UNWRAP: - case CKA_ALWAYS_SENSITIVE: - case CKA_EXTRACTABLE: - case CKA_NEVER_EXTRACTABLE: - classFlags &= LG_PRIVATE|LG_KEY; - break; - /* can't be a certificate if it doesn't match one of the above - * attributes */ - default: - classFlags = 0; - break; - } - if (copy) { - copy->data = (unsigned char*)pTemplate[i].pValue; - copy->len = pTemplate[i].ulValueLen; - } - copy = NULL; - } - - /* certs */ - if (classFlags & (LG_CERT|LG_TRUST)) { - lg_searchCertsAndTrust(sdb,&derCert,&name,&derSubject, - &issuerSN, &email,classFlags,search, - pTemplate, ulCount); - } - - /* keys */ - if (classFlags & (LG_PRIVATE|LG_PUBLIC|LG_KEY)) { - PRBool mustStrict = (name.len != 0); - lg_searchKeys(sdb, &key_id, classFlags, search, - mustStrict, pTemplate, ulCount); - } - - /* crl's */ - if (classFlags & LG_CRL) { - lg_searchCrls(sdb, &derSubject, isKrl, classFlags, search, - pTemplate, ulCount); - } - /* Add S/MIME entry stuff */ - if (classFlags & LG_SMIME) { - lg_searchSMime(sdb, &email, search, pTemplate, ulCount); - } - return CKR_OK; -} - - -/* lg_FindObjectsInit initializes a search for token and session objects - * that match a template. */ -CK_RV lg_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *pTemplate, - CK_ULONG ulCount, SDBFind **retSearch) -{ - SDBFind *search; - CK_RV crv = CKR_OK; - - *retSearch = NULL; - - search = (SDBFind *)PORT_Alloc(sizeof(SDBFind)); - if (search == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - search->handles = (CK_OBJECT_HANDLE *) - PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * LG_SEARCH_BLOCK_SIZE); - if (search->handles == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - search->index = 0; - search->size = 0; - search->array_size = LG_SEARCH_BLOCK_SIZE; - /* FIXME - do we still need to get Login state? */ - - crv = lg_searchTokenList(sdb, search, pTemplate, ulCount); - if (crv != CKR_OK) { - goto loser; - } - - *retSearch = search; - return CKR_OK; - -loser: - if (search) { - lg_FreeSearch(search); - } - return crv; -} - - -/* lg_FindObjects continues a search for token and session objects - * that match a template, obtaining additional object handles. */ -CK_RV lg_FindObjects(SDB *sdb, SDBFind *search, - CK_OBJECT_HANDLE *phObject,CK_ULONG ulMaxObjectCount, - CK_ULONG *pulObjectCount) -{ - int transfer; - int left; - - *pulObjectCount = 0; - left = search->size - search->index; - transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount; - if (transfer > 0) { - PORT_Memcpy(phObject,&search->handles[search->index], - transfer*sizeof(CK_OBJECT_HANDLE)); - } else { - *phObject = CK_INVALID_HANDLE; - } - - search->index += transfer; - *pulObjectCount = transfer; - return CKR_OK; -} - -/* lg_FindObjectsFinal finishes a search for token and session objects. */ -CK_RV lg_FindObjectsFinal(SDB* lgdb, SDBFind *search) -{ - - if (search != NULL) { - lg_FreeSearch(search); - } - return CKR_OK; -} diff --git a/security/nss/lib/softoken/legacydb/lginit.c b/security/nss/lib/softoken/legacydb/lginit.c deleted file mode 100644 index 152e00ad8..000000000 --- a/security/nss/lib/softoken/legacydb/lginit.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * NSS utility functions - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#include "lowkeyi.h" -#include "pcert.h" -#include "keydbi.h" -#include "lgdb.h" -#include "secoid.h" -#include "prenv.h" - -typedef struct LGPrivateStr { - NSSLOWCERTCertDBHandle *certDB; - NSSLOWKEYDBHandle *keyDB; - PRLock *dbLock; - PLHashTable *hashTable; -} LGPrivate; - -static char * -lg_certdb_name_cb(void *arg, int dbVersion) -{ - const char *configdir = (const char *)arg; - const char *dbver; - char *smpname = NULL; - char *dbname = NULL; - - switch (dbVersion) { - case 8: - dbver = "8"; - break; - case 7: - dbver = "7"; - break; - case 6: - dbver = "6"; - break; - case 5: - dbver = "5"; - break; - case 4: - default: - dbver = ""; - break; - } - - /* make sure we return something allocated with PORT_ so we have properly - * matched frees at the end */ - smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver); - if (smpname) { - dbname = PORT_Strdup(smpname); - PR_smprintf_free(smpname); - } - return dbname; -} - -static char * -lg_keydb_name_cb(void *arg, int dbVersion) -{ - const char *configdir = (const char *)arg; - const char *dbver; - char *smpname = NULL; - char *dbname = NULL; - - switch (dbVersion) { - case 4: - dbver = "4"; - break; - case 3: - dbver = "3"; - break; - case 1: - dbver = "1"; - break; - case 2: - default: - dbver = ""; - break; - } - - smpname = PR_smprintf(KEY_DB_FMT, configdir, dbver); - if (smpname) { - dbname = PORT_Strdup(smpname); - PR_smprintf_free(smpname); - } - return dbname; -} - -const char * -lg_EvaluateConfigDir(const char *configdir,char **appName) -{ - if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) { - char *cdir; - - *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1); - if (*appName == NULL) { - return configdir; - } - cdir = *appName; - while (*cdir && *cdir != ':') { - cdir++; - } - if (*cdir == ':') { - *cdir = 0; - cdir++; - } - configdir = cdir; - } - return configdir; -} - -static int rdbmapflags(int flags); -static rdbfunc lg_rdbfunc = NULL; -static rdbstatusfunc lg_rdbstatusfunc = NULL; - -/* NOTE: SHLIB_SUFFIX is defined on the command line */ -#define RDBLIB SHLIB_PREFIX"rdb."SHLIB_SUFFIX - -DB * rdbopen(const char *appName, const char *prefix, - const char *type, int flags, int *status) -{ - PRLibrary *lib; - DB *db; - char *disableUnload = NULL; - - if (lg_rdbfunc) { - db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags)); - if (!db && status && lg_rdbstatusfunc) { - *status = (*lg_rdbstatusfunc)(); - } - return db; - } - - /* - * try to open the library. - */ - lib = PR_LoadLibrary(RDBLIB); - - if (!lib) { - return NULL; - } - - /* get the entry points */ - lg_rdbstatusfunc = (rdbstatusfunc) PR_FindSymbol(lib,"rdbstatus"); - lg_rdbfunc = (rdbfunc) PR_FindSymbol(lib,"rdbopen"); - if (lg_rdbfunc) { - db = (*lg_rdbfunc)(appName,prefix,type,rdbmapflags(flags)); - if (!db && status && lg_rdbstatusfunc) { - *status = (*lg_rdbstatusfunc)(); - } - return db; - } - - /* couldn't find the entry point, unload the library and fail */ - disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD"); - if (!disableUnload) { - PR_UnloadLibrary(lib); - } - return NULL; -} - -/* - * the following data structures are from rdb.h. - */ -struct RDBStr { - DB db; - int (*xactstart)(DB *db); - int (*xactdone)(DB *db, PRBool abort); - int version; - int (*dbinitcomplete)(DB *db); -}; - -#define DB_RDB ((DBTYPE) 0xff) -#define RDB_RDONLY 1 -#define RDB_RDWR 2 -#define RDB_CREATE 4 - -static int -rdbmapflags(int flags) { - switch (flags) { - case NO_RDONLY: - return RDB_RDONLY; - case NO_RDWR: - return RDB_RDWR; - case NO_CREATE: - return RDB_CREATE; - default: - break; - } - return 0; -} - -PRBool -db_IsRDB(DB *db) -{ - return (PRBool) db->type == DB_RDB; -} - -int -db_BeginTransaction(DB *db) -{ - struct RDBStr *rdb = (struct RDBStr *)db; - if (db->type != DB_RDB) { - return 0; - } - - return rdb->xactstart(db); -} - -int -db_FinishTransaction(DB *db, PRBool abort) -{ - struct RDBStr *rdb = (struct RDBStr *)db; - if (db->type != DB_RDB) { - return 0; - } - - return rdb->xactdone(db, abort); -} - -static DB * -lg_getRawDB(SDB *sdb) -{ - NSSLOWCERTCertDBHandle *certDB; - NSSLOWKEYDBHandle *keyDB; - - certDB = lg_getCertDB(sdb); - if (certDB) { - return certDB->permCertDB; - } - keyDB = lg_getKeyDB(sdb); - if (keyDB) { - return keyDB->db; - } - return NULL; -} - -CK_RV -lg_Begin(SDB *sdb) -{ - DB *db = lg_getRawDB(sdb); - int ret; - - if (db == NULL) { - return CKR_GENERAL_ERROR; /* shouldn't happen */ - } - ret = db_BeginTransaction(db); - if (ret != 0) { - return CKR_GENERAL_ERROR; /* could happen */ - } - return CKR_OK; -} - -CK_RV -lg_Commit(SDB *sdb) -{ - DB *db = lg_getRawDB(sdb); - int ret; - - if (db == NULL) { - return CKR_GENERAL_ERROR; /* shouldn't happen */ - } - ret = db_FinishTransaction(db, PR_FALSE); - if (ret != 0) { - return CKR_GENERAL_ERROR; /* could happen */ - } - return CKR_OK; -} - -CK_RV -lg_Abort(SDB *sdb) -{ - DB *db = lg_getRawDB(sdb); - int ret; - - if (db == NULL) { - return CKR_GENERAL_ERROR; /* shouldn't happen */ - } - ret = db_FinishTransaction(db, PR_TRUE); - if (ret != 0) { - return CKR_GENERAL_ERROR; /* could happen */ - } - return CKR_OK; -} - -int -db_InitComplete(DB *db) -{ - struct RDBStr *rdb = (struct RDBStr *)db; - if (db->type != DB_RDB) { - return 0; - } - /* we should have added a version number to the RDBS structure. Since we - * didn't, we detect that we have and 'extended' structure if the rdbstatus - * func exists */ - if (!lg_rdbstatusfunc) { - return 0; - } - - return rdb->dbinitcomplete(db); -} - - - -SECStatus -db_Copy(DB *dest,DB *src) -{ - int ret; - DBT key,data; - ret = (*src->seq)(src, &key, &data, R_FIRST); - if (ret) { - return SECSuccess; - } - - do { - (void)(*dest->put)(dest,&key,&data, R_NOOVERWRITE); - } while ( (*src->seq)(src, &key, &data, R_NEXT) == 0); - (void)(*dest->sync)(dest,0); - - return SECSuccess; -} - - -static CK_RV -lg_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly, - NSSLOWCERTCertDBHandle **certdbPtr) -{ - NSSLOWCERTCertDBHandle *certdb = NULL; - CK_RV crv = CKR_NETSCAPE_CERTDB_FAILED; - SECStatus rv; - char * name = NULL; - char * appName = NULL; - - if (prefix == NULL) { - prefix = ""; - } - - configdir = lg_EvaluateConfigDir(configdir, &appName); - - name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix); - if (name == NULL) goto loser; - - certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle)); - if (certdb == NULL) - goto loser; - - certdb->ref = 1; -/* fix when we get the DB in */ - rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix, - lg_certdb_name_cb, (void *)name, PR_FALSE); - if (rv == SECSuccess) { - crv = CKR_OK; - *certdbPtr = certdb; - certdb = NULL; - } -loser: - if (certdb) PR_Free(certdb); - if (name) PR_smprintf_free(name); - if (appName) PORT_Free(appName); - return crv; -} - -static CK_RV -lg_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly, - NSSLOWKEYDBHandle **keydbPtr) -{ - NSSLOWKEYDBHandle *keydb; - char * name = NULL; - char * appName = NULL; - - if (prefix == NULL) { - prefix = ""; - } - configdir = lg_EvaluateConfigDir(configdir, &appName); - - name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix); - if (name == NULL) - return CKR_HOST_MEMORY; - keydb = nsslowkey_OpenKeyDB(readOnly, appName, prefix, - lg_keydb_name_cb, (void *)name); - PR_smprintf_free(name); - if (appName) PORT_Free(appName); - if (keydb == NULL) - return CKR_NETSCAPE_KEYDB_FAILED; - *keydbPtr = keydb; - - return CKR_OK; -} - -/* - * Accessors for the private parts of the sdb structure. - */ -void -lg_DBLock(SDB *sdb) -{ - LGPrivate *lgdb_p = (LGPrivate *)sdb->private; - SKIP_AFTER_FORK(PR_Lock(lgdb_p->dbLock)); -} - -void -lg_DBUnlock(SDB *sdb) -{ - LGPrivate *lgdb_p = (LGPrivate *)sdb->private; - SKIP_AFTER_FORK(PR_Unlock(lgdb_p->dbLock)); -} - -PLHashTable * -lg_GetHashTable(SDB *sdb) -{ - LGPrivate *lgdb_p = (LGPrivate *)sdb->private; - return lgdb_p->hashTable; -} - -NSSLOWCERTCertDBHandle * -lg_getCertDB(SDB *sdb) -{ - LGPrivate *lgdb_p = (LGPrivate *)sdb->private; - - return lgdb_p->certDB; -} - -NSSLOWKEYDBHandle * -lg_getKeyDB(SDB *sdb) -{ - LGPrivate *lgdb_p = (LGPrivate *)sdb->private; - - return lgdb_p->keyDB; -} - -PRBool parentForkedAfterC_Initialize; - -void lg_SetForkState(PRBool forked) -{ - parentForkedAfterC_Initialize = forked; -} - -CK_RV -lg_Close(SDB *sdb) -{ - LGPrivate *lgdb_p = (LGPrivate *)sdb->private; - lg_ClearTokenKeyHashTable(sdb); - if (lgdb_p) { - if (lgdb_p->certDB) { - nsslowcert_ClosePermCertDB(lgdb_p->certDB); - } else if (lgdb_p->keyDB) { - nsslowkey_CloseKeyDB(lgdb_p->keyDB); - } - if (lgdb_p->dbLock) { - SKIP_AFTER_FORK(PR_DestroyLock(lgdb_p->dbLock)); - } - if (lgdb_p->hashTable) { - PL_HashTableDestroy(lgdb_p->hashTable); - } - PORT_Free(lgdb_p); - } - PORT_Free(sdb); - return CKR_OK; -} - -static PLHashNumber -lg_HashNumber(const void *key) -{ - return (PLHashNumber) key; -} - -PRIntn -lg_CompareValues(const void *v1, const void *v2) -{ - PLHashNumber value1 = (PLHashNumber) v1; - PLHashNumber value2 = (PLHashNumber) v2; - return (value1 == value2); -} - -/* - * helper function to wrap a NSSLOWCERTCertDBHandle or a NSSLOWKEYDBHandle - * with and sdb structure. - */ -CK_RV -lg_init(SDB **pSdb, int flags, NSSLOWCERTCertDBHandle *certdbPtr, - NSSLOWKEYDBHandle *keydbPtr) -{ - SDB *sdb = NULL; - LGPrivate *lgdb_p = NULL; - CK_RV error = CKR_HOST_MEMORY; - - *pSdb = NULL; - sdb = (SDB *) PORT_Alloc(sizeof(SDB)); - if (sdb == NULL) { - goto loser; - } - lgdb_p = (LGPrivate *) PORT_Alloc(sizeof(LGPrivate)); - if (lgdb_p == NULL) { - goto loser; - } - /* invariant fields */ - lgdb_p->certDB = certdbPtr; - lgdb_p->keyDB = keydbPtr; - lgdb_p->dbLock = PR_NewLock(); - if (lgdb_p->dbLock == NULL) { - goto loser; - } - lgdb_p->hashTable = PL_NewHashTable(64, lg_HashNumber, lg_CompareValues, - SECITEM_HashCompare, NULL, 0); - if (lgdb_p->hashTable == NULL) { - goto loser; - } - - sdb->sdb_type = SDB_LEGACY; - sdb->sdb_flags = flags; - sdb->private = lgdb_p; - sdb->sdb_FindObjectsInit = lg_FindObjectsInit; - sdb->sdb_FindObjects = lg_FindObjects; - sdb->sdb_FindObjectsFinal = lg_FindObjectsFinal; - sdb->sdb_GetAttributeValue = lg_GetAttributeValue; - sdb->sdb_SetAttributeValue = lg_SetAttributeValue; - sdb->sdb_CreateObject = lg_CreateObject; - sdb->sdb_DestroyObject = lg_DestroyObject; - sdb->sdb_GetMetaData = lg_GetMetaData; - sdb->sdb_PutMetaData = lg_PutMetaData; - sdb->sdb_Begin = lg_Begin; - sdb->sdb_Commit = lg_Commit; - sdb->sdb_Abort = lg_Abort; - sdb->sdb_Reset = lg_Reset; - sdb->sdb_Close = lg_Close; - sdb->sdb_SetForkState = lg_SetForkState; - - *pSdb = sdb; - return CKR_OK; - -loser: - if (sdb) { - PORT_Free(sdb); - } - if (lgdb_p) { - if (lgdb_p->dbLock) { - PR_DestroyLock(lgdb_p->dbLock); - } - if (lgdb_p->hashTable) { - PL_HashTableDestroy(lgdb_p->hashTable); - } - PORT_Free(lgdb_p); - } - return error; - -} - -/* - * OK there are now lots of options here, lets go through them all: - * - * configdir - base directory where all the cert, key, and module datbases live. - * certPrefix - prefix added to the beginning of the cert database example: " - * "https-server1-" - * keyPrefix - prefix added to the beginning of the key database example: " - * "https-server1-" - * secmodName - name of the security module database (usually "secmod.db"). - * readOnly - Boolean: true if the databases are to be openned read only. - * nocertdb - Don't open the cert DB and key DB's, just initialize the - * Volatile certdb. - * nomoddb - Don't open the security module DB, just initialize the - * PKCS #11 module. - * forceOpen - Continue to force initializations even if the databases cannot - * be opened. - */ -CK_RV -legacy_Open(const char *configdir, const char *certPrefix, - const char *keyPrefix, int certVersion, int keyVersion, - int flags, SDB **certDB, SDB **keyDB) -{ - CK_RV crv = CKR_OK; - SECStatus rv; - PRBool readOnly = (flags == SDB_RDONLY)? PR_TRUE: PR_FALSE; - - rv = SECOID_Init(); - if (SECSuccess != rv) { - return CKR_DEVICE_ERROR; - } - nsslowcert_InitLocks(); - - if (keyDB) *keyDB = NULL; - if (certDB) *certDB = NULL; - - if (certDB) { - NSSLOWCERTCertDBHandle *certdbPtr; - - crv = lg_OpenCertDB(configdir, certPrefix, readOnly, &certdbPtr); - if (crv != CKR_OK) { - goto loser; - } - crv = lg_init(certDB, flags, certdbPtr, NULL); - if (crv != CKR_OK) { - nsslowcert_ClosePermCertDB(certdbPtr); - goto loser; - } - } - if (keyDB) { - NSSLOWKEYDBHandle *keydbPtr; - - crv = lg_OpenKeyDB(configdir, keyPrefix, readOnly, &keydbPtr); - if (crv != CKR_OK) { - goto loser; - } - crv = lg_init(keyDB, flags, NULL, keydbPtr); - if (crv != CKR_OK) { - nsslowkey_CloseKeyDB(keydbPtr); - goto loser; - } - if (certDB && *certDB) { - LGPrivate *lgdb_p = (LGPrivate *)(*certDB)->private; - lgdb_p->keyDB = keydbPtr; - } - } - -loser: - if (crv != CKR_OK) { - if (keyDB && *keyDB) { - lg_Close(*keyDB); - *keyDB = NULL; - } - if (certDB && *certDB) { - lg_Close(*certDB); - *certDB = NULL; - } - } - return crv; -} - -CK_RV -legacy_Shutdown(PRBool forked) -{ - lg_SetForkState(forked); - nsslowcert_DestroyFreeLists(); - nsslowcert_DestroyGlobalLocks(); - SECOID_Shutdown(); - lg_SetForkState(PR_FALSE); - return CKR_OK; -} - diff --git a/security/nss/lib/softoken/legacydb/lgutil.c b/security/nss/lib/softoken/legacydb/lgutil.c deleted file mode 100644 index f474b5fea..000000000 --- a/security/nss/lib/softoken/legacydb/lgutil.c +++ /dev/null @@ -1,424 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "lgdb.h" -#include "secerr.h" -#include "lgglue.h" - -/* - * ******************** Attribute Utilities ******************************* - */ - -/* - * look up and attribute structure from a type and Object structure. - * The returned attribute is referenced and needs to be freed when - * it is no longer needed. - */ -const CK_ATTRIBUTE * -lg_FindAttribute(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, - CK_ULONG count ) -{ - int i; - - for (i=0; i < count; i++) { - if (templ[i].type == type) { - return &templ[i]; - } - } - return NULL; -} - - -/* - * return true if object has attribute - */ -PRBool -lg_hasAttribute(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, - CK_ULONG count ) -{ - if (lg_FindAttribute(type, templ, count) == NULL) { - return PR_FALSE; - } - return PR_TRUE; -} - -/* - * copy an attribute into a SECItem. Secitem is allocated in the specified - * arena. - */ -CK_RV -lg_Attribute2SecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item) -{ - int len; - const CK_ATTRIBUTE *attribute; - - attribute = lg_FindAttribute(type, templ, count); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - len = attribute->ulValueLen; - - if (arena) { - item->data = (unsigned char *) PORT_ArenaAlloc(arena,len); - } else { - item->data = (unsigned char *) PORT_Alloc(len); - } - if (item->data == NULL) { - return CKR_HOST_MEMORY; - } - item->len = len; - PORT_Memcpy(item->data, attribute->pValue, len); - return CKR_OK; -} - - -/* - * copy an unsigned attribute into a SECItem. Secitem is allocated in - * the specified arena. - */ -CK_RV -lg_Attribute2SSecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item) -{ - const CK_ATTRIBUTE *attribute; - item->data = NULL; - - attribute = lg_FindAttribute(type, templ, count); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - - (void)SECITEM_AllocItem(arena, item, attribute->ulValueLen); - if (item->data == NULL) { - return CKR_HOST_MEMORY; - } - PORT_Memcpy(item->data, attribute->pValue, item->len); - return CKR_OK; -} - -/* - * copy an unsigned attribute into a SECItem. Secitem is allocated in - * the specified arena. - */ -CK_RV -lg_PrivAttr2SSecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item, SDB *sdbpw) -{ - const CK_ATTRIBUTE *attribute; - SECItem epki, *dest = NULL; - SECStatus rv; - - item->data = NULL; - - attribute = lg_FindAttribute(type, templ, count); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - - epki.data = attribute->pValue; - epki.len = attribute->ulValueLen; - - rv = lg_util_decrypt(sdbpw, &epki, &dest); - if (rv != SECSuccess) { - return CKR_USER_NOT_LOGGED_IN; - } - (void)SECITEM_AllocItem(arena, item, dest->len); - if (item->data == NULL) { - SECITEM_FreeItem(dest, PR_TRUE); - return CKR_HOST_MEMORY; - } - - PORT_Memcpy(item->data, dest->data, item->len); - SECITEM_FreeItem(dest, PR_TRUE); - return CKR_OK; -} - -CK_RV -lg_PrivAttr2SecItem(PLArenaPool *arena, CK_ATTRIBUTE_TYPE type, - const CK_ATTRIBUTE *templ, CK_ULONG count, - SECItem *item, SDB *sdbpw) -{ - return lg_PrivAttr2SSecItem(arena, type, templ, count, item, sdbpw); -} - -/* - * this is only valid for CK_BBOOL type attributes. Return the state - * of that attribute. - */ -PRBool -lg_isTrue(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - const CK_ATTRIBUTE *attribute; - PRBool tok = PR_FALSE; - - attribute=lg_FindAttribute(type, templ, count); - if (attribute == NULL) { return PR_FALSE; } - tok = (PRBool)(*(CK_BBOOL *)attribute->pValue); - - return tok; -} - -/* - * return a null terminated string from attribute 'type'. This string - * is allocated and needs to be freed with PORT_Free() When complete. - */ -char * -lg_getString(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, CK_ULONG count) -{ - const CK_ATTRIBUTE *attribute; - char *label = NULL; - - attribute = lg_FindAttribute(type, templ, count); - if (attribute == NULL) return NULL; - - if (attribute->pValue != NULL) { - label = (char *) PORT_Alloc(attribute->ulValueLen+1); - if (label == NULL) { - return NULL; - } - - PORT_Memcpy(label,attribute->pValue, attribute->ulValueLen); - label[attribute->ulValueLen] = 0; - } - return label; -} - -CK_RV -lg_GetULongAttribute(CK_ATTRIBUTE_TYPE type, const CK_ATTRIBUTE *templ, - CK_ULONG count, CK_ULONG *longData) -{ - const CK_ATTRIBUTE *attribute; - CK_ULONG value = 0; - const unsigned char *data; - int i; - - attribute = lg_FindAttribute(type, templ, count); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - - if (attribute->ulValueLen != 4) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - data = (const unsigned char *)attribute->pValue; - for (i=0; i < 4; i++) { - value |= (CK_ULONG)(data[i]) << ((3-i)*8); - } - - *longData = value; - return CKR_OK; -} - -/* - * ******************** Object Utilities ******************************* - */ - -SECStatus -lg_deleteTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle) -{ - SECItem *item; - PRBool rem; - PLHashTable *hashTable= lg_GetHashTable(sdb); - - item = (SECItem *)PL_HashTableLookup(hashTable, (void *)handle); - rem = PL_HashTableRemove(hashTable,(void *)handle) ; - if (rem && item) { - SECITEM_FreeItem(item,PR_TRUE); - } - return rem ? SECSuccess : SECFailure; -} - -/* must be called holding lg_DBLock(sdb) */ -static SECStatus -lg_addTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle, SECItem *key) -{ - PLHashEntry *entry; - SECItem *item; - PLHashTable *hashTable= lg_GetHashTable(sdb); - - item = SECITEM_DupItem(key); - if (item == NULL) { - return SECFailure; - } - entry = PL_HashTableAdd(hashTable,(void *)handle,item); - if (entry == NULL) { - SECITEM_FreeItem(item,PR_TRUE); - return SECFailure; - } - return SECSuccess; -} - -/* must be called holding lg_DBLock(sdb) */ -const SECItem * -lg_lookupTokenKeyByHandle(SDB *sdb, CK_OBJECT_HANDLE handle) -{ - PLHashTable *hashTable= lg_GetHashTable(sdb); - return (const SECItem *)PL_HashTableLookup(hashTable, (void *)handle); -} - - -static PRIntn -lg_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg) -{ - SECItem *item = (SECItem *)entry->value; - - SECITEM_FreeItem(item, PR_TRUE); - return HT_ENUMERATE_NEXT; -} - -CK_RV -lg_ClearTokenKeyHashTable(SDB *sdb) -{ - PLHashTable *hashTable; - lg_DBLock(sdb); - hashTable= lg_GetHashTable(sdb); - PL_HashTableEnumerateEntries(hashTable, lg_freeHashItem, NULL); - lg_DBUnlock(sdb); - return CKR_OK; -} - -/* - * handle Token Object stuff - */ -static void -lg_XORHash(unsigned char *key, unsigned char *dbkey, int len) -{ - int i; - - PORT_Memset(key, 0, 4); - - for (i=0; i < len-4; i += 4) { - key[0] ^= dbkey[i]; - key[1] ^= dbkey[i+1]; - key[2] ^= dbkey[i+2]; - key[3] ^= dbkey[i+3]; - } -} - -/* Make a token handle for an object and record it so we can find it again */ -CK_OBJECT_HANDLE -lg_mkHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class) -{ - unsigned char hashBuf[4]; - CK_OBJECT_HANDLE handle; - const SECItem *key; - - handle = class; - /* there is only one KRL, use a fixed handle for it */ - if (handle != LG_TOKEN_KRL_HANDLE) { - lg_XORHash(hashBuf,dbKey->data,dbKey->len); - handle = (hashBuf[0] << 24) | (hashBuf[1] << 16) | - (hashBuf[2] << 8) | hashBuf[3]; - handle = class | (handle & ~(LG_TOKEN_TYPE_MASK|LG_TOKEN_MASK)); - /* we have a CRL who's handle has randomly matched the reserved KRL - * handle, increment it */ - if (handle == LG_TOKEN_KRL_HANDLE) { - handle++; - } - } - - lg_DBLock(sdb); - while ((key = lg_lookupTokenKeyByHandle(sdb,handle)) != NULL) { - if (SECITEM_ItemsAreEqual(key,dbKey)) { - lg_DBUnlock(sdb); - return handle; - } - handle++; - } - lg_addTokenKeyByHandle(sdb,handle,dbKey); - lg_DBUnlock(sdb); - return handle; -} - -PRBool -lg_poisonHandle(SDB *sdb, SECItem *dbKey, CK_OBJECT_HANDLE class) -{ - unsigned char hashBuf[4]; - CK_OBJECT_HANDLE handle; - const SECItem *key; - - handle = class; - /* there is only one KRL, use a fixed handle for it */ - if (handle != LG_TOKEN_KRL_HANDLE) { - lg_XORHash(hashBuf,dbKey->data,dbKey->len); - handle = (hashBuf[0] << 24) | (hashBuf[1] << 16) | - (hashBuf[2] << 8) | hashBuf[3]; - handle = class | (handle & ~(LG_TOKEN_TYPE_MASK|LG_TOKEN_MASK)); - /* we have a CRL who's handle has randomly matched the reserved KRL - * handle, increment it */ - if (handle == LG_TOKEN_KRL_HANDLE) { - handle++; - } - } - lg_DBLock(sdb); - while ((key = lg_lookupTokenKeyByHandle(sdb,handle)) != NULL) { - if (SECITEM_ItemsAreEqual(key,dbKey)) { - key->data[0] ^= 0x80; - lg_DBUnlock(sdb); - return PR_TRUE; - } - handle++; - } - lg_DBUnlock(sdb); - return PR_FALSE; -} - -static LGEncryptFunc lg_encrypt_stub = NULL; -static LGDecryptFunc lg_decrypt_stub = NULL; - -void -legacy_SetCryptFunctions(LGEncryptFunc enc, LGDecryptFunc dec) -{ - lg_encrypt_stub = enc; - lg_decrypt_stub = dec; -} - -SECStatus lg_util_encrypt(PLArenaPool *arena, SDB *sdb, - SECItem *plainText, SECItem **cipherText) -{ - if (lg_encrypt_stub == NULL) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - return (*lg_encrypt_stub)(arena, sdb, plainText, cipherText); -} - -SECStatus lg_util_decrypt(SDB *sdb, SECItem *cipherText, SECItem **plainText) -{ - if (lg_decrypt_stub == NULL) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - return (*lg_decrypt_stub)(sdb, cipherText, plainText); -} - - diff --git a/security/nss/lib/softoken/legacydb/lowcert.c b/security/nss/lib/softoken/legacydb/lowcert.c deleted file mode 100644 index 143999045..000000000 --- a/security/nss/lib/softoken/legacydb/lowcert.c +++ /dev/null @@ -1,827 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Certificate handling code - * - * $Id$ - */ - -#include "seccomon.h" -#include "secder.h" -#include "nssilock.h" -#include "lowkeyi.h" -#include "secasn1.h" -#include "secoid.h" -#include "secerr.h" -#include "pcert.h" - -SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) - -static const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSLOWCERTSubjectPublicKeyInfo,algorithm), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_BIT_STRING, - offsetof(NSSLOWCERTSubjectPublicKeyInfo,subjectPublicKey), }, - { 0, } -}; - -static const SEC_ASN1Template nsslowcert_RSAPublicKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.modulus), }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.rsa.publicExponent), }, - { 0, } -}; -static const SEC_ASN1Template nsslowcert_DSAPublicKeyTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dsa.publicValue), }, - { 0, } -}; -static const SEC_ASN1Template nsslowcert_DHPublicKeyTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey,u.dh.publicValue), }, - { 0, } -}; - -/* - * 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_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk) -{ - pubk->u.rsa.modulus.type = siUnsignedInteger; - pubk->u.rsa.publicExponent.type = siUnsignedInteger; -} - -static void -prepare_low_dsa_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk) -{ - pubk->u.dsa.publicValue.type = siUnsignedInteger; - pubk->u.dsa.params.prime.type = siUnsignedInteger; - pubk->u.dsa.params.subPrime.type = siUnsignedInteger; - pubk->u.dsa.params.base.type = siUnsignedInteger; -} - -static void -prepare_low_dh_pub_key_for_asn1(NSSLOWKEYPublicKey *pubk) -{ - pubk->u.dh.prime.type = siUnsignedInteger; - pubk->u.dh.base.type = siUnsignedInteger; - pubk->u.dh.publicValue.type = siUnsignedInteger; -} - -/* - * simple cert decoder to avoid the cost of asn1 engine - */ -static unsigned char * -nsslowcert_dataStart(unsigned char *buf, unsigned int length, - unsigned int *data_length, PRBool includeTag, - unsigned char* rettag) { - unsigned char tag; - unsigned int used_length= 0; - - tag = buf[used_length++]; - - if (rettag) { - *rettag = tag; - } - - /* blow out when we come to the end */ - if (tag == 0) { - return NULL; - } - - *data_length = buf[used_length++]; - - if (*data_length&0x80) { - int len_count = *data_length & 0x7f; - - *data_length = 0; - - while (len_count-- > 0) { - *data_length = (*data_length << 8) | buf[used_length++]; - } - } - - if (*data_length > (length-used_length) ) { - *data_length = length-used_length; - return NULL; - } - if (includeTag) *data_length += used_length; - - return (buf + (includeTag ? 0 : used_length)); -} - -static void SetTimeType(SECItem* item, unsigned char tagtype) -{ - switch (tagtype) { - case SEC_ASN1_UTC_TIME: - item->type = siUTCTime; - break; - - case SEC_ASN1_GENERALIZED_TIME: - item->type = siGeneralizedTime; - break; - - default: - PORT_Assert(0); - break; - } -} - -static int -nsslowcert_GetValidityFields(unsigned char *buf,int buf_length, - SECItem *notBefore, SECItem *notAfter) -{ - unsigned char tagtype; - notBefore->data = nsslowcert_dataStart(buf,buf_length, - ¬Before->len,PR_FALSE, &tagtype); - if (notBefore->data == NULL) return SECFailure; - SetTimeType(notBefore, tagtype); - buf_length -= (notBefore->data-buf) + notBefore->len; - buf = notBefore->data + notBefore->len; - notAfter->data = nsslowcert_dataStart(buf,buf_length, - ¬After->len,PR_FALSE, &tagtype); - if (notAfter->data == NULL) return SECFailure; - SetTimeType(notAfter, tagtype); - return SECSuccess; -} - -static int -nsslowcert_GetCertFields(unsigned char *cert,int cert_length, - SECItem *issuer, SECItem *serial, SECItem *derSN, SECItem *subject, - SECItem *valid, SECItem *subjkey, SECItem *extensions) -{ - unsigned char *buf; - unsigned int buf_length; - unsigned char *dummy; - unsigned int dummylen; - - /* get past the signature wrap */ - buf = nsslowcert_dataStart(cert,cert_length,&buf_length,PR_FALSE, NULL); - if (buf == NULL) return SECFailure; - /* get into the raw cert data */ - buf = nsslowcert_dataStart(buf,buf_length,&buf_length,PR_FALSE, NULL); - if (buf == NULL) return SECFailure; - /* skip past any optional version number */ - if ((buf[0] & 0xa0) == 0xa0) { - dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL); - if (dummy == NULL) return SECFailure; - buf_length -= (dummy-buf) + dummylen; - buf = dummy + dummylen; - } - /* serial number */ - if (derSN) { - derSN->data=nsslowcert_dataStart(buf,buf_length,&derSN->len,PR_TRUE, NULL); - } - serial->data = nsslowcert_dataStart(buf,buf_length,&serial->len,PR_FALSE, NULL); - if (serial->data == NULL) return SECFailure; - buf_length -= (serial->data-buf) + serial->len; - buf = serial->data + serial->len; - /* skip the OID */ - dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL); - if (dummy == NULL) return SECFailure; - buf_length -= (dummy-buf) + dummylen; - buf = dummy + dummylen; - /* issuer */ - issuer->data = nsslowcert_dataStart(buf,buf_length,&issuer->len,PR_TRUE, NULL); - if (issuer->data == NULL) return SECFailure; - buf_length -= (issuer->data-buf) + issuer->len; - buf = issuer->data + issuer->len; - - /* only wanted issuer/SN */ - if (valid == NULL) { - return SECSuccess; - } - /* validity */ - valid->data = nsslowcert_dataStart(buf,buf_length,&valid->len,PR_FALSE, NULL); - if (valid->data == NULL) return SECFailure; - buf_length -= (valid->data-buf) + valid->len; - buf = valid->data + valid->len; - /*subject */ - subject->data=nsslowcert_dataStart(buf,buf_length,&subject->len,PR_TRUE, NULL); - if (subject->data == NULL) return SECFailure; - buf_length -= (subject->data-buf) + subject->len; - buf = subject->data + subject->len; - /* subject key info */ - subjkey->data=nsslowcert_dataStart(buf,buf_length,&subjkey->len,PR_TRUE, NULL); - if (subjkey->data == NULL) return SECFailure; - buf_length -= (subjkey->data-buf) + subjkey->len; - buf = subjkey->data + subjkey->len; - - extensions->data = NULL; - extensions->len = 0; - while (buf_length > 0) { - /* EXTENSIONS */ - if (buf[0] == 0xa3) { - extensions->data = nsslowcert_dataStart(buf,buf_length, - &extensions->len, PR_FALSE, NULL); - break; - } - dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE,NULL); - if (dummy == NULL) return SECFailure; - buf_length -= (dummy - buf) + dummylen; - buf = dummy + dummylen; - } - return SECSuccess; -} - -static SECStatus -nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *notAfter) -{ - int rv; - NSSLOWCERTValidity validity; - - rv = nsslowcert_GetValidityFields(c->validity.data,c->validity.len, - &validity.notBefore,&validity.notAfter); - if (rv != SECSuccess) { - return rv; - } - - /* convert DER not-before time */ - rv = DER_DecodeTimeChoice(notBefore, &validity.notBefore); - if (rv) { - return(SECFailure); - } - - /* convert DER not-after time */ - rv = DER_DecodeTimeChoice(notAfter, &validity.notAfter); - if (rv) { - return(SECFailure); - } - - return(SECSuccess); -} - -/* - * is certa newer than certb? If one is expired, pick the other one. - */ -PRBool -nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb) -{ - PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now; - SECStatus rv; - PRBool newerbefore, newerafter; - - rv = nsslowcert_GetCertTimes(certa, ¬BeforeA, ¬AfterA); - if ( rv != SECSuccess ) { - return(PR_FALSE); - } - - rv = nsslowcert_GetCertTimes(certb, ¬BeforeB, ¬AfterB); - if ( rv != SECSuccess ) { - return(PR_TRUE); - } - - newerbefore = PR_FALSE; - if ( LL_CMP(notBeforeA, >, notBeforeB) ) { - newerbefore = PR_TRUE; - } - - newerafter = PR_FALSE; - if ( LL_CMP(notAfterA, >, notAfterB) ) { - newerafter = PR_TRUE; - } - - if ( newerbefore && newerafter ) { - return(PR_TRUE); - } - - if ( ( !newerbefore ) && ( !newerafter ) ) { - return(PR_FALSE); - } - - /* get current time */ - now = PR_Now(); - - if ( newerbefore ) { - /* cert A was issued after cert B, but expires sooner */ - /* if A is expired, then pick B */ - if ( LL_CMP(notAfterA, <, now ) ) { - return(PR_FALSE); - } - return(PR_TRUE); - } else { - /* cert B was issued after cert A, but expires sooner */ - /* if B is expired, then pick A */ - if ( LL_CMP(notAfterB, <, now ) ) { - return(PR_TRUE); - } - return(PR_FALSE); - } -} - -#define SOFT_DEFAULT_CHUNKSIZE 2048 - -static SECStatus -nsslowcert_KeyFromIssuerAndSN(PRArenaPool *arena, - SECItem *issuer, SECItem *sn, SECItem *key) -{ - unsigned int len = sn->len + issuer->len; - - if (!arena) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto loser; - } - key->data = (unsigned char*)PORT_ArenaAlloc(arena, len); - if ( !key->data ) { - goto loser; - } - - key->len = len; - /* 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); -} - -static SECStatus -nsslowcert_KeyFromIssuerAndSNStatic(unsigned char *space, - int spaceLen, SECItem *issuer, SECItem *sn, SECItem *key) -{ - unsigned int len = sn->len + issuer->len; - - key->data = pkcs11_allocStaticData(len, space, spaceLen); - if ( !key->data ) { - goto loser; - } - - key->len = len; - /* 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); -} - - -static char * -nsslowcert_EmailName(SECItem *derDN, char *space, unsigned int len) -{ - unsigned char *buf; - unsigned int buf_length; - - /* unwrap outer sequence */ - buf=nsslowcert_dataStart(derDN->data,derDN->len,&buf_length,PR_FALSE,NULL); - if (buf == NULL) return NULL; - - /* Walk each RDN */ - while (buf_length > 0) { - unsigned char *rdn; - unsigned int rdn_length; - - /* grab next rdn */ - rdn=nsslowcert_dataStart(buf, buf_length, &rdn_length, PR_FALSE, NULL); - if (rdn == NULL) { return NULL; } - buf_length -= (rdn - buf) + rdn_length; - buf = rdn+rdn_length; - - while (rdn_length > 0) { - unsigned char *ava; - unsigned int ava_length; - unsigned char *oid; - unsigned int oid_length; - unsigned char *name; - unsigned int name_length; - SECItem oidItem; - SECOidTag type; - - /* unwrap the ava */ - ava=nsslowcert_dataStart(rdn, rdn_length, &ava_length, PR_FALSE, - NULL); - if (ava == NULL) return NULL; - rdn_length -= (ava-rdn)+ava_length; - rdn = ava + ava_length; - - oid=nsslowcert_dataStart(ava, ava_length, &oid_length, PR_FALSE, - NULL); - if (oid == NULL) { return NULL; } - ava_length -= (oid-ava)+oid_length; - ava = oid+oid_length; - - name=nsslowcert_dataStart(ava, ava_length, &name_length, PR_FALSE, - NULL); - if (oid == NULL) { return NULL; } - ava_length -= (name-ava)+name_length; - ava = name+name_length; - - oidItem.data = oid; - oidItem.len = oid_length; - type = SECOID_FindOIDTag(&oidItem); - if ((type == SEC_OID_PKCS9_EMAIL_ADDRESS) || - (type == SEC_OID_RFC1274_MAIL)) { - /* Email is supposed to be IA5String, so no - * translation necessary */ - char *emailAddr; - emailAddr = (char *)pkcs11_copyStaticData(name,name_length+1, - (unsigned char *)space,len); - if (emailAddr) { - emailAddr[name_length] = 0; - } - return emailAddr; - } - } - } - return NULL; -} - -static char * -nsslowcert_EmailAltName(NSSLOWCERTCertificate *cert, char *space, - unsigned int len) -{ - unsigned char *exts; - unsigned int exts_length; - - /* unwrap the sequence */ - exts = nsslowcert_dataStart(cert->extensions.data, cert->extensions.len, - &exts_length, PR_FALSE, NULL); - /* loop through extension */ - while (exts && exts_length > 0) { - unsigned char * ext; - unsigned int ext_length; - unsigned char *oid; - unsigned int oid_length; - unsigned char *nameList; - unsigned int nameList_length; - SECItem oidItem; - SECOidTag type; - - ext = nsslowcert_dataStart(exts, exts_length, &ext_length, - PR_FALSE, NULL); - if (ext == NULL) { break; } - exts_length -= (ext - exts) + ext_length; - exts = ext+ext_length; - - oid=nsslowcert_dataStart(ext, ext_length, &oid_length, PR_FALSE, NULL); - if (oid == NULL) { break; } - ext_length -= (oid - ext) + oid_length; - ext = oid+oid_length; - oidItem.data = oid; - oidItem.len = oid_length; - type = SECOID_FindOIDTag(&oidItem); - - /* get Alt Extension */ - if (type != SEC_OID_X509_SUBJECT_ALT_NAME) { - continue; - } - - /* skip passed the critical flag */ - if (ext[0] == 0x01) { /* BOOLEAN */ - unsigned char *dummy; - unsigned int dummy_length; - dummy = nsslowcert_dataStart(ext, ext_length, &dummy_length, - PR_FALSE, NULL); - if (dummy == NULL) { break; } - ext_length -= (dummy - ext) + dummy_length; - ext = dummy+dummy_length; - } - - - /* unwrap the name list */ - nameList = nsslowcert_dataStart(ext, ext_length, &nameList_length, - PR_FALSE, NULL); - if (nameList == NULL) { break; } - ext_length -= (nameList - ext) + nameList_length; - ext = nameList+nameList_length; - nameList = nsslowcert_dataStart(nameList, nameList_length, - &nameList_length, PR_FALSE, NULL); - /* loop through the name list */ - while (nameList && nameList_length > 0) { - unsigned char *thisName; - unsigned int thisName_length; - - thisName = nsslowcert_dataStart(nameList, nameList_length, - &thisName_length, PR_FALSE, NULL); - if (thisName == NULL) { break; } - if (nameList[0] == 0xa2) { /* DNS Name */ - SECItem dn; - char *emailAddr; - - dn.data = thisName; - dn.len = thisName_length; - emailAddr = nsslowcert_EmailName(&dn, space, len); - if (emailAddr) { - return emailAddr; - } - } - if (nameList[0] == 0x81) { /* RFC 822name */ - char *emailAddr; - emailAddr = (char *)pkcs11_copyStaticData(thisName, - thisName_length+1, (unsigned char *)space,len); - if (emailAddr) { - emailAddr[thisName_length] = 0; - } - return emailAddr; - } - nameList_length -= (thisName-nameList) + thisName_length; - nameList = thisName + thisName_length; - } - break; - } - return NULL; -} - -static char * -nsslowcert_GetCertificateEmailAddress(NSSLOWCERTCertificate *cert) -{ - char *emailAddr = NULL; - char *str; - - emailAddr = nsslowcert_EmailName(&cert->derSubject,cert->emailAddrSpace, - sizeof(cert->emailAddrSpace)); - /* couldn't find the email address in the DN, check the subject Alt name */ - if (!emailAddr && cert->extensions.data) { - emailAddr = nsslowcert_EmailAltName(cert, cert->emailAddrSpace, - sizeof(cert->emailAddrSpace)); - } - - - /* make it lower case */ - str = emailAddr; - while ( str && *str ) { - *str = tolower( *str ); - str++; - } - return emailAddr; - -} - -/* - * take a DER certificate and decode it into a certificate structure - */ -NSSLOWCERTCertificate * -nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, char *nickname) -{ - NSSLOWCERTCertificate *cert; - int rv; - - /* allocate the certificate structure */ - cert = nsslowcert_CreateCert(); - - if ( !cert ) { - goto loser; - } - - /* point to passed in DER data */ - cert->derCert = *derSignedCert; - cert->nickname = NULL; - cert->certKey.data = NULL; - cert->referenceCount = 1; - - /* decode the certificate info */ - rv = nsslowcert_GetCertFields(cert->derCert.data, cert->derCert.len, - &cert->derIssuer, &cert->serialNumber, &cert->derSN, &cert->derSubject, - &cert->validity, &cert->derSubjKeyInfo, &cert->extensions); - - /* cert->subjectKeyID; x509v3 subject key identifier */ - cert->subjectKeyID.data = NULL; - cert->subjectKeyID.len = 0; - cert->dbEntry = NULL; - cert ->trust = NULL; - cert ->dbhandle = NULL; - - /* generate and save the database key for the cert */ - rv = nsslowcert_KeyFromIssuerAndSNStatic(cert->certKeySpace, - sizeof(cert->certKeySpace), &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 */ - cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace, - sizeof(cert->nicknameSpace)); - } - -#ifdef FIXME - /* initialize the subjectKeyID */ - rv = cert_GetKeyID(cert); - if ( rv != SECSuccess ) { - goto loser; - } -#endif - - /* set the email address */ - cert->emailAddr = nsslowcert_GetCertificateEmailAddress(cert); - - - cert->referenceCount = 1; - - return(cert); - -loser: - if (cert) { - nsslowcert_DestroyCertificate(cert); - } - - return(0); -} - -char * -nsslowcert_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); -} - - -/* - * Generate a database key, based on serial number and issuer, from a - * DER certificate. - */ -SECStatus -nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key) -{ - int rv; - NSSLOWCERTCertKey certkey; - - PORT_Memset(&certkey, 0, sizeof(NSSLOWCERTCertKey)); - - rv = nsslowcert_GetCertFields(derCert->data, derCert->len, - &certkey.derIssuer, &certkey.serialNumber, NULL, NULL, - NULL, NULL, NULL); - - if ( rv ) { - goto loser; - } - - return(nsslowcert_KeyFromIssuerAndSN(arena, &certkey.derIssuer, - &certkey.serialNumber, key)); -loser: - return(SECFailure); -} - -NSSLOWKEYPublicKey * -nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *cert) -{ - NSSLOWCERTSubjectPublicKeyInfo spki; - NSSLOWKEYPublicKey *pubk; - SECItem os; - SECStatus rv; - PRArenaPool *arena; - SECOidTag tag; - SECItem newDerSubjKeyInfo; - - arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) - return NULL; - - pubk = (NSSLOWKEYPublicKey *) - PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPublicKey)); - if (pubk == NULL) { - PORT_FreeArena (arena, PR_FALSE); - return NULL; - } - - pubk->arena = arena; - PORT_Memset(&spki,0,sizeof(spki)); - - /* copy the DER into the arena, since Quick DER returns data that points - into the DER input, which may get freed by the caller */ - rv = SECITEM_CopyItem(arena, &newDerSubjKeyInfo, &cert->derSubjKeyInfo); - if ( rv != SECSuccess ) { - PORT_FreeArena (arena, PR_FALSE); - return NULL; - } - - /* we haven't bothered decoding the spki struct yet, do it now */ - rv = SEC_QuickDERDecodeItem(arena, &spki, - nsslowcert_SubjectPublicKeyInfoTemplate, &newDerSubjKeyInfo); - if (rv != SECSuccess) { - PORT_FreeArena (arena, PR_FALSE); - return NULL; - } - - /* 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 = NSSLOWKEYRSAKey; - prepare_low_rsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, - nsslowcert_RSAPublicKeyTemplate, &os); - if (rv == SECSuccess) - return pubk; - break; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - pubk->keyType = NSSLOWKEYDSAKey; - prepare_low_dsa_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, - nsslowcert_DSAPublicKeyTemplate, &os); - if (rv == SECSuccess) return pubk; - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: - pubk->keyType = NSSLOWKEYDHKey; - prepare_low_dh_pub_key_for_asn1(pubk); - rv = SEC_QuickDERDecodeItem(arena, pubk, - nsslowcert_DHPublicKeyTemplate, &os); - if (rv == SECSuccess) return pubk; - break; -#ifdef NSS_ENABLE_ECC - case SEC_OID_ANSIX962_EC_PUBLIC_KEY: - pubk->keyType = NSSLOWKEYECKey; - /* Since PKCS#11 directly takes the DER encoding of EC params - * and public value, we don't need any decoding here. - */ - rv = SECITEM_CopyItem(arena, &pubk->u.ec.ecParams.DEREncoding, - &spki.algorithm.parameters); - if ( rv != SECSuccess ) - break; - - /* Fill out the rest of the ecParams structure - * based on the encoded params - */ - if (LGEC_FillParams(arena, &pubk->u.ec.ecParams.DEREncoding, - &pubk->u.ec.ecParams) != SECSuccess) - break; - - rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, &os); - if (rv == SECSuccess) return pubk; - break; -#endif /* NSS_ENABLE_ECC */ - default: - rv = SECFailure; - break; - } - - nsslowkey_DestroyPublicKey (pubk); - return NULL; -} - diff --git a/security/nss/lib/softoken/legacydb/lowkey.c b/security/nss/lib/softoken/legacydb/lowkey.c deleted file mode 100644 index 5ee64d1f2..000000000 --- a/security/nss/lib/softoken/legacydb/lowkey.c +++ /dev/null @@ -1,468 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "lowkeyi.h" -#include "secoid.h" -#include "secitem.h" -#include "secder.h" -#include "secasn1.h" -#include "secerr.h" - -SEC_ASN1_MKSUB(SEC_AnyTemplate) -SEC_ASN1_MKSUB(SEC_BitStringTemplate) -SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) -SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) - -static const SEC_ASN1Template nsslowkey_AttributeTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSLOWKEYAttribute) }, - { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) }, - { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue), - SEC_ASN1_SUB(SEC_AnyTemplate) }, - { 0 } -}; - -static const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = { - { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate }, -}; -/* ASN1 Templates for new decoder/encoder */ -const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) }, - { SEC_ASN1_INTEGER, - offsetof(NSSLOWKEYPrivateKeyInfo,version) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSLOWKEYPrivateKeyInfo,algorithm), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSLOWKEYPrivateKeyInfo, attributes), - nsslowkey_SetOfAttributeTemplate }, - { 0 } -}; - -const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) }, - { SEC_ASN1_INTEGER, offsetof(PQGParams,prime) }, - { SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) }, - { SEC_ASN1_INTEGER, offsetof(PQGParams,base) }, - { 0, } -}; - -const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) }, - { 0 } -}; - - -const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) }, - { 0, } -}; - -const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) }, -}; - -const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) }, - { 0, } -}; - -#ifdef NSS_ENABLE_ECC - -/* XXX This is just a placeholder for later when we support - * generic curves and need full-blown support for parsing EC - * parameters. For now, we only support named curves in which - * EC params are simply encoded as an object ID and we don't - * use nsslowkey_ECParamsTemplate. - */ -const SEC_ASN1Template nsslowkey_ECParamsTemplate[] = { - { SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) }, - { SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named }, - { 0, } -}; - - -/* NOTE: The SECG specification allows the private key structure - * to contain curve parameters but recommends that they be stored - * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo - * instead. - */ -const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) }, - /* XXX The following template works for now since we only - * support named curves for which the parameters are - * encoded as an object ID. When we support generic curves, - * we'll need to define nsslowkey_ECParamsTemplate - */ -#if 1 - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, - offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID), - SEC_ASN1_SUB(SEC_ObjectIDTemplate) }, -#else - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams), - nsslowkey_ECParamsTemplate }, -#endif - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue), - SEC_ASN1_SUB(SEC_BitStringTemplate) }, - { 0, } -}; - - -/* - * smaller version of EC_FillParams. In this code, we only need - * oid and DER data. - */ -SECStatus -LGEC_FillParams(PRArenaPool *arena, const SECItem *encodedParams, - ECParams *params) -{ - SECOidTag tag; - SECItem oid = { siBuffer, NULL, 0}; - -#if EC_DEBUG - int i; - - printf("Encoded params in EC_DecodeParams: "); - for (i = 0; i < encodedParams->len; i++) { - printf("%02x:", encodedParams->data[i]); - } - printf("\n"); -#endif - - oid.len = encodedParams->len - 2; - oid.data = encodedParams->data + 2; - if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) || - ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) { - PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); - return SECFailure; - } - - params->arena = arena; - - /* For named curves, fill out curveOID */ - params->curveOID.len = oid.len; - params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len); - if (params->curveOID.data == NULL) { - return SECFailure; - } - memcpy(params->curveOID.data, oid.data, oid.len); - - return SECSuccess; -} - -/* Copy all of the fields from srcParams into dstParams - */ -SECStatus -LGEC_CopyParams(PRArenaPool *arena, ECParams *dstParams, - const ECParams *srcParams) -{ - SECStatus rv = SECFailure; - - dstParams->arena = arena; - rv = SECITEM_CopyItem(arena, &dstParams->DEREncoding, - &srcParams->DEREncoding); - if (rv != SECSuccess) { - goto loser; - } - rv =SECITEM_CopyItem(arena, &dstParams->curveOID, - &srcParams->curveOID); - if (rv != SECSuccess) { - goto loser; - } - - return SECSuccess; - -loser: - return SECFailure; -} -#endif /* NSS_ENABLE_ECC */ -/* - * 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. - */ - -void -prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *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; -} - -void -prepare_low_pqg_params_for_asn1(PQGParams *params) -{ - params->prime.type = siUnsignedInteger; - params->subPrime.type = siUnsignedInteger; - params->base.type = siUnsignedInteger; -} - -void -prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.dsa.publicValue.type = siUnsignedInteger; - 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; -} - -void -prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.dsa.privateValue.type = siUnsignedInteger; -} - -void -prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.dh.prime.type = siUnsignedInteger; - key->u.dh.base.type = siUnsignedInteger; - key->u.dh.publicValue.type = siUnsignedInteger; - key->u.dh.privateValue.type = siUnsignedInteger; -} - -#ifdef NSS_ENABLE_ECC -void -prepare_low_ecparams_for_asn1(ECParams *params) -{ - params->DEREncoding.type = siUnsignedInteger; - params->curveOID.type = siUnsignedInteger; -} - -void -prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.ec.version.type = siUnsignedInteger; - key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger; - key->u.ec.ecParams.curveOID.type = siUnsignedInteger; - key->u.ec.privateValue.type = siUnsignedInteger; - key->u.ec.publicValue.type = siUnsignedInteger; -} -#endif /* NSS_ENABLE_ECC */ - -void -nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) -{ - if (privk && privk->arena) { - PORT_FreeArena(privk->arena, PR_TRUE); - } -} - -void -nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk) -{ - if (pubk && pubk->arena) { - PORT_FreeArena(pubk->arena, PR_FALSE); - } -} -unsigned -nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk) -{ - unsigned char b0; - - /* interpret modulus length as key strength... in - * fortezza that's the public key length */ - - switch (pubk->keyType) { - case NSSLOWKEYRSAKey: - b0 = pubk->u.rsa.modulus.data[0]; - return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; - default: - break; - } - return 0; -} - -unsigned -nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk) -{ - - unsigned char b0; - - switch (privk->keyType) { - case NSSLOWKEYRSAKey: - b0 = privk->u.rsa.modulus.data[0]; - return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1; - default: - break; - } - return 0; -} - -NSSLOWKEYPublicKey * -nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) -{ - NSSLOWKEYPublicKey *pubk; - PLArenaPool *arena; - - - arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - switch(privk->keyType) { - case NSSLOWKEYRSAKey: - case NSSLOWKEYNullKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof (NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - if (privk->keyType == NSSLOWKEYNullKey) return pubk; - rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus, - &privk->u.rsa.modulus); - if (rv == SECSuccess) { - rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent, - &privk->u.rsa.publicExponent); - if (rv == SECSuccess) - return pubk; - } - } else { - PORT_SetError (SEC_ERROR_NO_MEMORY); - } - break; - case NSSLOWKEYDSAKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue, - &privk->u.dsa.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime, - &privk->u.dsa.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime, - &privk->u.dsa.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base, - &privk->u.dsa.params.base); - if (rv == SECSuccess) return pubk; - } - break; - case NSSLOWKEYDHKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue, - &privk->u.dh.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime, - &privk->u.dh.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dh.base, - &privk->u.dh.base); - if (rv == SECSuccess) return pubk; - } - break; -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, - &privk->u.ec.publicValue); - if (rv != SECSuccess) break; - pubk->u.ec.ecParams.arena = arena; - /* Copy the rest of the params */ - rv = LGEC_CopyParams(arena, &(pubk->u.ec.ecParams), - &(privk->u.ec.ecParams)); - if (rv == SECSuccess) return pubk; - } - break; -#endif /* NSS_ENABLE_ECC */ - /* No Fortezza in Low Key implementations (Fortezza keys aren't - * stored in our data base */ - default: - break; - } - - PORT_FreeArena (arena, PR_FALSE); - return NULL; -} - diff --git a/security/nss/lib/softoken/legacydb/lowkeyi.h b/security/nss/lib/softoken/legacydb/lowkeyi.h deleted file mode 100644 index 45359d4ef..000000000 --- a/security/nss/lib/softoken/legacydb/lowkeyi.h +++ /dev/null @@ -1,198 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#ifndef _LOWKEYI_H_ -#define _LOWKEYI_H_ - -#include "prtypes.h" -#include "seccomon.h" -#include "secoidt.h" -#include "pcertt.h" -#include "lowkeyti.h" -#include "sdb.h" - -SEC_BEGIN_PROTOS - -/* - * 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. - */ -extern void prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_pqg_params_for_asn1(PQGParams *params); -extern void prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -#ifdef NSS_ENABLE_ECC -extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_ecparams_for_asn1(ECParams *params); -#endif /* NSS_ENABLE_ECC */ - -typedef char * (* NSSLOWKEYDBNameFunc)(void *arg, int dbVersion); - -/* -** Open a key database. -*/ -extern NSSLOWKEYDBHandle *nsslowkey_OpenKeyDB(PRBool readOnly, - const char *domain, - const char *prefix, - NSSLOWKEYDBNameFunc namecb, - void *cbarg); - -/* -** Close the specified key database. -*/ -extern void nsslowkey_CloseKeyDB(NSSLOWKEYDBHandle *handle); - -/* - * Get the version number of the database - */ -extern int nsslowkey_GetKeyDBVersion(NSSLOWKEYDBHandle *handle); - -/* -** Delete a key from the database -*/ -extern SECStatus nsslowkey_DeleteKey(NSSLOWKEYDBHandle *handle, - const SECItem *pubkey); - -/* -** Store a key in the database, indexed by its public key modulus. -** "pk" is the private key to store -** "f" is a the callback function for getting the password -** "arg" is the argument for the callback -*/ -extern SECStatus nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle, - NSSLOWKEYPrivateKey *pk, - SECItem *pubKeyData, - char *nickname, - SDB *sdb); - -/* does the key for this cert exist in the database filed by modulus */ -extern PRBool nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, - NSSLOWCERTCertificate *cert); -/* does a key with this ID already exist? */ -extern PRBool nsslowkey_KeyForIDExists(NSSLOWKEYDBHandle *handle, SECItem *id); - -/* -** Destroy a private key object. -** "key" the object -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *key); - -/* -** Destroy a public key object. -** "key" the object -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key); - -/* -** Return the modulus length of "pubKey". -*/ -extern unsigned int nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubKey); - - -/* -** Return the modulus length of "privKey". -*/ -extern unsigned int nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privKey); - - -/* -** Convert a low private key "privateKey" into a public low key -*/ -extern NSSLOWKEYPublicKey - *nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privateKey); - - -SECStatus -nsslowkey_UpdateNickname(NSSLOWKEYDBHandle *handle, - NSSLOWKEYPrivateKey *privkey, - SECItem *pubKeyData, - char *nickname, - SDB *sdb); - -/* Store key by modulus and specify an encryption algorithm to use. - * handle is the pointer to the key database, - * privkey is the private key to be stored, - * f and arg are the function and arguments to the callback - * to get a password, - * algorithm is the algorithm which the privKey is to be stored. - * A return of anything but SECSuccess indicates failure. - */ -extern SECStatus -nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle, - NSSLOWKEYPrivateKey *privkey, - SECItem *pubKeyData, - char *nickname, - SDB *sdb, - PRBool update); - -/* Find key by modulus. This function is the inverse of store key - * by modulus. An attempt to locate the key with "modulus" is - * performed. If the key is found, the private key is returned, - * else NULL is returned. - * modulus is the modulus to locate - */ -extern NSSLOWKEYPrivateKey * -nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus, - SDB *sdb); - -extern char * -nsslowkey_FindKeyNicknameByPublicKey(NSSLOWKEYDBHandle *handle, - SECItem *modulus, SDB *sdb); - -#ifdef NSS_ENABLE_ECC -/* - * smaller version of EC_FillParams. In this code, we only need - * oid and DER data. - */ -SECStatus LGEC_FillParams(PRArenaPool *arena, const SECItem *encodedParams, - ECParams *params); - -/* Copy all of the fields from srcParams into dstParams */ -SECStatus LGEC_CopyParams(PRArenaPool *arena, ECParams *dstParams, - const ECParams *srcParams); -#endif -SEC_END_PROTOS - -#endif /* _LOWKEYI_H_ */ diff --git a/security/nss/lib/softoken/legacydb/lowkeyti.h b/security/nss/lib/softoken/legacydb/lowkeyti.h deleted file mode 100644 index 7fa74da72..000000000 --- a/security/nss/lib/softoken/legacydb/lowkeyti.h +++ /dev/null @@ -1,170 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef _LOWKEYTI_H_ -#define _LOWKEYTI_H_ 1 - -#include "blapit.h" -#include "prtypes.h" -#include "plarena.h" -#include "secitem.h" -#include "secasn1t.h" -#include "secoidt.h" - - -/* - * a key in/for the data base - */ -struct NSSLOWKEYDBKeyStr { - PLArenaPool *arena; - int version; - char *nickname; - SECItem salt; - SECItem derPK; -}; -typedef struct NSSLOWKEYDBKeyStr NSSLOWKEYDBKey; - -typedef struct NSSLOWKEYDBHandleStr NSSLOWKEYDBHandle; - -#ifdef NSS_USE_KEY4_DB -#define NSSLOWKEY_DB_FILE_VERSION 4 -#else -#define NSSLOWKEY_DB_FILE_VERSION 3 -#endif - -#define NSSLOWKEY_VERSION 0 /* what we *create* */ - -/* -** Typedef for callback to get a password "key". -*/ -extern const SEC_ASN1Template nsslowkey_PQGParamsTemplate[]; -extern const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[]; -extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[]; -extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[]; -extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[]; -extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[]; -#ifdef NSS_ENABLE_ECC -#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */ -extern const SEC_ASN1Template nsslowkey_ECParamsTemplate[]; -extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[]; -#endif /* NSS_ENABLE_ECC */ - -extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[]; -extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[]; - -/* - * PKCS #8 attributes - */ -struct NSSLOWKEYAttributeStr { - SECItem attrType; - SECItem *attrValue; -}; -typedef struct NSSLOWKEYAttributeStr NSSLOWKEYAttribute; - -/* -** A PKCS#8 private key info object -*/ -struct NSSLOWKEYPrivateKeyInfoStr { - PLArenaPool *arena; - SECItem version; - SECAlgorithmID algorithm; - SECItem privateKey; - NSSLOWKEYAttribute **attributes; -}; -typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo; -#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */ - -/* -** A PKCS#8 private key info object -*/ -struct NSSLOWKEYEncryptedPrivateKeyInfoStr { - PLArenaPool *arena; - SECAlgorithmID algorithm; - SECItem encryptedData; -}; -typedef struct NSSLOWKEYEncryptedPrivateKeyInfoStr NSSLOWKEYEncryptedPrivateKeyInfo; - - -typedef enum { - NSSLOWKEYNullKey = 0, - NSSLOWKEYRSAKey = 1, - NSSLOWKEYDSAKey = 2, - NSSLOWKEYDHKey = 4, - NSSLOWKEYECKey = 5 -} NSSLOWKEYType; - -/* -** An RSA public key object. -*/ -struct NSSLOWKEYPublicKeyStr { - PLArenaPool *arena; - NSSLOWKEYType keyType ; - union { - RSAPublicKey rsa; - DSAPublicKey dsa; - DHPublicKey dh; - ECPublicKey ec; - } u; -}; -typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey; - -/* -** Low Level private key object -** This is only used by the raw Crypto engines (crypto), keydb (keydb), -** and PKCS #11. Everyone else uses the high level key structure. -*/ -struct NSSLOWKEYPrivateKeyStr { - PLArenaPool *arena; - NSSLOWKEYType keyType; - union { - RSAPrivateKey rsa; - DSAPrivateKey dsa; - DHPrivateKey dh; - ECPrivateKey ec; - } u; -}; -typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey; - - -typedef struct NSSLOWKEYPasswordEntryStr NSSLOWKEYPasswordEntry; -struct NSSLOWKEYPasswordEntryStr { - SECItem salt; - SECItem value; - unsigned char data[128]; -}; - - -#endif /* _LOWKEYTI_H_ */ diff --git a/security/nss/lib/softoken/legacydb/manifest.mn b/security/nss/lib/softoken/legacydb/manifest.mn deleted file mode 100644 index c3048646e..000000000 --- a/security/nss/lib/softoken/legacydb/manifest.mn +++ /dev/null @@ -1,67 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** -CORE_DEPTH = ../../../.. - -MODULE = nss - -REQUIRES = dbm - -LIBRARY_NAME = nssdbm -LIBRARY_VERSION = 3 -MAPFILE = $(OBJDIR)/nssdbm.def - -DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DSOFTOKEN_LIB_NAME=\"$(notdir $(SHARED_LIBRARY))\" - -ifdef MOZILLA_CLIENT -INCLUDES += -I$(DIST)/include/sqlite3 -endif - -CSRCS = \ - dbmshim.c \ - keydb.c \ - lgattr.c \ - lgcreate.c \ - lgdestroy.c \ - lgfind.c \ - lginit.c \ - lgutil.c \ - lowcert.c \ - lowkey.c \ - pcertdb.c \ - pk11db.c \ - $(NULL) - diff --git a/security/nss/lib/softoken/legacydb/nssdbm.def b/security/nss/lib/softoken/legacydb/nssdbm.def deleted file mode 100644 index bf7f7a5a1..000000000 --- a/security/nss/lib/softoken/legacydb/nssdbm.def +++ /dev/null @@ -1,64 +0,0 @@ -;+# -;+# ***** BEGIN LICENSE BLOCK ***** -;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -;+# -;+# 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 the Initial Developer are Copyright (C) 2000 -;+# the Initial Developer. 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 -;+# either the GNU General Public License Version 2 or later (the "GPL"), or -;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -;+# in which case the provisions of the GPL or the LGPL are applicable instead -;+# of those above. If you wish to allow use of your version of this file only -;+# under the terms of either the GPL or the LGPL, and not to allow others to -;+# use your version of this file under the terms of the MPL, indicate your -;+# decision by deleting the provisions above and replace them with the notice -;+# and other provisions required by the GPL or the LGPL. If you do not delete -;+# the provisions above, a recipient may use your version of this file under -;+# the terms of any one of the MPL, the GPL or the LGPL. -;+# -;+# ***** END LICENSE BLOCK ***** -;+# -;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS -;+# 1. For all unix platforms, the string ";-" means "remove this line" -;+# 2. For all unix platforms, the string " DATA " will be removed from any -;+# line on which it occurs. -;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -;+# On AIX, lines containing ";+" will be removed. -;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. -;+# 5. For all unix platforms, after the above processing has taken place, -;+# all characters after the first ";" on the line will be removed. -;+# And for AIX, the first ";" will also be removed. -;+# This file is passed directly to windows. Since ';' is a comment, all UNIX -;+# directives are hidden behind ";", ";+", and ";-" -;+NSSDBM_3.12 { # NSS 3.12 release -;+ global: -LIBRARY nssdbm3 ;- -EXPORTS ;- -legacy_Open; -legacy_Shutdown; -legacy_ReadSecmodDB; -legacy_ReleaseSecmodDBData; -legacy_AddSecmodDB; -legacy_DeleteSecmodDB; -legacy_SetCryptFunctions; -;+ local: -;+ *; -;+}; diff --git a/security/nss/lib/softoken/legacydb/nssdbm.rc b/security/nss/lib/softoken/legacydb/nssdbm.rc deleted file mode 100644 index d89126a37..000000000 --- a/security/nss/lib/softoken/legacydb/nssdbm.rc +++ /dev/null @@ -1,100 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "../softkver.h" -#include <winver.h> - -#define MY_LIBNAME "nssdbm" -#define MY_FILEDESCRIPTION "Legacy Database Driver" - -#define STRINGIZE(x) #x -#define STRINGIZE2(x) STRINGIZE(x) -#define SOFTOKEN_VMAJOR_STR STRINGIZE2(SOFTOKEN_VMAJOR) - -#ifdef _DEBUG -#define MY_DEBUG_STR " (debug)" -#define MY_FILEFLAGS_1 VS_FF_DEBUG -#else -#define MY_DEBUG_STR "" -#define MY_FILEFLAGS_1 0x0L -#endif -#if SOFTOKEN_BETA -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE -#else -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 -#endif - -#ifdef WINNT -#define MY_FILEOS VOS_NT_WINDOWS32 -#else -#define MY_FILEOS VOS__WINDOWS32 -#endif - -#define MY_INTERNAL_NAME MY_LIBNAME SOFTOKEN_VMAJOR_STR - -///////////////////////////////////////////////////////////////////////////// -// -// Version-information resource -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,0 - PRODUCTVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS MY_FILEFLAGS_2 - FILEOS MY_FILEOS - FILETYPE VFT_DLL - FILESUBTYPE 0x0L // not used - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" // Lang=US English, CharSet=Unicode - BEGIN - VALUE "CompanyName", "Mozilla Foundation\0" - VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" - VALUE "FileVersion", SOFTOKEN_VERSION "\0" - VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" - VALUE "ProductName", "Network Security Services\0" - VALUE "ProductVersion", SOFTOKEN_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/security/nss/lib/softoken/legacydb/pcert.h b/security/nss/lib/softoken/legacydb/pcert.h deleted file mode 100644 index 68956abd6..000000000 --- a/security/nss/lib/softoken/legacydb/pcert.h +++ /dev/null @@ -1,261 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _PCERTDB_H_ -#define _PCERTDB_H_ - -#include "plarena.h" -#include "prlong.h" -#include "pcertt.h" - -#include "lowkeyti.h" /* for struct NSSLOWKEYPublicKeyStr */ - -SEC_BEGIN_PROTOS - -/* - * initialize any global certificate locks - */ -SECStatus nsslowcert_InitLocks(void); - -/* -** 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 nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *handle, - NSSLOWCERTCertificate *cert, - char *nickname, NSSLOWCERTCertTrust *trust); -SECStatus nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle, - NSSLOWCERTCertificate *cert, char *nickname); - -SECStatus nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert); - -typedef SECStatus (PR_CALLBACK * PermCertCallback)(NSSLOWCERTCertificate *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 -nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle, - PermCertCallback certfunc, - void *udata ); - -PRBool -nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle); - -certDBEntryRevocation * -nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, - SECItem *crlKey, PRBool isKRL); - -SECStatus -nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle,const SECItem *derName, - PRBool isKRL); -SECStatus -nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl , - SECItem *derKey, char *url, PRBool isKRL); - -NSSLOWCERTCertDBHandle *nsslowcert_GetDefaultCertDB(); -NSSLOWKEYPublicKey *nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *); - -NSSLOWCERTCertificate * -nsslowcert_NewTempCertificate(NSSLOWCERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER); -NSSLOWCERTCertificate * -nsslowcert_DupCertificate(NSSLOWCERTCertificate *cert); -void nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert); -void nsslowcert_DestroyTrust(NSSLOWCERTTrust *Trust); - -/* - * Lookup a certificate in the databases without locking - * "certKey" is the database key to look for - * - * XXX - this should be internal, but pkcs 11 needs to call it during a - * traversal. - */ -NSSLOWCERTCertificate * -nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey); - -/* - * Lookup trust for a certificate in the databases without locking - * "certKey" is the database key to look for - * - * XXX - this should be internal, but pkcs 11 needs to call it during a - * traversal. - */ -NSSLOWCERTTrust * -nsslowcert_FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey); - -/* -** 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 NSSLOWCERTCertificate * -nsslowcert_FindCertByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN); - -/* -** 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 NSSLOWCERTTrust * -nsslowcert_FindTrustByIssuerAndSN (NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN); - -/* -** Find a certificate in the database by a DER encoded certificate -** "derCert" is the DER encoded certificate -*/ -extern NSSLOWCERTCertificate * -nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert); - -/* convert an email address to lower case */ -char *nsslowcert_FixupEmailAddr(char *emailAddr); - -/* -** Decode a DER encoded certificate into an NSSLOWCERTCertificate 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 NSSLOWCERTCertificate * -nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, char *nickname); - -SECStatus -nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key); - -certDBEntrySMime * -nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *certHandle, - char *emailAddr); -void -nsslowcert_DestroyDBEntry(certDBEntry *entry); - -SECStatus -nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly, - const char *domain, const char *prefix, - NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile); - -void -nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle); - -/* - * is certa newer than certb? If one is expired, pick the other one. - */ -PRBool -nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb); - - -SECStatus -nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle, - certDBEntryType type, - SECStatus (* callback)(SECItem *data, SECItem *key, - certDBEntryType type, void *pdata), - void *udata ); -SECStatus -nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle, - SECItem *derSubject, - NSSLOWCERTCertCallback cb, void *cbarg); -int -nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle, - SECItem *derSubject); -SECStatus -nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle, - char *nickname, NSSLOWCERTCertCallback cb, void *cbarg); - -int -nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle, - char *nickname); -SECStatus -nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert, - NSSLOWCERTCertTrust *trust); - -SECStatus -nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr, - SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime); - -/* - * Change the trust attributes of a certificate and make them permanent - * in the database. - */ -SECStatus -nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle, - NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust); - -PRBool -nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle); - -void -nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value); - -PRBool -nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust); - -void -nsslowcert_DestroyFreeLists(void); - -void -nsslowcert_DestroyGlobalLocks(void); - -void -pkcs11_freeNickname(char *nickname, char *space); - -char * -pkcs11_copyNickname(char *nickname, char *space, int spaceLen); - -void -pkcs11_freeStaticData(unsigned char *data, unsigned char *space); - -unsigned char * -pkcs11_allocStaticData(int datalen, unsigned char *space, int spaceLen); - -unsigned char * -pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space, - int spaceLen); -NSSLOWCERTCertificate * -nsslowcert_CreateCert(void); - -certDBEntry * -nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey, - certDBEntryType entryType, void *pdata); - -SEC_END_PROTOS - - #endif /* _PCERTDB_H_ */ diff --git a/security/nss/lib/softoken/legacydb/pcertdb.c b/security/nss/lib/softoken/legacydb/pcertdb.c deleted file mode 100644 index 039d6aed3..000000000 --- a/security/nss/lib/softoken/legacydb/pcertdb.c +++ /dev/null @@ -1,5366 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Permanent Certificate database handling code - * - * $Id$ - */ -#include "lowkeyti.h" -#include "pcert.h" -#include "mcom_db.h" -#include "pcert.h" -#include "secitem.h" -#include "secder.h" - -#include "secerr.h" -#include "lgdb.h" - -/* forward declaration */ -NSSLOWCERTCertificate * -nsslowcert_FindCertByDERCertNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *derCert); -static SECStatus -nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, - char *emailAddr, SECItem *derSubject, SECItem *emailProfile, - SECItem *profileTime); -static SECStatus -nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle, - NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust); -static SECStatus -nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl, - SECItem *crlKey, char *url, PRBool isKRL); - -static NSSLOWCERTCertificate *certListHead = NULL; -static NSSLOWCERTTrust *trustListHead = NULL; -static certDBEntryCert *entryListHead = NULL; -static int certListCount = 0; -static int trustListCount = 0; -static int entryListCount = 0; -#define MAX_CERT_LIST_COUNT 10 -#define MAX_TRUST_LIST_COUNT 10 -#define MAX_ENTRY_LIST_COUNT 10 - -/* - * the following functions are wrappers for the db library that implement - * a global lock to make the database thread safe. - */ -static PZLock *dbLock = NULL; -static PZLock *certRefCountLock = NULL; -static PZLock *certTrustLock = NULL; -static PZLock *freeListLock = NULL; - -void -certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle) -{ - if (dbLock == NULL) { - dbLock = PZ_NewLock(nssILockCertDB); - PORT_Assert(dbLock != NULL); - } -} - -SECStatus -nsslowcert_InitLocks(void) -{ - if (freeListLock == NULL) { - freeListLock = PZ_NewLock(nssILockRefLock); - if (freeListLock == NULL) { - return SECFailure; - } - } - if (certRefCountLock == NULL) { - certRefCountLock = PZ_NewLock(nssILockRefLock); - if (certRefCountLock == NULL) { - return SECFailure; - } - } - if (certTrustLock == NULL ) { - certTrustLock = PZ_NewLock(nssILockCertDB); - if (certTrustLock == NULL) { - return SECFailure; - } - } - - return SECSuccess; -} - -/* - * Acquire the global lock on the cert database. - * This lock is currently used for the following operations: - * adding or deleting a cert to either the temp or perm databases - * converting a temp to perm or perm to temp - * changing (maybe just adding!?) the trust of a cert - * chaning the DB status checking Configuration - */ -static void -nsslowcert_LockDB(NSSLOWCERTCertDBHandle *handle) -{ - PZ_EnterMonitor(handle->dbMon); - return; -} - -/* - * Free the global cert database lock. - */ -static void -nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle) -{ - PRStatus prstat; - - prstat = PZ_ExitMonitor(handle->dbMon); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - - -/* - * 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. - */ -static void -nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert) -{ - PORT_Assert(certRefCountLock != NULL); - - PZ_Lock(certRefCountLock); - return; -} - -/* - * Free the cert reference count lock - */ -static void -nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert) -{ - PRStatus prstat; - - PORT_Assert(certRefCountLock != NULL); - - prstat = PZ_Unlock(certRefCountLock); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - -/* - * 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. - */ -static void -nsslowcert_LockCertTrust(NSSLOWCERTCertificate *cert) -{ - PORT_Assert(certTrustLock != NULL); - - PZ_Lock(certTrustLock); - return; -} - -/* - * Free the cert trust lock - */ -static void -nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert) -{ - PRStatus prstat; - - PORT_Assert(certTrustLock != NULL); - - prstat = PZ_Unlock(certTrustLock); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - - -/* - * 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. - */ -static void -nsslowcert_LockFreeList(void) -{ - PORT_Assert(freeListLock != NULL); - - SKIP_AFTER_FORK(PZ_Lock(freeListLock)); - return; -} - -/* - * Free the cert reference count lock - */ -static void -nsslowcert_UnlockFreeList(void) -{ - PRStatus prstat = PR_SUCCESS; - - PORT_Assert(freeListLock != NULL); - - SKIP_AFTER_FORK(prstat = PZ_Unlock(freeListLock)); - - PORT_Assert(prstat == PR_SUCCESS); - - return; -} - -NSSLOWCERTCertificate * -nsslowcert_DupCertificate(NSSLOWCERTCertificate *c) -{ - if (c) { - nsslowcert_LockCertRefCount(c); - ++c->referenceCount; - nsslowcert_UnlockCertRefCount(c); - } - return c; -} - -static int -certdb_Get(DB *db, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PZ_Lock(dbLock); - - ret = (* db->get)(db, key, data, flags); - - prstat = PZ_Unlock(dbLock); - - return(ret); -} - -static int -certdb_Put(DB *db, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret = 0; - - PORT_Assert(dbLock != NULL); - PZ_Lock(dbLock); - - ret = (* db->put)(db, key, data, flags); - - prstat = PZ_Unlock(dbLock); - - return(ret); -} - -static int -certdb_Sync(DB *db, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PZ_Lock(dbLock); - - ret = (* db->sync)(db, flags); - - prstat = PZ_Unlock(dbLock); - - return(ret); -} - -#define DB_NOT_FOUND -30991 /* from DBM 3.2 */ -static int -certdb_Del(DB *db, DBT *key, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PZ_Lock(dbLock); - - ret = (* db->del)(db, key, flags); - - prstat = PZ_Unlock(dbLock); - - /* don't fail if the record is already deleted */ - if (ret == DB_NOT_FOUND) { - ret = 0; - } - - return(ret); -} - -static int -certdb_Seq(DB *db, DBT *key, DBT *data, unsigned int flags) -{ - PRStatus prstat; - int ret; - - PORT_Assert(dbLock != NULL); - PZ_Lock(dbLock); - - ret = (* db->seq)(db, key, data, flags); - - prstat = PZ_Unlock(dbLock); - - return(ret); -} - -static void -certdb_Close(DB *db) -{ - PRStatus prstat = PR_SUCCESS; - - PORT_Assert(dbLock != NULL); - SKIP_AFTER_FORK(PZ_Lock(dbLock)); - - (* db->close)(db); - - SKIP_AFTER_FORK(prstat = PZ_Unlock(dbLock)); - - return; -} - -void -pkcs11_freeNickname(char *nickname, char *space) -{ - if (nickname && nickname != space) { - PORT_Free(nickname); - } -} - -char * -pkcs11_copyNickname(char *nickname,char *space, int spaceLen) -{ - int len; - char *copy = NULL; - - len = PORT_Strlen(nickname)+1; - if (len <= spaceLen) { - copy = space; - PORT_Memcpy(copy,nickname,len); - } else { - copy = PORT_Strdup(nickname); - } - - return copy; -} - -void -pkcs11_freeStaticData (unsigned char *data, unsigned char *space) -{ - if (data && data != space) { - PORT_Free(data); - } -} - -unsigned char * -pkcs11_allocStaticData(int len, unsigned char *space, int spaceLen) -{ - unsigned char *data = NULL; - - if (len <= spaceLen) { - data = space; - } else { - data = (unsigned char *) PORT_Alloc(len); - } - - return data; -} - -unsigned char * -pkcs11_copyStaticData(unsigned char *data, int len, - unsigned char *space, int spaceLen) -{ - unsigned char *copy = pkcs11_allocStaticData(len, space, spaceLen); - if (copy) { - PORT_Memcpy(copy,data,len); - } - - return copy; -} - -/* - * destroy a database entry - */ -static void -DestroyDBEntry(certDBEntry *entry) -{ - PRArenaPool *arena = entry->common.arena; - - /* must be one of our certDBEntry from the free list */ - if (arena == NULL) { - certDBEntryCert *certEntry; - if ( entry->common.type != certDBEntryTypeCert) { - return; - } - certEntry = (certDBEntryCert *)entry; - - pkcs11_freeStaticData(certEntry->derCert.data, certEntry->derCertSpace); - pkcs11_freeNickname(certEntry->nickname, certEntry->nicknameSpace); - - nsslowcert_LockFreeList(); - if (entryListCount > MAX_ENTRY_LIST_COUNT) { - PORT_Free(certEntry); - } else { - entryListCount++; - PORT_Memset(certEntry, 0, sizeof( *certEntry)); - certEntry->next = entryListHead; - entryListHead = certEntry; - } - nsslowcert_UnlockFreeList(); - return; - } - - - /* Zero out the entry struct, so that any further attempts to use it - * will cause an exception (e.g. null pointer reference). */ - PORT_Memset(&entry->common, 0, sizeof entry->common); - PORT_FreeArena(arena, PR_FALSE); - - return; -} - -/* forward references */ -static void nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert); - -static SECStatus -DeleteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryType type, SECItem *dbkey) -{ - DBT key; - int ret; - - /* init the database key */ - key.data = dbkey->data; - key.size = dbkey->len; - - dbkey->data[0] = (unsigned char)type; - - /* delete entry from database */ - ret = certdb_Del(handle->permCertDB, &key, 0 ); - if ( ret != 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - ret = certdb_Sync(handle->permCertDB, 0); - if ( ret ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -ReadDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry, - SECItem *dbkey, SECItem *dbentry, PRArenaPool *arena) -{ - DBT data, key; - int ret; - unsigned char *buf; - - /* init the database key */ - key.data = dbkey->data; - key.size = dbkey->len; - - dbkey->data[0] = (unsigned char)entry->type; - - /* read entry from database */ - ret = certdb_Get(handle->permCertDB, &key, &data, 0 ); - if ( ret != 0 ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* validate the entry */ - if ( data.size < SEC_DB_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - buf = (unsigned char *)data.data; - /* version 7 has the same schema, we may be using a v7 db if we openned - * the databases readonly. */ - if (!((buf[0] == (unsigned char)CERT_DB_FILE_VERSION) - || (buf[0] == (unsigned char) CERT_DB_V7_FILE_VERSION))) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - if ( buf[1] != (unsigned char)entry->type ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy out header information */ - entry->version = (unsigned int)buf[0]; - entry->type = (certDBEntryType)buf[1]; - entry->flags = (unsigned int)buf[2]; - - /* format body of entry for return to caller */ - dbentry->len = data.size - SEC_DB_ENTRY_HEADER_LEN; - if ( dbentry->len ) { - if (arena) { - dbentry->data = (unsigned char *) - PORT_ArenaAlloc(arena, dbentry->len); - if ( dbentry->data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - PORT_Memcpy(dbentry->data, &buf[SEC_DB_ENTRY_HEADER_LEN], - dbentry->len); - } else { - dbentry->data = &buf[SEC_DB_ENTRY_HEADER_LEN]; - } - } else { - dbentry->data = NULL; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/** - ** Implement low level database access - **/ -static SECStatus -WriteDBEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCommon *entry, - SECItem *dbkey, SECItem *dbentry) -{ - int ret; - DBT data, key; - unsigned char *buf; - - data.data = dbentry->data; - data.size = dbentry->len; - - buf = (unsigned char*)data.data; - - buf[0] = (unsigned char)entry->version; - buf[1] = (unsigned char)entry->type; - buf[2] = (unsigned char)entry->flags; - - key.data = dbkey->data; - key.size = dbkey->len; - - dbkey->data[0] = (unsigned char)entry->type; - - /* put the record into the database now */ - ret = certdb_Put(handle->permCertDB, &key, &data, 0); - - if ( ret != 0 ) { - goto loser; - } - - ret = certdb_Sync( handle->permCertDB, 0 ); - - if ( ret ) { - goto loser; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * encode a database cert record - */ -static SECStatus -EncodeDBCertEntry(certDBEntryCert *entry, PRArenaPool *arena, SECItem *dbitem) -{ - unsigned int nnlen; - unsigned char *buf; - char *nn; - char zbuf = 0; - - if ( entry->nickname ) { - nn = entry->nickname; - } else { - nn = &zbuf; - } - nnlen = PORT_Strlen(nn) + 1; - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->derCert.len + nnlen + DB_CERT_ENTRY_HEADER_LEN + - SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->trust.sslFlags >> 8 ) & 0xff; - buf[1] = entry->trust.sslFlags & 0xff; - buf[2] = ( entry->trust.emailFlags >> 8 ) & 0xff; - buf[3] = entry->trust.emailFlags & 0xff; - buf[4] = ( entry->trust.objectSigningFlags >> 8 ) & 0xff; - buf[5] = entry->trust.objectSigningFlags & 0xff; - buf[6] = ( entry->derCert.len >> 8 ) & 0xff; - buf[7] = entry->derCert.len & 0xff; - buf[8] = ( nnlen >> 8 ) & 0xff; - buf[9] = nnlen & 0xff; - - PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN], entry->derCert.data, - entry->derCert.len); - - PORT_Memcpy(&buf[DB_CERT_ENTRY_HEADER_LEN + entry->derCert.len], - nn, nnlen); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * encode a database key for a cert record - */ -static SECStatus -EncodeDBCertKey(const SECItem *certKey, PRArenaPool *arena, SECItem *dbkey) -{ - unsigned int len = certKey->len + SEC_DB_KEY_HEADER_LEN; - if (arena) { - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, len); - } else { - if (dbkey->len < len) { - dbkey->data = (unsigned char *)PORT_Alloc(len); - } - } - dbkey->len = len; - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], - certKey->data, certKey->len); - dbkey->data[0] = certDBEntryTypeCert; - - return(SECSuccess); -loser: - return(SECFailure); -} - -static SECStatus -EncodeDBGenericKey(const SECItem *certKey, PRArenaPool *arena, SECItem *dbkey, - certDBEntryType entryType) -{ - /* - * we only allow _one_ KRL key! - */ - if (entryType == certDBEntryTypeKeyRevocation) { - dbkey->len = SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - dbkey->data[0] = (unsigned char) entryType; - return(SECSuccess); - } - - - dbkey->len = certKey->len + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], - certKey->data, certKey->len); - dbkey->data[0] = (unsigned char) entryType; - - return(SECSuccess); -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry) -{ - unsigned int nnlen; - unsigned int headerlen; - int lenoff; - - /* allow updates of old versions of the database */ - switch ( entry->common.version ) { - case 5: - headerlen = DB_CERT_V5_ENTRY_HEADER_LEN; - lenoff = 3; - break; - case 6: - /* should not get here */ - PORT_Assert(0); - headerlen = DB_CERT_V6_ENTRY_HEADER_LEN; - lenoff = 3; - break; - case 7: - case 8: - headerlen = DB_CERT_ENTRY_HEADER_LEN; - lenoff = 6; - break; - default: - /* better not get here */ - PORT_Assert(0); - headerlen = DB_CERT_V5_ENTRY_HEADER_LEN; - lenoff = 3; - break; - } - - /* is record long enough for header? */ - if ( dbentry->len < headerlen ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->derCert.len = ( ( dbentry->data[lenoff] << 8 ) | - dbentry->data[lenoff+1] ); - nnlen = ( ( dbentry->data[lenoff+2] << 8 ) | dbentry->data[lenoff+3] ); - if ( ( entry->derCert.len + nnlen + headerlen ) - != dbentry->len) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy the dercert */ - - entry->derCert.data = pkcs11_copyStaticData(&dbentry->data[headerlen], - entry->derCert.len,entry->derCertSpace,sizeof(entry->derCertSpace)); - if ( entry->derCert.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* copy the nickname */ - if ( nnlen > 1 ) { - entry->nickname = (char *)pkcs11_copyStaticData( - &dbentry->data[headerlen+entry->derCert.len], nnlen, - (unsigned char *)entry->nicknameSpace, - sizeof(entry->nicknameSpace)); - if ( entry->nickname == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - } else { - entry->nickname = NULL; - } - - if ( entry->common.version < 7 ) { - /* allow updates of v5 db */ - entry->trust.sslFlags = dbentry->data[0]; - entry->trust.emailFlags = dbentry->data[1]; - entry->trust.objectSigningFlags = dbentry->data[2]; - } else { - entry->trust.sslFlags = ( dbentry->data[0] << 8 ) | dbentry->data[1]; - entry->trust.emailFlags = ( dbentry->data[2] << 8 ) | dbentry->data[3]; - entry->trust.objectSigningFlags = - ( dbentry->data[4] << 8 ) | dbentry->data[5]; - } - - return(SECSuccess); -loser: - return(SECFailure); -} - - -/* - * Create a new certDBEntryCert from existing data - */ -static certDBEntryCert * -NewDBCertEntry(SECItem *derCert, char *nickname, - NSSLOWCERTCertTrust *trust, int flags) -{ - certDBEntryCert *entry; - PRArenaPool *arena = NULL; - int nnlen; - - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); - - if ( !arena ) { - goto loser; - } - - entry = PORT_ArenaZNew(arena, certDBEntryCert); - if ( entry == NULL ) { - goto loser; - } - - /* fill in the dbCert */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeCert; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - if ( trust ) { - entry->trust = *trust; - } - - entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, derCert->len); - if ( !entry->derCert.data ) { - goto loser; - } - entry->derCert.len = derCert->len; - PORT_Memcpy(entry->derCert.data, derCert->data, derCert->len); - - nnlen = ( nickname ? strlen(nickname) + 1 : 0 ); - - if ( nnlen ) { - entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( !entry->nickname ) { - goto loser; - } - PORT_Memcpy(entry->nickname, nickname, nnlen); - - } else { - entry->nickname = 0; - } - - return(entry); - -loser: - - /* allocation error, free arena and return */ - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); -} - -/* - * Decode a version 4 DBCert from the byte stream database format - * and construct a current database entry struct - */ -static certDBEntryCert * -DecodeV4DBCertEntry(unsigned char *buf, int len) -{ - certDBEntryCert *entry; - int certlen; - int nnlen; - PRArenaPool *arena; - - /* make sure length is at least long enough for the header */ - if ( len < DBCERT_V4_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(0); - } - - /* get other lengths */ - certlen = buf[3] << 8 | buf[4]; - nnlen = buf[5] << 8 | buf[6]; - - /* make sure DB entry is the right size */ - if ( ( certlen + nnlen + DBCERT_V4_HEADER_LEN ) != len ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(0); - } - - /* allocate arena */ - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); - - if ( !arena ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); - } - - /* allocate structure and members */ - entry = (certDBEntryCert *) PORT_ArenaAlloc(arena, sizeof(certDBEntryCert)); - - if ( !entry ) { - goto loser; - } - - entry->common.arena = arena; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.type = certDBEntryTypeCert; - entry->common.flags = 0; - entry->trust.sslFlags = buf[0]; - entry->trust.emailFlags = buf[1]; - entry->trust.objectSigningFlags = buf[2]; - - entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen); - if ( !entry->derCert.data ) { - goto loser; - } - entry->derCert.len = certlen; - PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen); - - if ( nnlen ) { - entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen); - if ( !entry->nickname ) { - goto loser; - } - PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen); - - if (PORT_Strcmp(entry->nickname, "Server-Cert") == 0) { - entry->trust.sslFlags |= CERTDB_USER; - } - } else { - entry->nickname = 0; - } - - return(entry); - -loser: - PORT_FreeArena(arena, PR_FALSE); - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); -} - -/* - * Encode a Certificate database entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBCertEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECItem tmpitem; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBCertEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - /* get the database key and format it */ - rv = nsslowcert_KeyFromDERCert(tmparena, &entry->derCert, &tmpitem); - if ( rv == SECFailure ) { - goto loser; - } - - rv = EncodeDBCertKey(&tmpitem, tmparena, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); -} - - -/* - * delete a certificate entry - */ -static SECStatus -DeleteDBCertEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey) -{ - SECItem dbkey; - SECStatus rv; - - dbkey.data= NULL; - dbkey.len = 0; - - rv = EncodeDBCertKey(certKey, NULL, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeCert, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - if (dbkey.data) { - PORT_Free(dbkey.data); - } - return(SECSuccess); - -loser: - if (dbkey.data) { - PORT_Free(dbkey.data); - } - return(SECFailure); -} - -static certDBEntryCert * -CreateCertEntry(void) -{ - certDBEntryCert *entry; - - nsslowcert_LockFreeList(); - entry = entryListHead; - if (entry) { - entryListCount--; - entryListHead = entry->next; - } - PORT_Assert(entryListCount >= 0); - nsslowcert_UnlockFreeList(); - if (entry) { - return entry; - } - - return PORT_ZNew(certDBEntryCert); -} - -static void -DestroyCertEntryFreeList(void) -{ - certDBEntryCert *entry; - - nsslowcert_LockFreeList(); - while (NULL != (entry = entryListHead)) { - entryListCount--; - entryListHead = entry->next; - PORT_Free(entry); - } - PORT_Assert(!entryListCount); - entryListCount = 0; - nsslowcert_UnlockFreeList(); -} - -/* - * Read a certificate entry - */ -static certDBEntryCert * -ReadDBCertEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey) -{ - certDBEntryCert *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - unsigned char buf[512]; - - dbkey.data = buf; - dbkey.len = sizeof(buf); - - entry = CreateCertEntry(); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = NULL; - entry->common.type = certDBEntryTypeCert; - - rv = EncodeDBCertKey(certKey, NULL, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL); - if ( rv == SECFailure ) { - goto loser; - } - - rv = DecodeDBCertEntry(entry, &dbentry); - if ( rv != SECSuccess ) { - goto loser; - } - - pkcs11_freeStaticData(dbkey.data,buf); - dbkey.data = NULL; - return(entry); - -loser: - pkcs11_freeStaticData(dbkey.data,buf); - dbkey.data = NULL; - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - - return(NULL); -} - -/* - * encode a database cert record - */ -static SECStatus -EncodeDBCrlEntry(certDBEntryRevocation *entry, PRArenaPool *arena, SECItem *dbitem) -{ - unsigned int nnlen = 0; - unsigned char *buf; - - if (entry->url) { - nnlen = PORT_Strlen(entry->url) + 1; - } - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->derCrl.len + nnlen - + SEC_DB_ENTRY_HEADER_LEN + DB_CRL_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->derCrl.len >> 8 ) & 0xff; - buf[1] = entry->derCrl.len & 0xff; - buf[2] = ( nnlen >> 8 ) & 0xff; - buf[3] = nnlen & 0xff; - - PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN], entry->derCrl.data, - entry->derCrl.len); - - if (nnlen != 0) { - PORT_Memcpy(&buf[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len], - entry->url, nnlen); - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBCrlEntry(certDBEntryRevocation *entry, SECItem *dbentry) -{ - unsigned int nnlen; - - /* is record long enough for header? */ - if ( dbentry->len < DB_CRL_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->derCrl.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] ); - if ( ( entry->derCrl.len + nnlen + DB_CRL_ENTRY_HEADER_LEN ) - != dbentry->len) { - /* CRL entry is greater than 64 K. Hack to make this continue to work */ - if (dbentry->len >= (0xffff - DB_CRL_ENTRY_HEADER_LEN) - nnlen) { - entry->derCrl.len = - (dbentry->len - DB_CRL_ENTRY_HEADER_LEN) - nnlen; - } else { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - } - - /* copy the dercert */ - entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->derCrl.len); - if ( entry->derCrl.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->derCrl.data, &dbentry->data[DB_CRL_ENTRY_HEADER_LEN], - entry->derCrl.len); - - /* copy the url */ - entry->url = NULL; - if (nnlen != 0) { - entry->url = (char *)PORT_ArenaAlloc(entry->common.arena, nnlen); - if ( entry->url == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->url, - &dbentry->data[DB_CRL_ENTRY_HEADER_LEN + entry->derCrl.len], - nnlen); - } - - return(SECSuccess); -loser: - return(SECFailure); -} - -/* - * Create a new certDBEntryRevocation from existing data - */ -static certDBEntryRevocation * -NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags) -{ - certDBEntryRevocation *entry; - PRArenaPool *arena = NULL; - int nnlen; - - arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE ); - - if ( !arena ) { - goto loser; - } - - entry = PORT_ArenaZNew(arena, certDBEntryRevocation); - if ( entry == NULL ) { - goto loser; - } - - /* fill in the dbRevolcation */ - entry->common.arena = arena; - entry->common.type = crlType; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - - entry->derCrl.data = (unsigned char *)PORT_ArenaAlloc(arena, derCrl->len); - if ( !entry->derCrl.data ) { - goto loser; - } - - if (url) { - nnlen = PORT_Strlen(url) + 1; - entry->url = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( !entry->url ) { - goto loser; - } - PORT_Memcpy(entry->url, url, nnlen); - } else { - entry->url = NULL; - } - - - entry->derCrl.len = derCrl->len; - PORT_Memcpy(entry->derCrl.data, derCrl->data, derCrl->len); - - return(entry); - -loser: - - /* allocation error, free arena and return */ - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - PORT_SetError(SEC_ERROR_NO_MEMORY); - return(0); -} - - -static SECStatus -WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry, - SECItem *crlKey ) -{ - SECItem dbkey; - PRArenaPool *tmparena = NULL; - SECItem encodedEntry; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry); - if ( rv == SECFailure ) { - goto loser; - } - - rv = EncodeDBGenericKey(crlKey, tmparena, &dbkey, entry->common.type); - if ( rv == SECFailure ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &encodedEntry); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); -} -/* - * delete a crl entry - */ -static SECStatus -DeleteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, const SECItem *crlKey, - certDBEntryType crlType) -{ - SECItem dbkey; - PRArenaPool *arena = NULL; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBGenericKey(crlKey, arena, &dbkey, crlType); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, crlType, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read a certificate entry - */ -static certDBEntryRevocation * -ReadDBCrlEntry(NSSLOWCERTCertDBHandle *handle, SECItem *certKey, - certDBEntryType crlType) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryRevocation *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryRevocation *) - PORT_ArenaAlloc(arena, sizeof(certDBEntryRevocation)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = crlType; - - rv = EncodeDBGenericKey(certKey, tmparena, &dbkey, crlType); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, NULL); - if ( rv == SECFailure ) { - goto loser; - } - - rv = DecodeDBCrlEntry(entry, &dbentry); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -void -nsslowcert_DestroyDBEntry(certDBEntry *entry) -{ - DestroyDBEntry(entry); - return; -} - -/* - * Encode a database nickname record - */ -static SECStatus -EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena, - SECItem *dbitem) -{ - unsigned char *buf; - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN + - SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->subjectName.len >> 8 ) & 0xff; - buf[1] = entry->subjectName.len & 0xff; - - PORT_Memcpy(&buf[DB_NICKNAME_ENTRY_HEADER_LEN], entry->subjectName.data, - entry->subjectName.len); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Encode a database key for a nickname record - */ -static SECStatus -EncodeDBNicknameKey(char *nickname, PRArenaPool *arena, - SECItem *dbkey) -{ - unsigned int nnlen; - - nnlen = PORT_Strlen(nickname) + 1; /* includes null */ - - /* now get the database key and format it */ - dbkey->len = nnlen + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], nickname, nnlen); - dbkey->data[0] = certDBEntryTypeNickname; - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBNicknameEntry(certDBEntryNickname *entry, SECItem *dbentry, - char *nickname) -{ - /* is record long enough for header? */ - if ( dbentry->len < DB_NICKNAME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - if (( entry->subjectName.len + DB_NICKNAME_ENTRY_HEADER_LEN ) != - dbentry->len ){ - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy the certkey */ - entry->subjectName.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->subjectName.len); - if ( entry->subjectName.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->subjectName.data, - &dbentry->data[DB_NICKNAME_ENTRY_HEADER_LEN], - entry->subjectName.len); - entry->subjectName.type = siBuffer; - - entry->nickname = (char *)PORT_ArenaAlloc(entry->common.arena, - PORT_Strlen(nickname)+1); - if ( entry->nickname ) { - PORT_Strcpy(entry->nickname, nickname); - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new nickname entry - */ -static certDBEntryNickname * -NewDBNicknameEntry(char *nickname, SECItem *subjectName, unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntryNickname *entry; - int nnlen; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryNickname)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* init common fields */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeNickname; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - /* copy the nickname */ - nnlen = PORT_Strlen(nickname) + 1; - - entry->nickname = (char*)PORT_ArenaAlloc(arena, nnlen); - if ( entry->nickname == NULL ) { - goto loser; - } - - PORT_Memcpy(entry->nickname, nickname, nnlen); - - rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName); - if ( rv != SECSuccess ) { - goto loser; - } - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * delete a nickname entry - */ -static SECStatus -DeleteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - SECItem dbkey; - - if ( nickname == NULL ) { - return(SECSuccess); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBNicknameKey(nickname, arena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeNickname, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read a nickname entry - */ -static certDBEntryNickname * -ReadDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, char *nickname) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryNickname *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryNickname *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryNickname)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeNickname; - - rv = EncodeDBNicknameKey(nickname, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - /* is record long enough for header? */ - if ( dbentry.len < DB_NICKNAME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - rv = DecodeDBNicknameEntry(entry, &dbentry, nickname); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Encode a nickname entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBNicknameEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryNickname *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBNicknameEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBNicknameKey(entry->nickname, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); - -} - -static SECStatus -EncodeDBSMimeEntry(certDBEntrySMime *entry, PRArenaPool *arena, - SECItem *dbitem) -{ - unsigned char *buf; - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = entry->subjectName.len + entry->smimeOptions.len + - entry->optionsDate.len + - DB_SMIME_ENTRY_HEADER_LEN + SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( entry->subjectName.len >> 8 ) & 0xff; - buf[1] = entry->subjectName.len & 0xff; - buf[2] = ( entry->smimeOptions.len >> 8 ) & 0xff; - buf[3] = entry->smimeOptions.len & 0xff; - buf[4] = ( entry->optionsDate.len >> 8 ) & 0xff; - buf[5] = entry->optionsDate.len & 0xff; - - /* if no smime options, then there should not be an options date either */ - PORT_Assert( ! ( ( entry->smimeOptions.len == 0 ) && - ( entry->optionsDate.len != 0 ) ) ); - - PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN], entry->subjectName.data, - entry->subjectName.len); - if ( entry->smimeOptions.len ) { - PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN+entry->subjectName.len], - entry->smimeOptions.data, - entry->smimeOptions.len); - PORT_Memcpy(&buf[DB_SMIME_ENTRY_HEADER_LEN + entry->subjectName.len + - entry->smimeOptions.len], - entry->optionsDate.data, - entry->optionsDate.len); - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Encode a database key for a SMIME record - */ -static SECStatus -EncodeDBSMimeKey(char *emailAddr, PRArenaPool *arena, - SECItem *dbkey) -{ - unsigned int addrlen; - - addrlen = PORT_Strlen(emailAddr) + 1; /* includes null */ - - /* now get the database key and format it */ - dbkey->len = addrlen + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], emailAddr, addrlen); - dbkey->data[0] = certDBEntryTypeSMimeProfile; - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Decode a database SMIME record - */ -static SECStatus -DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr) -{ - /* is record long enough for header? */ - if ( dbentry->len < DB_SMIME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* is database entry correct length? */ - entry->subjectName.len = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - entry->smimeOptions.len = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] ); - entry->optionsDate.len = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] ); - if (( entry->subjectName.len + entry->smimeOptions.len + - entry->optionsDate.len + DB_SMIME_ENTRY_HEADER_LEN ) != dbentry->len){ - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - /* copy the subject name */ - entry->subjectName.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->subjectName.len); - if ( entry->subjectName.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->subjectName.data, - &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN], - entry->subjectName.len); - - /* copy the smime options */ - if ( entry->smimeOptions.len ) { - entry->smimeOptions.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->smimeOptions.len); - if ( entry->smimeOptions.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->smimeOptions.data, - &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN + - entry->subjectName.len], - entry->smimeOptions.len); - } - if ( entry->optionsDate.len ) { - entry->optionsDate.data = - (unsigned char *)PORT_ArenaAlloc(entry->common.arena, - entry->optionsDate.len); - if ( entry->optionsDate.data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->optionsDate.data, - &dbentry->data[DB_SMIME_ENTRY_HEADER_LEN + - entry->subjectName.len + - entry->smimeOptions.len], - entry->optionsDate.len); - } - - /* both options and options date must either exist or not exist */ - if ( ( ( entry->optionsDate.len == 0 ) || - ( entry->smimeOptions.len == 0 ) ) && - entry->smimeOptions.len != entry->optionsDate.len ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena, - PORT_Strlen(emailAddr)+1); - if ( entry->emailAddr ) { - PORT_Strcpy(entry->emailAddr, emailAddr); - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new SMIME entry - */ -static certDBEntrySMime * -NewDBSMimeEntry(char *emailAddr, SECItem *subjectName, SECItem *smimeOptions, - SECItem *optionsDate, unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntrySMime *entry; - int addrlen; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySMime)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* init common fields */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSMimeProfile; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - /* copy the email addr */ - addrlen = PORT_Strlen(emailAddr) + 1; - - entry->emailAddr = (char*)PORT_ArenaAlloc(arena, addrlen); - if ( entry->emailAddr == NULL ) { - goto loser; - } - - PORT_Memcpy(entry->emailAddr, emailAddr, addrlen); - - /* copy the subject name */ - rv = SECITEM_CopyItem(arena, &entry->subjectName, subjectName); - if ( rv != SECSuccess ) { - goto loser; - } - - /* copy the smime options */ - if ( smimeOptions ) { - rv = SECITEM_CopyItem(arena, &entry->smimeOptions, smimeOptions); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - PORT_Assert(optionsDate == NULL); - entry->smimeOptions.data = NULL; - entry->smimeOptions.len = 0; - } - - /* copy the options date */ - if ( optionsDate ) { - rv = SECITEM_CopyItem(arena, &entry->optionsDate, optionsDate); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - PORT_Assert(smimeOptions == NULL); - entry->optionsDate.data = NULL; - entry->optionsDate.len = 0; - } - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * delete a SMIME entry - */ -static SECStatus -DeleteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr) -{ - PRArenaPool *arena = NULL; - SECStatus rv; - SECItem dbkey; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBSMimeKey(emailAddr, arena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeSMimeProfile, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read a SMIME entry - */ -certDBEntrySMime * -nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntrySMime *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySMime)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSMimeProfile; - - rv = EncodeDBSMimeKey(emailAddr, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - /* is record long enough for header? */ - if ( dbentry.len < DB_SMIME_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - rv = DecodeDBSMimeEntry(entry, &dbentry, emailAddr); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Encode a SMIME entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySMime *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBSMimeEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBSMimeKey(entry->emailAddr, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); - -} - -/* - * Encode a database subject record - */ -static SECStatus -EncodeDBSubjectEntry(certDBEntrySubject *entry, PRArenaPool *arena, - SECItem *dbitem) -{ - unsigned char *buf; - int len; - unsigned int ncerts; - unsigned int i; - unsigned char *tmpbuf; - unsigned int nnlen = 0; - unsigned int eaddrslen = 0; - int keyidoff; - SECItem *certKeys; - SECItem *keyIDs; - - if ( entry->nickname ) { - nnlen = PORT_Strlen(entry->nickname) + 1; - } - if ( entry->emailAddrs ) { - eaddrslen = 2; - for (i=0; i < entry->nemailAddrs; i++) { - eaddrslen += PORT_Strlen(entry->emailAddrs[i]) + 1 + 2; - } - } - - ncerts = entry->ncerts; - - /* compute the length of the entry */ - keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen ; - len = keyidoff + 4 * ncerts + eaddrslen; - for ( i = 0; i < ncerts; i++ ) { - len += entry->certKeys[i].len; - len += entry->keyIDs[i].len; - } - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem->len = len + SEC_DB_ENTRY_HEADER_LEN; - - dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); - if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* fill in database record */ - buf = &dbitem->data[SEC_DB_ENTRY_HEADER_LEN]; - - buf[0] = ( ncerts >> 8 ) & 0xff; - buf[1] = ncerts & 0xff; - buf[2] = ( nnlen >> 8 ) & 0xff; - buf[3] = nnlen & 0xff; - /* v7 email field is NULL in v8 */ - buf[4] = 0; - buf[5] = 0; - - PORT_Memcpy(&buf[DB_SUBJECT_ENTRY_HEADER_LEN], entry->nickname, nnlen); - - for ( i = 0; i < ncerts; i++ ) { - - certKeys = entry->certKeys; - keyIDs = entry->keyIDs; - - buf[keyidoff+i*2] = ( certKeys[i].len >> 8 ) & 0xff; - buf[keyidoff+1+i*2] = certKeys[i].len & 0xff; - buf[keyidoff+ncerts*2+i*2] = ( keyIDs[i].len >> 8 ) & 0xff; - buf[keyidoff+1+ncerts*2+i*2] = keyIDs[i].len & 0xff; - } - - /* temp pointer used to stuff certkeys and keyids into the buffer */ - tmpbuf = &buf[keyidoff+ncerts*4]; - - for ( i = 0; i < ncerts; i++ ) { - certKeys = entry->certKeys; - PORT_Memcpy(tmpbuf, certKeys[i].data, certKeys[i].len); - tmpbuf = tmpbuf + certKeys[i].len; - } - - for ( i = 0; i < ncerts; i++ ) { - keyIDs = entry->keyIDs; - PORT_Memcpy(tmpbuf, keyIDs[i].data, keyIDs[i].len); - tmpbuf = tmpbuf + keyIDs[i].len; - } - - if (entry->emailAddrs) { - tmpbuf[0] = (entry->nemailAddrs >> 8) & 0xff; - tmpbuf[1] = entry->nemailAddrs & 0xff; - tmpbuf += 2; - for (i=0; i < entry->nemailAddrs; i++) { - int nameLen = PORT_Strlen(entry->emailAddrs[i]) + 1; - tmpbuf[0] = (nameLen >> 8) & 0xff; - tmpbuf[1] = nameLen & 0xff; - tmpbuf += 2; - PORT_Memcpy(tmpbuf,entry->emailAddrs[i],nameLen); - tmpbuf +=nameLen; - } - } - - PORT_Assert(tmpbuf == &buf[len]); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * Encode a database key for a subject record - */ -static SECStatus -EncodeDBSubjectKey(SECItem *derSubject, PRArenaPool *arena, - SECItem *dbkey) -{ - dbkey->len = derSubject->len + SEC_DB_KEY_HEADER_LEN; - dbkey->data = (unsigned char *)PORT_ArenaAlloc(arena, dbkey->len); - if ( dbkey->data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey->data[SEC_DB_KEY_HEADER_LEN], derSubject->data, - derSubject->len); - dbkey->data[0] = certDBEntryTypeSubject; - - return(SECSuccess); - -loser: - return(SECFailure); -} - -static SECStatus -DecodeDBSubjectEntry(certDBEntrySubject *entry, SECItem *dbentry, - const SECItem *derSubject) -{ - unsigned int ncerts; - PRArenaPool *arena; - unsigned int len, itemlen; - unsigned char *tmpbuf; - unsigned char *end; - unsigned int i; - SECStatus rv; - unsigned int keyidoff; - unsigned int nnlen, eaddrlen; - unsigned int stdlen; - - arena = entry->common.arena; - - rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject); - if ( rv != SECSuccess ) { - goto loser; - } - - /* is record long enough for header? */ - if ( dbentry->len < DB_SUBJECT_ENTRY_HEADER_LEN ) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - entry->ncerts = ncerts = ( ( dbentry->data[0] << 8 ) | dbentry->data[1] ); - nnlen = ( ( dbentry->data[2] << 8 ) | dbentry->data[3] ); - eaddrlen = ( ( dbentry->data[4] << 8 ) | dbentry->data[5] ); - stdlen = ncerts * 4 + DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen; - if ( dbentry->len < stdlen) { - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, - sizeof(SECItem) * ncerts); - entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, - sizeof(SECItem) * ncerts); - - if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - if ( nnlen > 1 ) { /* null terminator is stored */ - entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( entry->nickname == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->nickname, - &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN], - nnlen); - } else { - entry->nickname = NULL; - } - - /* if we have an old style email entry, there is only one */ - entry->nemailAddrs = 0; - if ( eaddrlen > 1 ) { /* null terminator is stored */ - entry->emailAddrs = (char **)PORT_ArenaAlloc(arena, sizeof(char *)); - if ( entry->emailAddrs == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->emailAddrs[0] = (char *)PORT_ArenaAlloc(arena, eaddrlen); - if ( entry->emailAddrs[0] == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->emailAddrs[0], - &dbentry->data[DB_SUBJECT_ENTRY_HEADER_LEN+nnlen], - eaddrlen); - entry->nemailAddrs = 1; - } else { - entry->emailAddrs = NULL; - } - - /* collect the lengths of the certKeys and keyIDs, and total the - * overall length. - */ - keyidoff = DB_SUBJECT_ENTRY_HEADER_LEN + nnlen + eaddrlen; - len = keyidoff + 4 * ncerts; - - tmpbuf = &dbentry->data[0]; - - for ( i = 0; i < ncerts; i++ ) { - - itemlen = ( tmpbuf[keyidoff + 2*i] << 8 ) | tmpbuf[keyidoff + 1 + 2*i] ; - len += itemlen; - entry->certKeys[i].len = itemlen; - - itemlen = ( tmpbuf[keyidoff + 2*ncerts + 2*i] << 8 ) | - tmpbuf[keyidoff + 1 + 2*ncerts + 2*i] ; - len += itemlen; - entry->keyIDs[i].len = itemlen; - } - - /* is database entry correct length? */ - if ( len > dbentry->len ){ - PORT_SetError(SEC_ERROR_BAD_DATABASE); - goto loser; - } - - tmpbuf = &tmpbuf[keyidoff + 4*ncerts]; - for ( i = 0; i < ncerts; i++ ) { - entry->certKeys[i].data = - (unsigned char *)PORT_ArenaAlloc(arena, entry->certKeys[i].len); - if ( entry->certKeys[i].data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->certKeys[i].data, tmpbuf, entry->certKeys[i].len); - tmpbuf = &tmpbuf[entry->certKeys[i].len]; - } - - for ( i = 0; i < ncerts; i++ ) { - entry->keyIDs[i].data = - (unsigned char *)PORT_ArenaAlloc(arena, entry->keyIDs[i].len); - if ( entry->keyIDs[i].data == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - PORT_Memcpy(entry->keyIDs[i].data, tmpbuf, entry->keyIDs[i].len); - tmpbuf = &tmpbuf[entry->keyIDs[i].len]; - } - - end = &dbentry->data[dbentry->len]; - if ((eaddrlen == 0) && (tmpbuf+1 < end)) { - /* read in the additional email addresses */ - entry->nemailAddrs = tmpbuf[0] << 8 | tmpbuf[1]; - tmpbuf += 2; - entry->emailAddrs = (char **) - PORT_ArenaAlloc(arena, entry->nemailAddrs * sizeof(char *)); - if (entry->emailAddrs == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - for (i=0; i < entry->nemailAddrs; i++) { - int nameLen; - if (tmpbuf + 2 > end) { - goto loser; - } - - nameLen = tmpbuf[0] << 8 | tmpbuf[1]; - entry->emailAddrs[i] = PORT_ArenaAlloc(arena,nameLen); - if (entry->emailAddrs == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - if (tmpbuf + (nameLen+2) > end) { - goto loser; - } - PORT_Memcpy(entry->emailAddrs[i],&tmpbuf[2],nameLen); - tmpbuf += 2 + nameLen; - } - } - - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new subject entry with a single cert - */ -static certDBEntrySubject * -NewDBSubjectEntry(SECItem *derSubject, SECItem *certKey, - SECItem *keyID, char *nickname, char *emailAddr, - unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntrySubject *entry; - SECStatus rv; - unsigned int nnlen; - unsigned int eaddrlen; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySubject)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* init common fields */ - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSubject; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - /* copy the subject */ - rv = SECITEM_CopyItem(arena, &entry->derSubject, derSubject); - if ( rv != SECSuccess ) { - goto loser; - } - - entry->ncerts = 1; - entry->nemailAddrs = 0; - /* copy nickname */ - if ( nickname && ( *nickname != '\0' ) ) { - nnlen = PORT_Strlen(nickname) + 1; - entry->nickname = (char *)PORT_ArenaAlloc(arena, nnlen); - if ( entry->nickname == NULL ) { - goto loser; - } - - PORT_Memcpy(entry->nickname, nickname, nnlen); - } else { - entry->nickname = NULL; - } - - /* copy email addr */ - if ( emailAddr && ( *emailAddr != '\0' ) ) { - emailAddr = nsslowcert_FixupEmailAddr(emailAddr); - if ( emailAddr == NULL ) { - entry->emailAddrs = NULL; - goto loser; - } - - eaddrlen = PORT_Strlen(emailAddr) + 1; - entry->emailAddrs = (char **)PORT_ArenaAlloc(arena, sizeof(char *)); - if ( entry->emailAddrs == NULL ) { - PORT_Free(emailAddr); - goto loser; - } - entry->emailAddrs[0] = PORT_ArenaStrdup(arena,emailAddr); - if (entry->emailAddrs[0]) { - entry->nemailAddrs = 1; - } - - PORT_Free(emailAddr); - } else { - entry->emailAddrs = NULL; - } - - /* allocate space for certKeys and keyIDs */ - entry->certKeys = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); - entry->keyIDs = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); - if ( ( entry->certKeys == NULL ) || ( entry->keyIDs == NULL ) ) { - goto loser; - } - - /* copy the certKey and keyID */ - rv = SECITEM_CopyItem(arena, &entry->certKeys[0], certKey); - if ( rv != SECSuccess ) { - goto loser; - } - rv = SECITEM_CopyItem(arena, &entry->keyIDs[0], keyID); - if ( rv != SECSuccess ) { - goto loser; - } - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * delete a subject entry - */ -static SECStatus -DeleteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject) -{ - SECItem dbkey; - PRArenaPool *arena = NULL; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBSubjectKey(derSubject, arena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = DeleteDBEntry(handle, certDBEntryTypeSubject, &dbkey); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - return(SECSuccess); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(SECFailure); -} - -/* - * Read the subject entry - */ -static certDBEntrySubject * -ReadDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntrySubject *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena, - sizeof(certDBEntrySubject)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeSubject; - - rv = EncodeDBSubjectKey(derSubject, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if ( rv == SECFailure ) { - goto loser; - } - - rv = DecodeDBSubjectEntry(entry, &dbentry, derSubject); - if ( rv == SECFailure ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Encode a subject name entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, certDBEntrySubject *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - rv = EncodeDBSubjectEntry(entry, tmparena, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBSubjectKey(&entry->derSubject, tmparena, &dbkey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); - -} - -typedef enum { nsslowcert_remove, nsslowcert_add } nsslowcertUpdateType; - -static SECStatus -nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle, - SECItem *derSubject, char *emailAddr, nsslowcertUpdateType updateType) -{ - certDBEntrySubject *entry = NULL; - int index = -1, i; - SECStatus rv; - - if (emailAddr) { - emailAddr = nsslowcert_FixupEmailAddr(emailAddr); - if (emailAddr == NULL) { - return SECFailure; - } - } else { - return SECSuccess; - } - - entry = ReadDBSubjectEntry(dbhandle,derSubject); - if (entry == NULL) { - rv = SECFailure; - goto done; - } - - for (i=0; i < (int)(entry->nemailAddrs); i++) { - if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) { - index = i; - } - } - - if (updateType == nsslowcert_remove) { - if (index == -1) { - rv = SECSuccess; - goto done; - } - entry->nemailAddrs--; - for (i=index; i < (int)(entry->nemailAddrs); i++) { - entry->emailAddrs[i] = entry->emailAddrs[i+1]; - } - } else { - char **newAddrs = NULL; - - if (index != -1) { - rv = SECSuccess; - goto done; - } - newAddrs = (char **)PORT_ArenaAlloc(entry->common.arena, - (entry->nemailAddrs+1)* sizeof(char *)); - if (!newAddrs) { - rv = SECFailure; - goto done; - } - for (i=0; i < (int)(entry->nemailAddrs); i++) { - newAddrs[i] = entry->emailAddrs[i]; - } - newAddrs[entry->nemailAddrs] = - PORT_ArenaStrdup(entry->common.arena,emailAddr); - if (!newAddrs[entry->nemailAddrs]) { - rv = SECFailure; - goto done; - } - entry->emailAddrs = newAddrs; - entry->nemailAddrs++; - } - - /* delete the subject entry */ - DeleteDBSubjectEntry(dbhandle, derSubject); - - /* write the new one */ - rv = WriteDBSubjectEntry(dbhandle, entry); - - done: - if (entry) DestroyDBEntry((certDBEntry *)entry); - if (emailAddr) PORT_Free(emailAddr); - return rv; -} - -/* - * writes a nickname to an existing subject entry that does not currently - * have one - */ -static SECStatus -AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle, - NSSLOWCERTCertificate *cert, char *nickname) -{ - certDBEntrySubject *entry; - SECStatus rv; - - if ( nickname == NULL ) { - return(SECFailure); - } - - entry = ReadDBSubjectEntry(dbhandle,&cert->derSubject); - PORT_Assert(entry != NULL); - if ( entry == NULL ) { - goto loser; - } - - PORT_Assert(entry->nickname == NULL); - if ( entry->nickname != NULL ) { - goto loser; - } - - entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname); - - if ( entry->nickname == NULL ) { - goto loser; - } - - /* delete the subject entry */ - DeleteDBSubjectEntry(dbhandle, &cert->derSubject); - - /* write the new one */ - rv = WriteDBSubjectEntry(dbhandle, entry); - if ( rv != SECSuccess ) { - goto loser; - } - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * create a new version entry - */ -static certDBEntryVersion * -NewDBVersionEntry(unsigned int flags) -{ - PRArenaPool *arena = NULL; - certDBEntryVersion *entry; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryVersion)); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeVersion; - entry->common.version = CERT_DB_FILE_VERSION; - entry->common.flags = flags; - - return(entry); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - -/* - * Read the version entry - */ -static certDBEntryVersion * -ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle) -{ - PRArenaPool *arena = NULL; - PRArenaPool *tmparena = NULL; - certDBEntryVersion *entry; - SECItem dbkey; - SECItem dbentry; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - entry = PORT_ArenaZNew(arena, certDBEntryVersion); - if ( entry == NULL ) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - entry->common.arena = arena; - entry->common.type = certDBEntryTypeVersion; - - /* now get the database key and format it */ - dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN; - dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len); - if ( dbkey.data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY, - SEC_DB_VERSION_KEY_LEN); - - rv = ReadDBEntry(handle, &entry->common, &dbkey, &dbentry, tmparena); - if (rv != SECSuccess) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(entry); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(NULL); -} - - -/* - * Encode a version entry into byte stream suitable for - * the database - */ -static SECStatus -WriteDBVersionEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryVersion *entry) -{ - SECItem dbitem, dbkey; - PRArenaPool *tmparena = NULL; - SECStatus rv; - - tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( tmparena == NULL ) { - goto loser; - } - - /* allocate space for encoded database record, including space - * for low level header - */ - dbitem.len = SEC_DB_ENTRY_HEADER_LEN; - - dbitem.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbitem.len); - if ( dbitem.data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - /* now get the database key and format it */ - dbkey.len = SEC_DB_VERSION_KEY_LEN + SEC_DB_KEY_HEADER_LEN; - dbkey.data = (unsigned char *)PORT_ArenaAlloc(tmparena, dbkey.len); - if ( dbkey.data == NULL ) { - goto loser; - } - PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], SEC_DB_VERSION_KEY, - SEC_DB_VERSION_KEY_LEN); - - /* now write it to the database */ - rv = WriteDBEntry(handle, &entry->common, &dbkey, &dbitem); - if ( rv != SECSuccess ) { - goto loser; - } - - PORT_FreeArena(tmparena, PR_FALSE); - return(SECSuccess); - -loser: - if ( tmparena ) { - PORT_FreeArena(tmparena, PR_FALSE); - } - return(SECFailure); -} - -/* - * cert is no longer a perm cert, but will remain a temp cert - */ -static SECStatus -RemovePermSubjectNode(NSSLOWCERTCertificate *cert) -{ - certDBEntrySubject *entry; - unsigned int i; - SECStatus rv; - - entry = ReadDBSubjectEntry(cert->dbhandle,&cert->derSubject); - if ( entry == NULL ) { - return(SECFailure); - } - - PORT_Assert(entry->ncerts); - rv = SECFailure; - - if ( entry->ncerts > 1 ) { - for ( i = 0; i < entry->ncerts; i++ ) { - if ( SECITEM_CompareItem(&entry->certKeys[i], &cert->certKey) == - SECEqual ) { - /* copy rest of list forward one entry */ - for ( i = i + 1; i < entry->ncerts; i++ ) { - entry->certKeys[i-1] = entry->certKeys[i]; - entry->keyIDs[i-1] = entry->keyIDs[i]; - } - entry->ncerts--; - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - rv = WriteDBSubjectEntry(cert->dbhandle, entry); - break; - } - } - } else { - /* no entries left, delete the perm entry in the DB */ - if ( entry->emailAddrs ) { - /* if the subject had an email record, then delete it too */ - for (i=0; i < entry->nemailAddrs; i++) { - DeleteDBSMimeEntry(cert->dbhandle, entry->emailAddrs[i]); - } - } - if ( entry->nickname ) { - DeleteDBNicknameEntry(cert->dbhandle, entry->nickname); - } - - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - } - DestroyDBEntry((certDBEntry *)entry); - - return(rv); -} - -/* - * add a cert to the perm subject list - */ -static SECStatus -AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert, - char *nickname) -{ - SECItem *newCertKeys, *newKeyIDs; - unsigned int i, new_i; - SECStatus rv; - unsigned int ncerts; - - PORT_Assert(entry); - ncerts = entry->ncerts; - - if ( nickname && entry->nickname ) { - /* nicknames must be the same */ - PORT_Assert(PORT_Strcmp(nickname, entry->nickname) == 0); - } - - if ( ( entry->nickname == NULL ) && ( nickname != NULL ) ) { - /* copy nickname into the entry */ - entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname); - if ( entry->nickname == NULL ) { - return(SECFailure); - } - } - - /* a DB entry already exists, so add this cert */ - newCertKeys = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1); - newKeyIDs = PORT_ArenaZNewArray(entry->common.arena, SECItem, ncerts + 1); - - if ( ( newCertKeys == NULL ) || ( newKeyIDs == NULL ) ) { - return(SECFailure); - } - - /* Step 1: copy certs older than "cert" into new entry. */ - for ( i = 0, new_i=0; i < ncerts; i++ ) { - NSSLOWCERTCertificate *cmpcert; - PRBool isNewer; - cmpcert = nsslowcert_FindCertByKey(cert->dbhandle, - &entry->certKeys[i]); - /* The entry has been corrupted, remove it from the list */ - if (!cmpcert) { - continue; - } - - isNewer = nsslowcert_IsNewer(cert, cmpcert); - nsslowcert_DestroyCertificate(cmpcert); - if ( isNewer ) - break; - /* copy this cert entry */ - newCertKeys[new_i] = entry->certKeys[i]; - newKeyIDs[new_i] = entry->keyIDs[i]; - new_i++; - } - - /* Step 2: Add "cert" to the entry. */ - rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i], - &cert->certKey); - if ( rv != SECSuccess ) { - return(SECFailure); - } - rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i], - &cert->subjectKeyID); - if ( rv != SECSuccess ) { - return(SECFailure); - } - new_i++; - - /* Step 3: copy remaining certs (if any) from old entry to new. */ - for ( ; i < ncerts; i++ ,new_i++) { - newCertKeys[new_i] = entry->certKeys[i]; - newKeyIDs[new_i] = entry->keyIDs[i]; - } - - /* update certKeys and keyIDs */ - entry->certKeys = newCertKeys; - entry->keyIDs = newKeyIDs; - - /* set new count value */ - entry->ncerts = new_i; - - DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject); - rv = WriteDBSubjectEntry(cert->dbhandle, entry); - return(rv); -} - - -SECStatus -nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle, - SECItem *derSubject, - NSSLOWCERTCertCallback cb, void *cbarg) -{ - certDBEntrySubject *entry; - unsigned int i; - NSSLOWCERTCertificate *cert; - SECStatus rv = SECSuccess; - - entry = ReadDBSubjectEntry(handle, derSubject); - - if ( entry == NULL ) { - return(SECFailure); - } - - for( i = 0; i < entry->ncerts; i++ ) { - cert = nsslowcert_FindCertByKey(handle, &entry->certKeys[i]); - if (!cert) { - continue; - } - rv = (* cb)(cert, cbarg); - nsslowcert_DestroyCertificate(cert); - if ( rv == SECFailure ) { - break; - } - } - - DestroyDBEntry((certDBEntry *)entry); - - return(rv); -} - -int -nsslowcert_NumPermCertsForSubject(NSSLOWCERTCertDBHandle *handle, - SECItem *derSubject) -{ - certDBEntrySubject *entry; - int ret; - - entry = ReadDBSubjectEntry(handle, derSubject); - - if ( entry == NULL ) { - return(SECFailure); - } - - ret = entry->ncerts; - - DestroyDBEntry((certDBEntry *)entry); - - return(ret); -} - -SECStatus -nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle, - char *nickname, NSSLOWCERTCertCallback cb, void *cbarg) -{ - certDBEntryNickname *nnentry = NULL; - certDBEntrySMime *smentry = NULL; - SECStatus rv; - SECItem *derSubject = NULL; - - nnentry = ReadDBNicknameEntry(handle, nickname); - if ( nnentry ) { - derSubject = &nnentry->subjectName; - } else { - smentry = nsslowcert_ReadDBSMimeEntry(handle, nickname); - if ( smentry ) { - derSubject = &smentry->subjectName; - } - } - - if ( derSubject ) { - rv = nsslowcert_TraversePermCertsForSubject(handle, derSubject, - cb, cbarg); - } else { - rv = SECFailure; - } - - if ( nnentry ) { - DestroyDBEntry((certDBEntry *)nnentry); - } - if ( smentry ) { - DestroyDBEntry((certDBEntry *)smentry); - } - - return(rv); -} - -int -nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle, - char *nickname) -{ - certDBEntryNickname *entry; - int ret; - - entry = ReadDBNicknameEntry(handle, nickname); - - if ( entry ) { - ret = nsslowcert_NumPermCertsForSubject(handle, &entry->subjectName); - DestroyDBEntry((certDBEntry *)entry); - } else { - ret = 0; - } - return(ret); -} - -/* - * add a nickname to a cert that doesn't have one - */ -static SECStatus -AddNicknameToPermCert(NSSLOWCERTCertDBHandle *dbhandle, - NSSLOWCERTCertificate *cert, char *nickname) -{ - certDBEntryCert *entry; - int rv; - - entry = cert->dbEntry; - PORT_Assert(entry != NULL); - if ( entry == NULL ) { - goto loser; - } - - pkcs11_freeNickname(entry->nickname,entry->nicknameSpace); - entry->nickname = NULL; - entry->nickname = pkcs11_copyNickname(nickname,entry->nicknameSpace, - sizeof(entry->nicknameSpace)); - - rv = WriteDBCertEntry(dbhandle, entry); - if ( rv ) { - goto loser; - } - - pkcs11_freeNickname(cert->nickname,cert->nicknameSpace); - cert->nickname = NULL; - cert->nickname = pkcs11_copyNickname(nickname,cert->nicknameSpace, - sizeof(cert->nicknameSpace)); - - return(SECSuccess); - -loser: - return(SECFailure); -} - -/* - * add a nickname to a cert that is already in the perm database, but doesn't - * have one yet (it is probably an e-mail cert). - */ -SECStatus -nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle, - NSSLOWCERTCertificate *cert, char *nickname) -{ - SECStatus rv = SECFailure; - certDBEntrySubject *entry = NULL; - certDBEntryNickname *nicknameEntry = NULL; - - nsslowcert_LockDB(dbhandle); - - entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject); - if (entry == NULL) goto loser; - - if ( entry->nickname == NULL ) { - - /* no nickname for subject */ - rv = AddNicknameToSubject(dbhandle, cert, nickname); - if ( rv != SECSuccess ) { - goto loser; - } - rv = AddNicknameToPermCert(dbhandle, cert, nickname); - if ( rv != SECSuccess ) { - goto loser; - } - nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0); - if ( nicknameEntry == NULL ) { - goto loser; - } - - rv = WriteDBNicknameEntry(dbhandle, nicknameEntry); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - /* subject already has a nickname */ - rv = AddNicknameToPermCert(dbhandle, cert, entry->nickname); - if ( rv != SECSuccess ) { - goto loser; - } - /* make sure nickname entry exists. If the database was corrupted, - * we may have lost the nickname entry. Add it back now */ - nicknameEntry = ReadDBNicknameEntry(dbhandle, entry->nickname); - if (nicknameEntry == NULL ) { - nicknameEntry = NewDBNicknameEntry(entry->nickname, - &cert->derSubject, 0); - if ( nicknameEntry == NULL ) { - goto loser; - } - - rv = WriteDBNicknameEntry(dbhandle, nicknameEntry); - if ( rv != SECSuccess ) { - goto loser; - } - } - } - rv = SECSuccess; - -loser: - if (entry) { - DestroyDBEntry((certDBEntry *)entry); - } - if (nicknameEntry) { - DestroyDBEntry((certDBEntry *)nicknameEntry); - } - nsslowcert_UnlockDB(dbhandle); - return(rv); -} - -static certDBEntryCert * -AddCertToPermDB(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCertificate *cert, - char *nickname, NSSLOWCERTCertTrust *trust) -{ - certDBEntryCert *certEntry = NULL; - certDBEntryNickname *nicknameEntry = NULL; - certDBEntrySubject *subjectEntry = NULL; - int state = 0; - SECStatus rv; - PRBool donnentry = PR_FALSE; - - if ( nickname ) { - donnentry = PR_TRUE; - } - - subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject); - - if ( subjectEntry && subjectEntry->nickname ) { - donnentry = PR_FALSE; - nickname = subjectEntry->nickname; - } - - certEntry = NewDBCertEntry(&cert->derCert, nickname, trust, 0); - if ( certEntry == NULL ) { - goto loser; - } - - if ( donnentry ) { - nicknameEntry = NewDBNicknameEntry(nickname, &cert->derSubject, 0); - if ( nicknameEntry == NULL ) { - goto loser; - } - } - - rv = WriteDBCertEntry(handle, certEntry); - if ( rv != SECSuccess ) { - goto loser; - } - state = 1; - - if ( nicknameEntry ) { - rv = WriteDBNicknameEntry(handle, nicknameEntry); - if ( rv != SECSuccess ) { - goto loser; - } - } - - state = 2; - - /* "Change" handles if necessary */ - cert->dbhandle = handle; - - /* add to or create new subject entry */ - if ( subjectEntry ) { - /* REWRITE BASED ON SUBJECT ENTRY */ - rv = AddPermSubjectNode(subjectEntry, cert, nickname); - if ( rv != SECSuccess ) { - goto loser; - } - } else { - /* make a new subject entry - this case is only used when updating - * an old version of the database. This is OK because the oldnickname - * db format didn't allow multiple certs with the same subject. - */ - /* where does subjectKeyID and certKey come from? */ - subjectEntry = NewDBSubjectEntry(&cert->derSubject, &cert->certKey, - &cert->subjectKeyID, nickname, - NULL, 0); - if ( subjectEntry == NULL ) { - goto loser; - } - rv = WriteDBSubjectEntry(handle, subjectEntry); - if ( rv != SECSuccess ) { - goto loser; - } - } - - state = 3; - - if ( nicknameEntry ) { - DestroyDBEntry((certDBEntry *)nicknameEntry); - } - - if ( subjectEntry ) { - DestroyDBEntry((certDBEntry *)subjectEntry); - } - - return(certEntry); - -loser: - /* don't leave partial entry in the database */ - if ( state > 0 ) { - rv = DeleteDBCertEntry(handle, &cert->certKey); - } - if ( ( state > 1 ) && donnentry ) { - rv = DeleteDBNicknameEntry(handle, nickname); - } - if ( state > 2 ) { - rv = DeleteDBSubjectEntry(handle, &cert->derSubject); - } - if ( certEntry ) { - DestroyDBEntry((certDBEntry *)certEntry); - } - if ( nicknameEntry ) { - DestroyDBEntry((certDBEntry *)nicknameEntry); - } - if ( subjectEntry ) { - DestroyDBEntry((certDBEntry *)subjectEntry); - } - - return(NULL); -} - -/* forward declaration */ -static SECStatus -UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb); - -/* - * version 8 uses the same schema as version 7. The only differences are - * 1) version 8 db uses the blob shim to store data entries > 32k. - * 2) version 8 db sets the db block size to 32k. - * both of these are dealt with by the handle. - */ - -static SECStatus -UpdateV8DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb) -{ - return UpdateV7DB(handle,updatedb); -} - - -/* - * we could just blindly sequence through reading key data pairs and writing - * them back out, but some cert.db's have gotten quite large and may have some - * subtle corruption problems, so instead we cycle through the certs and - * CRL's and S/MIME profiles and rebuild our subject lists from those records. - */ -static SECStatus -UpdateV7DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb) -{ - DBT key, data; - int ret; - NSSLOWCERTCertificate *cert; - PRBool isKRL = PR_FALSE; - certDBEntryType entryType; - SECItem dbEntry, dbKey; - certDBEntryRevocation crlEntry; - certDBEntryCert certEntry; - certDBEntrySMime smimeEntry; - SECStatus rv; - - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - - if ( ret ) { - return(SECFailure); - } - - do { - unsigned char *dataBuf = (unsigned char *)data.data; - unsigned char *keyBuf = (unsigned char *)key.data; - dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN]; - dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN; - entryType = (certDBEntryType) keyBuf[0]; - dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN]; - dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN; - if ((dbEntry.len <= 0) || (dbKey.len <= 0)) { - continue; - } - - switch (entryType) { - /* these entries will get regenerated as we read the - * rest of the data from the database */ - case certDBEntryTypeVersion: - case certDBEntryTypeSubject: - case certDBEntryTypeContentVersion: - case certDBEntryTypeNickname: - /* smime profiles need entries created after the certs have - * been imported, loop over them in a second run */ - case certDBEntryTypeSMimeProfile: - break; - - case certDBEntryTypeCert: - /* decode Entry */ - certEntry.common.version = (unsigned int)dataBuf[0]; - certEntry.common.type = entryType; - certEntry.common.flags = (unsigned int)dataBuf[2]; - rv = DecodeDBCertEntry(&certEntry,&dbEntry); - if (rv != SECSuccess) { - break; - } - /* should we check for existing duplicates? */ - cert = nsslowcert_DecodeDERCertificate(&certEntry.derCert, - certEntry.nickname); - if (cert) { - nsslowcert_UpdatePermCert(handle, cert, certEntry.nickname, - &certEntry.trust); - nsslowcert_DestroyCertificate(cert); - } - /* free any data the decode may have allocated. */ - pkcs11_freeStaticData(certEntry.derCert.data, - certEntry.derCertSpace); - pkcs11_freeNickname(certEntry.nickname, certEntry.nicknameSpace); - break; - - case certDBEntryTypeKeyRevocation: - isKRL = PR_TRUE; - /* fall through */ - case certDBEntryTypeRevocation: - crlEntry.common.version = (unsigned int)dataBuf[0]; - crlEntry.common.type = entryType; - crlEntry.common.flags = (unsigned int)dataBuf[2]; - crlEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (crlEntry.common.arena == NULL) { - break; - } - rv = DecodeDBCrlEntry(&crlEntry,&dbEntry); - if (rv != SECSuccess) { - break; - } - nsslowcert_UpdateCrl(handle, &crlEntry.derCrl, &dbKey, - crlEntry.url, isKRL); - /* free data allocated by the decode */ - PORT_FreeArena(crlEntry.common.arena, PR_FALSE); - crlEntry.common.arena = NULL; - break; - - default: - break; - } - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - /* now loop again updating just the SMimeProfile. */ - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - - if ( ret ) { - return(SECFailure); - } - - do { - unsigned char *dataBuf = (unsigned char *)data.data; - unsigned char *keyBuf = (unsigned char *)key.data; - dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN]; - dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN; - entryType = (certDBEntryType) keyBuf[0]; - if (entryType != certDBEntryTypeSMimeProfile) { - continue; - } - dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN]; - dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN; - if ((dbEntry.len <= 0) || (dbKey.len <= 0)) { - continue; - } - smimeEntry.common.version = (unsigned int)dataBuf[0]; - smimeEntry.common.type = entryType; - smimeEntry.common.flags = (unsigned int)dataBuf[2]; - smimeEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - /* decode entry */ - rv = DecodeDBSMimeEntry(&smimeEntry,&dbEntry,(char *)dbKey.data); - if (rv == SECSuccess) { - nsslowcert_UpdateSMimeProfile(handle, smimeEntry.emailAddr, - &smimeEntry.subjectName, &smimeEntry.smimeOptions, - &smimeEntry.optionsDate); - } - PORT_FreeArena(smimeEntry.common.arena, PR_FALSE); - smimeEntry.common.arena = NULL; - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - (* updatedb->close)(updatedb); - - /* a database update is a good time to go back and verify the integrity of - * the keys and certs */ - handle->dbVerify = PR_TRUE; - return(SECSuccess); -} - -/* - * NOTE - Version 6 DB did not go out to the real world in a release, - * so we can remove this function in a later release. - */ -static SECStatus -UpdateV6DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb) -{ - int ret; - DBT key, data; - unsigned char *buf, *tmpbuf = NULL; - certDBEntryType type; - certDBEntryNickname *nnEntry = NULL; - certDBEntrySubject *subjectEntry = NULL; - certDBEntrySMime *emailEntry = NULL; - char *nickname; - char *emailAddr; - SECStatus rv; - - /* - * Sequence through the old database and copy all of the entries - * to the new database. Subject name entries will have the new - * fields inserted into them (with zero length). - */ - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - if ( ret ) { - return(SECFailure); - } - - do { - buf = (unsigned char *)data.data; - - if ( data.size >= 3 ) { - if ( buf[0] == 6 ) { /* version number */ - type = (certDBEntryType)buf[1]; - if ( type == certDBEntryTypeSubject ) { - /* expando subjecto entrieo */ - tmpbuf = (unsigned char *)PORT_Alloc(data.size + 4); - if ( tmpbuf ) { - /* copy header stuff */ - PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN + 2); - /* insert 4 more bytes of zero'd header */ - PORT_Memset(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 2], - 0, 4); - /* copy rest of the data */ - PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6], - &buf[SEC_DB_ENTRY_HEADER_LEN + 2], - data.size - (SEC_DB_ENTRY_HEADER_LEN + 2)); - - data.data = (void *)tmpbuf; - data.size += 4; - buf = tmpbuf; - } - } else if ( type == certDBEntryTypeCert ) { - /* expando certo entrieo */ - tmpbuf = (unsigned char *)PORT_Alloc(data.size + 3); - if ( tmpbuf ) { - /* copy header stuff */ - PORT_Memcpy(tmpbuf, buf, SEC_DB_ENTRY_HEADER_LEN); - - /* copy trust flage, setting msb's to 0 */ - tmpbuf[SEC_DB_ENTRY_HEADER_LEN] = 0; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+1] = - buf[SEC_DB_ENTRY_HEADER_LEN]; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+2] = 0; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+3] = - buf[SEC_DB_ENTRY_HEADER_LEN+1]; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+4] = 0; - tmpbuf[SEC_DB_ENTRY_HEADER_LEN+5] = - buf[SEC_DB_ENTRY_HEADER_LEN+2]; - - /* copy rest of the data */ - PORT_Memcpy(&tmpbuf[SEC_DB_ENTRY_HEADER_LEN + 6], - &buf[SEC_DB_ENTRY_HEADER_LEN + 3], - data.size - (SEC_DB_ENTRY_HEADER_LEN + 3)); - - data.data = (void *)tmpbuf; - data.size += 3; - buf = tmpbuf; - } - - } - - /* update the record version number */ - buf[0] = CERT_DB_FILE_VERSION; - - /* copy to the new database */ - ret = certdb_Put(handle->permCertDB, &key, &data, 0); - if ( tmpbuf ) { - PORT_Free(tmpbuf); - tmpbuf = NULL; - } - } - } - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - ret = certdb_Sync(handle->permCertDB, 0); - - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - if ( ret ) { - return(SECFailure); - } - - do { - buf = (unsigned char *)data.data; - - if ( data.size >= 3 ) { - if ( buf[0] == CERT_DB_FILE_VERSION ) { /* version number */ - type = (certDBEntryType)buf[1]; - if ( type == certDBEntryTypeNickname ) { - nickname = &((char *)key.data)[1]; - - /* get the matching nickname entry in the new DB */ - nnEntry = ReadDBNicknameEntry(handle, nickname); - if ( nnEntry == NULL ) { - goto endloop; - } - - /* find the subject entry pointed to by nickname */ - subjectEntry = ReadDBSubjectEntry(handle, - &nnEntry->subjectName); - if ( subjectEntry == NULL ) { - goto endloop; - } - - subjectEntry->nickname = - (char *)PORT_ArenaAlloc(subjectEntry->common.arena, - key.size - 1); - if ( subjectEntry->nickname ) { - PORT_Memcpy(subjectEntry->nickname, nickname, - key.size - 1); - rv = WriteDBSubjectEntry(handle, subjectEntry); - } - } else if ( type == certDBEntryTypeSMimeProfile ) { - emailAddr = &((char *)key.data)[1]; - - /* get the matching smime entry in the new DB */ - emailEntry = nsslowcert_ReadDBSMimeEntry(handle, emailAddr); - if ( emailEntry == NULL ) { - goto endloop; - } - - /* find the subject entry pointed to by nickname */ - subjectEntry = ReadDBSubjectEntry(handle, - &emailEntry->subjectName); - if ( subjectEntry == NULL ) { - goto endloop; - } - - subjectEntry->emailAddrs = (char **) - PORT_ArenaAlloc(subjectEntry->common.arena, - sizeof(char *)); - if ( subjectEntry->emailAddrs ) { - subjectEntry->emailAddrs[0] = - (char *)PORT_ArenaAlloc(subjectEntry->common.arena, - key.size - 1); - if ( subjectEntry->emailAddrs[0] ) { - PORT_Memcpy(subjectEntry->emailAddrs[0], emailAddr, - key.size - 1); - subjectEntry->nemailAddrs = 1; - rv = WriteDBSubjectEntry(handle, subjectEntry); - } - } - } - -endloop: - if ( subjectEntry ) { - DestroyDBEntry((certDBEntry *)subjectEntry); - subjectEntry = NULL; - } - if ( nnEntry ) { - DestroyDBEntry((certDBEntry *)nnEntry); - nnEntry = NULL; - } - if ( emailEntry ) { - DestroyDBEntry((certDBEntry *)emailEntry); - emailEntry = NULL; - } - } - } - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - ret = certdb_Sync(handle->permCertDB, 0); - - (* updatedb->close)(updatedb); - return(SECSuccess); -} - - -static SECStatus -updateV5Callback(NSSLOWCERTCertificate *cert, SECItem *k, void *pdata) -{ - NSSLOWCERTCertDBHandle *handle; - certDBEntryCert *entry; - NSSLOWCERTCertTrust *trust; - - handle = (NSSLOWCERTCertDBHandle *)pdata; - trust = &cert->dbEntry->trust; - - /* SSL user certs can be used for email if they have an email addr */ - if ( cert->emailAddr && ( trust->sslFlags & CERTDB_USER ) && - ( trust->emailFlags == 0 ) ) { - trust->emailFlags = CERTDB_USER; - } - /* servers didn't set the user flags on the server cert.. */ - if (PORT_Strcmp(cert->dbEntry->nickname,"Server-Cert") == 0) { - trust->sslFlags |= CERTDB_USER; - } - - entry = AddCertToPermDB(handle, cert, cert->dbEntry->nickname, - &cert->dbEntry->trust); - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - - return(SECSuccess); -} - -static SECStatus -UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb) -{ - NSSLOWCERTCertDBHandle updatehandle; - SECStatus rv; - - updatehandle.permCertDB = updatedb; - updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB); - updatehandle.dbVerify = 0; - updatehandle.ref = 1; /* prevent premature close */ - - rv = nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback, - (void *)handle); - - PZ_DestroyMonitor(updatehandle.dbMon); - - (* updatedb->close)(updatedb); - return(SECSuccess); -} - -static PRBool -isV4DB(DB *db) { - DBT key,data; - int ret; - - key.data = "Version"; - key.size = 7; - - ret = (*db->get)(db, &key, &data, 0); - if (ret) { - return PR_FALSE; - } - - if ((data.size == 1) && (*(unsigned char *)data.data <= 4)) { - return PR_TRUE; - } - - return PR_FALSE; -} - -static SECStatus -UpdateV4DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb) -{ - DBT key, data; - certDBEntryCert *entry, *entry2; - int ret; - PRArenaPool *arena = NULL; - NSSLOWCERTCertificate *cert; - - ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); - - if ( ret ) { - return(SECFailure); - } - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - return(SECFailure); - } - - do { - if ( data.size != 1 ) { /* skip version number */ - - /* decode the old DB entry */ - entry = (certDBEntryCert *) - DecodeV4DBCertEntry((unsigned char*)data.data, data.size); - - if ( entry ) { - cert = nsslowcert_DecodeDERCertificate(&entry->derCert, - entry->nickname); - - if ( cert != NULL ) { - /* add to new database */ - entry2 = AddCertToPermDB(handle, cert, entry->nickname, - &entry->trust); - - nsslowcert_DestroyCertificate(cert); - if ( entry2 ) { - DestroyDBEntry((certDBEntry *)entry2); - } - } - DestroyDBEntry((certDBEntry *)entry); - } - } - } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); - - PORT_FreeArena(arena, PR_FALSE); - (* updatedb->close)(updatedb); - return(SECSuccess); -} - - -/* - * return true if a database key conflict exists - */ -PRBool -nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle) -{ - SECStatus rv; - DBT tmpdata; - DBT namekey; - int ret; - SECItem keyitem; - PRArenaPool *arena = NULL; - SECItem derKey; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - /* get the db key of the cert */ - rv = nsslowcert_KeyFromDERCert(arena, derCert, &derKey); - if ( rv != SECSuccess ) { - goto loser; - } - - rv = EncodeDBCertKey(&derKey, arena, &keyitem); - if ( rv != SECSuccess ) { - goto loser; - } - - namekey.data = keyitem.data; - namekey.size = keyitem.len; - - ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0); - if ( ret == 0 ) { - goto loser; - } - - PORT_FreeArena(arena, PR_FALSE); - - return(PR_FALSE); -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return(PR_TRUE); -} - -/* - * return true if a nickname conflict exists - * NOTE: caller must have already made sure that this exact cert - * doesn't exist in the DB - */ -static PRBool -nsslowcert_CertNicknameConflict(char *nickname, SECItem *derSubject, - NSSLOWCERTCertDBHandle *handle) -{ - PRBool rv; - certDBEntryNickname *entry; - - if ( nickname == NULL ) { - return(PR_FALSE); - } - - entry = ReadDBNicknameEntry(handle, nickname); - - if ( entry == NULL ) { - /* no entry for this nickname, so no conflict */ - return(PR_FALSE); - } - - rv = PR_TRUE; - if ( SECITEM_CompareItem(derSubject, &entry->subjectName) == SECEqual ) { - /* if subject names are the same, then no conflict */ - rv = PR_FALSE; - } - - DestroyDBEntry((certDBEntry *)entry); - return(rv); -} - -#ifdef DBM_USING_NSPR -#define NO_RDONLY PR_RDONLY -#define NO_RDWR PR_RDWR -#define NO_CREATE (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE) -#else -#define NO_RDONLY O_RDONLY -#define NO_RDWR O_RDWR -#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC) -#endif - -/* - * open an old database that needs to be updated - */ -static DB * -nsslowcert_openolddb(NSSLOWCERTDBNameFunc namecb, void *cbarg, int version) -{ - char * tmpname; - DB *updatedb = NULL; - - tmpname = (* namecb)(cbarg, version); /* get v6 db name */ - if ( tmpname ) { - updatedb = dbopen( tmpname, NO_RDONLY, 0600, DB_HASH, 0 ); - PORT_Free(tmpname); - } - return updatedb; -} - -static SECStatus -openNewCertDB(const char *appName, const char *prefix, const char *certdbname, - NSSLOWCERTCertDBHandle *handle, NSSLOWCERTDBNameFunc namecb, void *cbarg) -{ - SECStatus rv; - certDBEntryVersion *versionEntry = NULL; - DB *updatedb = NULL; - int status = RDB_FAIL; - - if (appName) { - handle->permCertDB=rdbopen( appName, prefix, "cert", NO_CREATE, &status); - } else { - handle->permCertDB=dbsopen(certdbname, NO_CREATE, 0600, DB_HASH, 0); - } - - /* if create fails then we lose */ - if ( handle->permCertDB == 0 ) { - return status == RDB_RETRY ? SECWouldBlock : SECFailure; - } - - /* Verify version number; */ - versionEntry = NewDBVersionEntry(0); - if ( versionEntry == NULL ) { - rv = SECFailure; - goto loser; - } - - rv = WriteDBVersionEntry(handle, versionEntry); - - DestroyDBEntry((certDBEntry *)versionEntry); - - if ( rv != SECSuccess ) { - goto loser; - } - - /* rv must already be Success here because of previous if statement */ - /* try to upgrade old db here */ - if (appName && - (updatedb = dbsopen(certdbname, NO_RDONLY, 0600, DB_HASH, 0)) != NULL) { - rv = UpdateV8DB(handle, updatedb); - } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,7)) != NULL) { - rv = UpdateV7DB(handle, updatedb); - } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,6)) != NULL) { - rv = UpdateV6DB(handle, updatedb); - } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,5)) != NULL) { - rv = UpdateV5DB(handle, updatedb); - } else if ((updatedb = nsslowcert_openolddb(namecb,cbarg,4)) != NULL) { - /* NES has v5 format db's with v4 db names! */ - if (isV4DB(updatedb)) { - rv = UpdateV4DB(handle,updatedb); - } else { - rv = UpdateV5DB(handle,updatedb); - } - } - - -loser: - db_InitComplete(handle->permCertDB); - return rv; -} - -static int -nsslowcert_GetVersionNumber( NSSLOWCERTCertDBHandle *handle) -{ - certDBEntryVersion *versionEntry = NULL; - int version = 0; - - versionEntry = ReadDBVersionEntry(handle); - if ( versionEntry == NULL ) { - return 0; - } - version = versionEntry->common.version; - DestroyDBEntry((certDBEntry *)versionEntry); - return version; -} - -/* - * Open the certificate database and index databases. Create them if - * they are not there or bad. - */ -static SECStatus -nsslowcert_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly, - const char *appName, const char *prefix, - NSSLOWCERTDBNameFunc namecb, void *cbarg) -{ - SECStatus rv; - int openflags; - char *certdbname; - int version = 0; - - certdbname = (* namecb)(cbarg, CERT_DB_FILE_VERSION); - if ( certdbname == NULL ) { - return(SECFailure); - } - - openflags = readOnly ? NO_RDONLY : NO_RDWR; - - /* - * first open the permanent file based database. - */ - if (appName) { - handle->permCertDB = rdbopen( appName, prefix, "cert", openflags, NULL); - } else { - handle->permCertDB = dbsopen( certdbname, openflags, 0600, DB_HASH, 0 ); - } - - /* check for correct version number */ - if ( handle->permCertDB ) { - version = nsslowcert_GetVersionNumber(handle); - if ((version != CERT_DB_FILE_VERSION) && - !(appName && version == CERT_DB_V7_FILE_VERSION)) { - goto loser; - } - } else if ( readOnly ) { - /* don't create if readonly */ - /* Try openning a version 7 database */ - handle->permCertDB = nsslowcert_openolddb(namecb,cbarg, 7); - if (!handle->permCertDB) { - goto loser; - } - if (nsslowcert_GetVersionNumber(handle) != 7) { - goto loser; - } - } else { - /* if first open fails, try to create a new DB */ - rv = openNewCertDB(appName,prefix,certdbname,handle,namecb,cbarg); - if (rv == SECWouldBlock) { - /* only the rdb version can fail with wouldblock */ - handle->permCertDB = - rdbopen( appName, prefix, "cert", openflags, NULL); - - /* check for correct version number */ - if ( !handle->permCertDB ) { - goto loser; - } - version = nsslowcert_GetVersionNumber(handle); - if ((version != CERT_DB_FILE_VERSION) && - !(appName && version == CERT_DB_V7_FILE_VERSION)) { - goto loser; - } - } else if (rv != SECSuccess) { - goto loser; - } - } - - PORT_Free(certdbname); - - return (SECSuccess); - -loser: - - PORT_SetError(SEC_ERROR_BAD_DATABASE); - - if ( handle->permCertDB ) { - certdb_Close(handle->permCertDB); - handle->permCertDB = 0; - } - - PORT_Free(certdbname); - - return(SECFailure); -} - -/* - * delete all DB records associated with a particular certificate - */ -static SECStatus -DeletePermCert(NSSLOWCERTCertificate *cert) -{ - SECStatus rv; - SECStatus ret; - - ret = SECSuccess; - - rv = DeleteDBCertEntry(cert->dbhandle, &cert->certKey); - if ( rv != SECSuccess ) { - ret = SECFailure; - } - - rv = RemovePermSubjectNode(cert); - - - return(ret); -} - -/* - * Delete a certificate from the permanent database. - */ -SECStatus -nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert) -{ - SECStatus rv; - - nsslowcert_LockDB(cert->dbhandle); - - /* delete the records from the permanent database */ - rv = DeletePermCert(cert); - - /* get rid of dbcert and stuff pointing to it */ - DestroyDBEntry((certDBEntry *)cert->dbEntry); - cert->dbEntry = NULL; - cert->trust = NULL; - - nsslowcert_UnlockDB(cert->dbhandle); - return(rv); -} - -/* - * Traverse all of the entries in the database of a particular type - * call the given function for each one. - */ -SECStatus -nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle, - certDBEntryType type, - SECStatus (* callback)(SECItem *data, SECItem *key, - certDBEntryType type, void *pdata), - void *udata ) -{ - DBT data; - DBT key; - SECStatus rv; - int ret; - SECItem dataitem; - SECItem keyitem; - unsigned char *buf; - unsigned char *keybuf; - - ret = certdb_Seq(handle->permCertDB, &key, &data, R_FIRST); - - if ( ret ) { - return(SECFailure); - } - - do { - buf = (unsigned char *)data.data; - - if ( buf[1] == (unsigned char)type ) { - dataitem.len = data.size; - dataitem.data = buf; - dataitem.type = siBuffer; - keyitem.len = key.size - SEC_DB_KEY_HEADER_LEN; - keybuf = (unsigned char *)key.data; - keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN]; - keyitem.type = siBuffer; - /* type should equal keybuf[0]. */ - - rv = (* callback)(&dataitem, &keyitem, type, udata); - if ( rv != SECSuccess ) { - return(rv); - } - } - } while ( certdb_Seq(handle->permCertDB, &key, &data, R_NEXT) == 0 ); - - return(SECSuccess); -} -/* - * Decode a certificate and enter it into the temporary certificate database. - * Deal with nicknames correctly - * - * This is the private entry point. - */ -static NSSLOWCERTCertificate * -DecodeACert(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry) -{ - NSSLOWCERTCertificate *cert = NULL; - - cert = nsslowcert_DecodeDERCertificate(&entry->derCert, entry->nickname ); - - if ( cert == NULL ) { - goto loser; - } - - cert->dbhandle = handle; - cert->dbEntry = entry; - cert->trust = &entry->trust; - - return(cert); - -loser: - return(0); -} - -static NSSLOWCERTTrust * -CreateTrust(void) -{ - NSSLOWCERTTrust *trust = NULL; - - nsslowcert_LockFreeList(); - trust = trustListHead; - if (trust) { - trustListCount--; - trustListHead = trust->next; - } - PORT_Assert(trustListCount >= 0); - nsslowcert_UnlockFreeList(); - if (trust) { - return trust; - } - - return PORT_ZNew(NSSLOWCERTTrust); -} - -static void -DestroyTrustFreeList(void) -{ - NSSLOWCERTTrust *trust; - - nsslowcert_LockFreeList(); - while (NULL != (trust = trustListHead)) { - trustListCount--; - trustListHead = trust->next; - PORT_Free(trust); - } - PORT_Assert(!trustListCount); - trustListCount = 0; - nsslowcert_UnlockFreeList(); -} - -static NSSLOWCERTTrust * -DecodeTrustEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryCert *entry, - const SECItem *dbKey) -{ - NSSLOWCERTTrust *trust = CreateTrust(); - if (trust == NULL) { - return trust; - } - trust->dbhandle = handle; - trust->dbEntry = entry; - trust->dbKey.data = pkcs11_copyStaticData(dbKey->data,dbKey->len, - trust->dbKeySpace, sizeof(trust->dbKeySpace)); - if (!trust->dbKey.data) { - PORT_Free(trust); - return NULL; - } - trust->dbKey.len = dbKey->len; - - trust->trust = &entry->trust; - trust->derCert = &entry->derCert; - - return(trust); -} - -typedef struct { - PermCertCallback certfunc; - NSSLOWCERTCertDBHandle *handle; - void *data; -} PermCertCallbackState; - -/* - * traversal callback to decode certs and call callers callback - */ -static SECStatus -certcallback(SECItem *dbdata, SECItem *dbkey, certDBEntryType type, void *data) -{ - PermCertCallbackState *mystate; - SECStatus rv; - certDBEntryCert *entry; - SECItem entryitem; - NSSLOWCERTCertificate *cert; - PRArenaPool *arena = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - entry = (certDBEntryCert *)PORT_ArenaAlloc(arena, sizeof(certDBEntryCert)); - mystate = (PermCertCallbackState *)data; - entry->common.version = (unsigned int)dbdata->data[0]; - entry->common.type = (certDBEntryType)dbdata->data[1]; - entry->common.flags = (unsigned int)dbdata->data[2]; - entry->common.arena = arena; - - entryitem.len = dbdata->len - SEC_DB_ENTRY_HEADER_LEN; - entryitem.data = &dbdata->data[SEC_DB_ENTRY_HEADER_LEN]; - - rv = DecodeDBCertEntry(entry, &entryitem); - if (rv != SECSuccess ) { - goto loser; - } - entry->derCert.type = siBuffer; - - /* note: Entry is 'inheritted'. */ - cert = DecodeACert(mystate->handle, entry); - - rv = (* mystate->certfunc)(cert, dbkey, mystate->data); - - /* arena stored in entry destroyed by nsslowcert_DestroyCertificate */ - nsslowcert_DestroyCertificateNoLocking(cert); - - return(rv); - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - return(SECFailure); -} - -/* - * Traverse all of the certificates in the permanent database and - * call the given function for each one; expect the caller to have lock. - */ -static SECStatus -TraversePermCertsNoLocking(NSSLOWCERTCertDBHandle *handle, - SECStatus (* certfunc)(NSSLOWCERTCertificate *cert, - SECItem *k, - void *pdata), - void *udata ) -{ - SECStatus rv; - PermCertCallbackState mystate; - - mystate.certfunc = certfunc; - mystate.handle = handle; - mystate.data = udata; - rv = nsslowcert_TraverseDBEntries(handle, certDBEntryTypeCert, certcallback, - (void *)&mystate); - - return(rv); -} - -/* - * Traverse all of the certificates in the permanent database and - * call the given function for each one. - */ -SECStatus -nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle, - SECStatus (* certfunc)(NSSLOWCERTCertificate *cert, SECItem *k, - void *pdata), - void *udata ) -{ - SECStatus rv; - - nsslowcert_LockDB(handle); - rv = TraversePermCertsNoLocking(handle, certfunc, udata); - nsslowcert_UnlockDB(handle); - - return(rv); -} - - - -/* - * Close the database - */ -void -nsslowcert_ClosePermCertDB(NSSLOWCERTCertDBHandle *handle) -{ - if ( handle ) { - if ( handle->permCertDB ) { - certdb_Close( handle->permCertDB ); - handle->permCertDB = NULL; - } - if (handle->dbMon) { - PZ_DestroyMonitor(handle->dbMon); - handle->dbMon = NULL; - } - PORT_Free(handle); - } - return; -} - -/* - * Get the trust attributes from a certificate - */ -SECStatus -nsslowcert_GetCertTrust(NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust) -{ - SECStatus rv; - - nsslowcert_LockCertTrust(cert); - - if ( cert->trust == NULL ) { - rv = SECFailure; - } else { - *trust = *cert->trust; - rv = SECSuccess; - } - - nsslowcert_UnlockCertTrust(cert); - return(rv); -} - -/* - * Change the trust attributes of a certificate and make them permanent - * in the database. - */ -SECStatus -nsslowcert_ChangeCertTrust(NSSLOWCERTCertDBHandle *handle, - NSSLOWCERTCertificate *cert, NSSLOWCERTCertTrust *trust) -{ - certDBEntryCert *entry; - int rv; - SECStatus ret; - - nsslowcert_LockDB(handle); - nsslowcert_LockCertTrust(cert); - /* only set the trust on permanent certs */ - if ( cert->trust == NULL ) { - ret = SECFailure; - goto done; - } - - *cert->trust = *trust; - if ( cert->dbEntry == NULL ) { - ret = SECSuccess; /* not in permanent database */ - goto done; - } - - entry = cert->dbEntry; - entry->trust = *trust; - - rv = WriteDBCertEntry(handle, entry); - if ( rv ) { - ret = SECFailure; - goto done; - } - - ret = SECSuccess; - -done: - nsslowcert_UnlockCertTrust(cert); - nsslowcert_UnlockDB(handle); - return(ret); -} - - -static SECStatus -nsslowcert_UpdatePermCert(NSSLOWCERTCertDBHandle *dbhandle, - NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust) -{ - char *oldnn; - certDBEntryCert *entry; - PRBool conflict; - SECStatus ret; - - PORT_Assert(!cert->dbEntry); - - /* don't add a conflicting nickname */ - conflict = nsslowcert_CertNicknameConflict(nickname, &cert->derSubject, - dbhandle); - if ( conflict ) { - ret = SECFailure; - goto done; - } - - /* save old nickname so that we can delete it */ - oldnn = cert->nickname; - - entry = AddCertToPermDB(dbhandle, cert, nickname, trust); - - if ( entry == NULL ) { - ret = SECFailure; - goto done; - } - - pkcs11_freeNickname(oldnn,cert->nicknameSpace); - - cert->nickname = (entry->nickname) ? pkcs11_copyNickname(entry->nickname, - cert->nicknameSpace, sizeof(cert->nicknameSpace)) : NULL; - cert->trust = &entry->trust; - cert->dbEntry = entry; - - ret = SECSuccess; -done: - return(ret); -} - -SECStatus -nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle, - NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust) -{ - SECStatus ret; - - nsslowcert_LockDB(dbhandle); - - ret = nsslowcert_UpdatePermCert(dbhandle, cert, nickname, trust); - - nsslowcert_UnlockDB(dbhandle); - return(ret); -} - -/* - * Open the certificate database and index databases. Create them if - * they are not there or bad. - */ -SECStatus -nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly, - const char *appName, const char *prefix, - NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile) -{ - int rv; - - certdb_InitDBLock(handle); - - handle->dbMon = PZ_NewMonitor(nssILockCertDB); - PORT_Assert(handle->dbMon != NULL); - handle->dbVerify = PR_FALSE; - - rv = nsslowcert_OpenPermCertDB(handle, readOnly, appName, prefix, - namecb, cbarg); - if ( rv ) { - goto loser; - } - - return (SECSuccess); - -loser: - - PORT_SetError(SEC_ERROR_BAD_DATABASE); - return(SECFailure); -} - -PRBool -nsslowcert_needDBVerify(NSSLOWCERTCertDBHandle *handle) -{ - if (!handle) return PR_FALSE; - return handle->dbVerify; -} - -void -nsslowcert_setDBVerify(NSSLOWCERTCertDBHandle *handle, PRBool value) -{ - handle->dbVerify = value; -} - - -/* - * Lookup a certificate in the databases. - */ -static NSSLOWCERTCertificate * -FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool lockdb) -{ - NSSLOWCERTCertificate *cert = NULL; - certDBEntryCert *entry; - PRBool locked = PR_FALSE; - - if ( lockdb ) { - locked = PR_TRUE; - nsslowcert_LockDB(handle); - } - - /* find in perm database */ - entry = ReadDBCertEntry(handle, certKey); - - if ( entry == NULL ) { - goto loser; - } - - /* inherit entry */ - cert = DecodeACert(handle, entry); - -loser: - if (cert == NULL) { - if (entry) { - DestroyDBEntry((certDBEntry *)entry); - } - } - - if ( locked ) { - nsslowcert_UnlockDB(handle); - } - - return(cert); -} - -/* - * Lookup a certificate in the databases. - */ -static NSSLOWCERTTrust * -FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey, PRBool lockdb) -{ - NSSLOWCERTTrust *trust = NULL; - certDBEntryCert *entry; - PRBool locked = PR_FALSE; - - if ( lockdb ) { - locked = PR_TRUE; - nsslowcert_LockDB(handle); - } - - /* find in perm database */ - entry = ReadDBCertEntry(handle, certKey); - - if ( entry == NULL ) { - goto loser; - } - - if (!nsslowcert_hasTrust(&entry->trust)) { - goto loser; - } - - /* inherit entry */ - trust = DecodeTrustEntry(handle, entry, certKey); - -loser: - if (trust == NULL) { - if (entry) { - DestroyDBEntry((certDBEntry *)entry); - } - } - - if ( locked ) { - nsslowcert_UnlockDB(handle); - } - - return(trust); -} - -/* - * Lookup a certificate in the databases without locking - */ -NSSLOWCERTCertificate * -nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey) -{ - return(FindCertByKey(handle, certKey, PR_FALSE)); -} - -/* - * Lookup a trust object in the databases without locking - */ -NSSLOWCERTTrust * -nsslowcert_FindTrustByKey(NSSLOWCERTCertDBHandle *handle, const SECItem *certKey) -{ - return(FindTrustByKey(handle, certKey, PR_FALSE)); -} - -/* - * Generate a key from an issuerAndSerialNumber, and find the - * associated cert in the database. - */ -NSSLOWCERTCertificate * -nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssuerAndSN *issuerAndSN) -{ - SECItem certKey; - SECItem *sn = &issuerAndSN->serialNumber; - SECItem *issuer = &issuerAndSN->derIssuer; - NSSLOWCERTCertificate *cert; - int data_left = sn->len-1; - int data_len = sn->len; - int index = 0; - - /* automatically detect DER encoded serial numbers and remove the der - * encoding since the database expects unencoded data. - * if it's DER encoded, there must be at least 3 bytes, tag, len, data */ - if ((sn->len >= 3) && (sn->data[0] == 0x2)) { - /* remove the der encoding of the serial number before generating the - * key.. */ - data_left = sn->len-2; - data_len = sn->data[1]; - index = 2; - - /* extended length ? (not very likely for a serial number) */ - if (data_len & 0x80) { - int len_count = data_len & 0x7f; - - data_len = 0; - data_left -= len_count; - if (data_left > 0) { - while (len_count --) { - data_len = (data_len << 8) | sn->data[index++]; - } - } - } - /* XXX leaving any leading zeros on the serial number for backwards - * compatibility - */ - /* not a valid der, must be just an unlucky serial number value */ - if (data_len != data_left) { - data_len = sn->len; - index = 0; - } - } - - certKey.type = 0; - certKey.data = (unsigned char*)PORT_Alloc(sn->len + issuer->len); - certKey.len = data_len + issuer->len; - - if ( certKey.data == NULL ) { - return(0); - } - - /* first try the serial number as hand-decoded above*/ - /* copy the serialNumber */ - PORT_Memcpy(certKey.data, &sn->data[index], data_len); - - /* copy the issuer */ - PORT_Memcpy( &certKey.data[data_len],issuer->data,issuer->len); - - cert = nsslowcert_FindCertByKey(handle, &certKey); - if (cert) { - PORT_Free(certKey.data); - return (cert); - } - - /* didn't find it, try by der encoded serial number */ - /* copy the serialNumber */ - PORT_Memcpy(certKey.data, sn->data, sn->len); - - /* copy the issuer */ - PORT_Memcpy( &certKey.data[sn->len], issuer->data, issuer->len); - certKey.len = sn->len + issuer->len; - - cert = nsslowcert_FindCertByKey(handle, &certKey); - - PORT_Free(certKey.data); - - return(cert); -} - -/* - * Generate a key from an issuerAndSerialNumber, and find the - * associated cert in the database. - */ -NSSLOWCERTTrust * -nsslowcert_FindTrustByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, - NSSLOWCERTIssuerAndSN *issuerAndSN) -{ - SECItem certKey; - SECItem *sn = &issuerAndSN->serialNumber; - SECItem *issuer = &issuerAndSN->derIssuer; - NSSLOWCERTTrust *trust; - unsigned char keyBuf[512]; - int data_left = sn->len-1; - int data_len = sn->len; - int index = 0; - int len; - - /* automatically detect DER encoded serial numbers and remove the der - * encoding since the database expects unencoded data. - * if it's DER encoded, there must be at least 3 bytes, tag, len, data */ - if ((sn->len >= 3) && (sn->data[0] == 0x2)) { - /* remove the der encoding of the serial number before generating the - * key.. */ - data_left = sn->len-2; - data_len = sn->data[1]; - index = 2; - - /* extended length ? (not very likely for a serial number) */ - if (data_len & 0x80) { - int len_count = data_len & 0x7f; - - data_len = 0; - data_left -= len_count; - if (data_left > 0) { - while (len_count --) { - data_len = (data_len << 8) | sn->data[index++]; - } - } - } - /* XXX leaving any leading zeros on the serial number for backwards - * compatibility - */ - /* not a valid der, must be just an unlucky serial number value */ - if (data_len != data_left) { - data_len = sn->len; - index = 0; - } - } - - certKey.type = 0; - certKey.len = data_len + issuer->len; - len = sn->len + issuer->len; - if (len > sizeof (keyBuf)) { - certKey.data = (unsigned char*)PORT_Alloc(len); - } else { - certKey.data = keyBuf; - } - - if ( certKey.data == NULL ) { - return(0); - } - - /* first try the serial number as hand-decoded above*/ - /* copy the serialNumber */ - PORT_Memcpy(certKey.data, &sn->data[index], data_len); - - /* copy the issuer */ - PORT_Memcpy( &certKey.data[data_len],issuer->data,issuer->len); - - trust = nsslowcert_FindTrustByKey(handle, &certKey); - if (trust) { - pkcs11_freeStaticData(certKey.data, keyBuf); - return (trust); - } - - if (index == 0) { - pkcs11_freeStaticData(certKey.data, keyBuf); - return NULL; - } - - /* didn't find it, try by der encoded serial number */ - /* copy the serialNumber */ - PORT_Memcpy(certKey.data, sn->data, sn->len); - - /* copy the issuer */ - PORT_Memcpy( &certKey.data[sn->len], issuer->data, issuer->len); - certKey.len = sn->len + issuer->len; - - trust = nsslowcert_FindTrustByKey(handle, &certKey); - - pkcs11_freeStaticData(certKey.data, keyBuf); - - return(trust); -} - -/* - * look for the given DER certificate in the database - */ -NSSLOWCERTCertificate * -nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert) -{ - PRArenaPool *arena; - SECItem certKey; - SECStatus rv; - NSSLOWCERTCertificate *cert = NULL; - - /* create a scratch arena */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return(NULL); - } - - /* extract the database key from the cert */ - rv = nsslowcert_KeyFromDERCert(arena, derCert, &certKey); - if ( rv != SECSuccess ) { - goto loser; - } - - /* find the certificate */ - cert = nsslowcert_FindCertByKey(handle, &certKey); - -loser: - PORT_FreeArena(arena, PR_FALSE); - return(cert); -} - -static void -DestroyCertificate(NSSLOWCERTCertificate *cert, PRBool lockdb) -{ - int refCount; - NSSLOWCERTCertDBHandle *handle; - - if ( cert ) { - - handle = cert->dbhandle; - - /* - * handle may be NULL, for example if the cert was created with - * nsslowcert_DecodeDERCertificate. - */ - if ( lockdb && handle ) { - nsslowcert_LockDB(handle); - } - - nsslowcert_LockCertRefCount(cert); - PORT_Assert(cert->referenceCount > 0); - refCount = --cert->referenceCount; - nsslowcert_UnlockCertRefCount(cert); - - if ( ( refCount == 0 ) ) { - certDBEntryCert *entry = cert->dbEntry; - - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - - pkcs11_freeNickname(cert->nickname,cert->nicknameSpace); - pkcs11_freeNickname(cert->emailAddr,cert->emailAddrSpace); - pkcs11_freeStaticData(cert->certKey.data,cert->certKeySpace); - cert->certKey.data = NULL; - cert->nickname = NULL; - - /* zero cert before freeing. Any stale references to this cert - * after this point will probably cause an exception. */ - PORT_Memset(cert, 0, sizeof *cert); - - /* use reflock to protect the free list */ - nsslowcert_LockFreeList(); - if (certListCount > MAX_CERT_LIST_COUNT) { - PORT_Free(cert); - } else { - certListCount++; - cert->next = certListHead; - certListHead = cert; - } - nsslowcert_UnlockFreeList(); - cert = NULL; - } - if ( lockdb && handle ) { - nsslowcert_UnlockDB(handle); - } - } - - return; -} - -NSSLOWCERTCertificate * -nsslowcert_CreateCert(void) -{ - NSSLOWCERTCertificate *cert; - nsslowcert_LockFreeList(); - cert = certListHead; - if (cert) { - certListHead = cert->next; - certListCount--; - } - PORT_Assert(certListCount >= 0); - nsslowcert_UnlockFreeList(); - if (cert) { - return cert; - } - return PORT_ZNew(NSSLOWCERTCertificate); -} - -static void -DestroyCertFreeList(void) -{ - NSSLOWCERTCertificate *cert; - - nsslowcert_LockFreeList(); - while (NULL != (cert = certListHead)) { - certListCount--; - certListHead = cert->next; - PORT_Free(cert); - } - PORT_Assert(!certListCount); - certListCount = 0; - nsslowcert_UnlockFreeList(); -} - -void -nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust) -{ - certDBEntryCert *entry = trust->dbEntry; - - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - pkcs11_freeStaticData(trust->dbKey.data,trust->dbKeySpace); - PORT_Memset(trust, 0, sizeof(*trust)); - - nsslowcert_LockFreeList(); - if (trustListCount > MAX_TRUST_LIST_COUNT) { - PORT_Free(trust); - } else { - trustListCount++; - trust->next = trustListHead; - trustListHead = trust; - } - nsslowcert_UnlockFreeList(); - - return; -} - -void -nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert) -{ - DestroyCertificate(cert, PR_TRUE); - return; -} - -static void -nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert) -{ - DestroyCertificate(cert, PR_FALSE); - return; -} - -/* - * Lookup a CRL in the databases. We mirror the same fast caching data base - * caching stuff used by certificates....? - */ -certDBEntryRevocation * -nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, - SECItem *crlKey, PRBool isKRL) -{ - SECItem keyitem; - DBT key; - SECStatus rv; - PRArenaPool *arena = NULL; - certDBEntryRevocation *entry = NULL; - certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation - : certDBEntryTypeRevocation; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - goto loser; - } - - rv = EncodeDBGenericKey(crlKey, arena, &keyitem, crlType); - if ( rv != SECSuccess ) { - goto loser; - } - - key.data = keyitem.data; - key.size = keyitem.len; - - /* find in perm database */ - entry = ReadDBCrlEntry(handle, crlKey, crlType); - - if ( entry == NULL ) { - goto loser; - } - -loser: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); - } - - return entry; -} - -/* - * replace the existing URL in the data base with a new one - */ -static SECStatus -nsslowcert_UpdateCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl, - SECItem *crlKey, char *url, PRBool isKRL) -{ - SECStatus rv = SECFailure; - certDBEntryRevocation *entry = NULL; - certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation - : certDBEntryTypeRevocation; - DeleteDBCrlEntry(handle, crlKey, crlType); - - /* Write the new entry into the data base */ - entry = NewDBCrlEntry(derCrl, url, crlType, 0); - if (entry == NULL) goto done; - - rv = WriteDBCrlEntry(handle, entry, crlKey); - if (rv != SECSuccess) goto done; - -done: - if (entry) { - DestroyDBEntry((certDBEntry *)entry); - } - return rv; -} - -SECStatus -nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl, - SECItem *crlKey, char *url, PRBool isKRL) -{ - SECStatus rv; - - rv = nsslowcert_UpdateCrl(handle, derCrl, crlKey, url, isKRL); - - return rv; -} - -SECStatus -nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle, const SECItem *derName, - PRBool isKRL) -{ - SECStatus rv; - certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation - : certDBEntryTypeRevocation; - - rv = DeleteDBCrlEntry(handle, derName, crlType); - if (rv != SECSuccess) goto done; - -done: - return rv; -} - - -PRBool -nsslowcert_hasTrust(NSSLOWCERTCertTrust *trust) -{ - if (trust == NULL) { - return PR_FALSE; - } - return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) && - (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) && - (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN)); -} - -/* - * This function has the logic that decides if another person's cert and - * email profile from an S/MIME message should be saved. It can deal with - * the case when there is no profile. - */ -static SECStatus -nsslowcert_UpdateSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, - char *emailAddr, SECItem *derSubject, SECItem *emailProfile, - SECItem *profileTime) -{ - certDBEntrySMime *entry = NULL; - SECStatus rv = SECFailure;; - - - /* find our existing entry */ - entry = nsslowcert_ReadDBSMimeEntry(dbhandle, emailAddr); - - if ( entry ) { - /* keep our old db entry consistant for old applications. */ - if (!SECITEM_ItemsAreEqual(derSubject, &entry->subjectName)) { - nsslowcert_UpdateSubjectEmailAddr(dbhandle, &entry->subjectName, - emailAddr, nsslowcert_remove); - } - DestroyDBEntry((certDBEntry *)entry); - entry = NULL; - } - - /* now save the entry */ - entry = NewDBSMimeEntry(emailAddr, derSubject, emailProfile, - profileTime, 0); - if ( entry == NULL ) { - rv = SECFailure; - goto loser; - } - - nsslowcert_LockDB(dbhandle); - - rv = DeleteDBSMimeEntry(dbhandle, emailAddr); - /* if delete fails, try to write new entry anyway... */ - - /* link subject entry back here */ - rv = nsslowcert_UpdateSubjectEmailAddr(dbhandle, derSubject, emailAddr, - nsslowcert_add); - if ( rv != SECSuccess ) { - nsslowcert_UnlockDB(dbhandle); - goto loser; - } - - rv = WriteDBSMimeEntry(dbhandle, entry); - if ( rv != SECSuccess ) { - nsslowcert_UnlockDB(dbhandle); - goto loser; - } - - nsslowcert_UnlockDB(dbhandle); - - rv = SECSuccess; - -loser: - if ( entry ) { - DestroyDBEntry((certDBEntry *)entry); - } - return(rv); -} - -SECStatus -nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr, - SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime) -{ - SECStatus rv = SECFailure;; - - - rv = nsslowcert_UpdateSMimeProfile(dbhandle, emailAddr, - derSubject, emailProfile, profileTime); - - return(rv); -} - -void -nsslowcert_DestroyFreeLists(void) -{ - if (freeListLock == NULL) { - return; - } - DestroyCertEntryFreeList(); - DestroyTrustFreeList(); - DestroyCertFreeList(); - SKIP_AFTER_FORK(PZ_DestroyLock(freeListLock)); - freeListLock = NULL; -} - -void -nsslowcert_DestroyGlobalLocks(void) -{ - if (dbLock) { - SKIP_AFTER_FORK(PZ_DestroyLock(dbLock)); - dbLock = NULL; - } - if (certRefCountLock) { - SKIP_AFTER_FORK(PZ_DestroyLock(certRefCountLock)); - certRefCountLock = NULL; - } - if (certTrustLock) { - SKIP_AFTER_FORK(PZ_DestroyLock(certTrustLock)); - certTrustLock = NULL; - } -} - -certDBEntry * -nsslowcert_DecodeAnyDBEntry(SECItem *dbData, const SECItem *dbKey, - certDBEntryType entryType, void *pdata) -{ - PLArenaPool *arena = NULL; - certDBEntry *entry; - SECStatus rv; - SECItem dbEntry; - - - if ((dbData->len < SEC_DB_ENTRY_HEADER_LEN) || (dbKey->len == 0)) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - goto loser; - } - dbEntry.data = &dbData->data[SEC_DB_ENTRY_HEADER_LEN]; - dbEntry.len = dbData->len - SEC_DB_ENTRY_HEADER_LEN; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto loser; - } - entry = PORT_ArenaZNew(arena, certDBEntry); - if (!entry) - goto loser; - - entry->common.version = (unsigned int)dbData->data[0]; - entry->common.flags = (unsigned int)dbData->data[2]; - entry->common.type = entryType; - entry->common.arena = arena; - - switch (entryType) { - case certDBEntryTypeContentVersion: /* This type appears to be unused */ - case certDBEntryTypeVersion: /* This type has only the common hdr */ - rv = SECSuccess; - break; - - case certDBEntryTypeSubject: - rv = DecodeDBSubjectEntry(&entry->subject, &dbEntry, dbKey); - break; - - case certDBEntryTypeNickname: - rv = DecodeDBNicknameEntry(&entry->nickname, &dbEntry, - (char *)dbKey->data); - break; - - /* smime profiles need entries created after the certs have - * been imported, loop over them in a second run */ - case certDBEntryTypeSMimeProfile: - rv = DecodeDBSMimeEntry(&entry->smime, &dbEntry, (char *)dbKey->data); - break; - - case certDBEntryTypeCert: - rv = DecodeDBCertEntry(&entry->cert, &dbEntry); - break; - - case certDBEntryTypeKeyRevocation: - case certDBEntryTypeRevocation: - rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry); - break; - - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - rv = SECFailure; - } - - if (rv == SECSuccess) - return entry; - -loser: - if (arena) - PORT_FreeArena(arena, PR_FALSE); - return NULL; -} - diff --git a/security/nss/lib/softoken/legacydb/pcertt.h b/security/nss/lib/softoken/legacydb/pcertt.h deleted file mode 100644 index 476a2d079..000000000 --- a/security/nss/lib/softoken/legacydb/pcertt.h +++ /dev/null @@ -1,450 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * certt.h - public data structures for the certificate library - * - * $Id$ - */ -#ifndef _PCERTT_H_ -#define _PCERTT_H_ - -#include "prclist.h" -#include "pkcs11t.h" -#include "seccomon.h" -#include "secoidt.h" -#include "plarena.h" -#include "prcvar.h" -#include "nssilock.h" -#include "prio.h" -#include "prmon.h" - -/* Non-opaque objects */ -typedef struct NSSLOWCERTCertDBHandleStr NSSLOWCERTCertDBHandle; -typedef struct NSSLOWCERTCertKeyStr NSSLOWCERTCertKey; - -typedef struct NSSLOWCERTTrustStr NSSLOWCERTTrust; -typedef struct NSSLOWCERTCertTrustStr NSSLOWCERTCertTrust; -typedef struct NSSLOWCERTCertificateStr NSSLOWCERTCertificate; -typedef struct NSSLOWCERTCertificateListStr NSSLOWCERTCertificateList; -typedef struct NSSLOWCERTIssuerAndSNStr NSSLOWCERTIssuerAndSN; -typedef struct NSSLOWCERTSignedDataStr NSSLOWCERTSignedData; -typedef struct NSSLOWCERTSubjectPublicKeyInfoStr NSSLOWCERTSubjectPublicKeyInfo; -typedef struct NSSLOWCERTValidityStr NSSLOWCERTValidity; - -/* -** An X.509 validity object -*/ -struct NSSLOWCERTValidityStr { - PRArenaPool *arena; - SECItem notBefore; - SECItem notAfter; -}; - -/* - * A serial number and issuer name, which is used as a database key - */ -struct NSSLOWCERTCertKeyStr { - SECItem serialNumber; - SECItem derIssuer; -}; - -/* -** A signed data object. Used to implement the "signed" macro used -** in the X.500 specs. -*/ -struct NSSLOWCERTSignedDataStr { - SECItem data; - SECAlgorithmID signatureAlgorithm; - SECItem signature; -}; - -/* -** An X.509 subject-public-key-info object -*/ -struct NSSLOWCERTSubjectPublicKeyInfoStr { - PRArenaPool *arena; - SECAlgorithmID algorithm; - SECItem subjectPublicKey; -}; - -typedef struct _certDBEntryCert certDBEntryCert; -typedef struct _certDBEntryRevocation certDBEntryRevocation; - -struct NSSLOWCERTCertTrustStr { - unsigned int sslFlags; - unsigned int emailFlags; - unsigned int objectSigningFlags; -}; - -/* -** PKCS11 Trust representation -*/ -struct NSSLOWCERTTrustStr { - NSSLOWCERTTrust *next; - NSSLOWCERTCertDBHandle *dbhandle; - SECItem dbKey; /* database key for this cert */ - certDBEntryCert *dbEntry; /* database entry struct */ - NSSLOWCERTCertTrust *trust; - SECItem *derCert; /* original DER for the cert */ - unsigned char dbKeySpace[512]; -}; - -/* -** An X.509 certificate object (the unsigned form) -*/ -struct NSSLOWCERTCertificateStr { - /* 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 - */ - NSSLOWCERTCertificate *next; - NSSLOWCERTCertDBHandle *dbhandle; - - SECItem derCert; /* original DER for the cert */ - SECItem derIssuer; /* DER for issuer name */ - SECItem derSN; - SECItem serialNumber; - SECItem derSubject; /* DER for subject name */ - SECItem derSubjKeyInfo; - NSSLOWCERTSubjectPublicKeyInfo *subjectPublicKeyInfo; - SECItem certKey; /* database key for this cert */ - SECItem validity; - certDBEntryCert *dbEntry; /* database entry struct */ - SECItem subjectKeyID; /* x509v3 subject key identifier */ - SECItem extensions; - char *nickname; - char *emailAddr; - NSSLOWCERTCertTrust *trust; - - /* the reference count is modified whenever someone looks up, dups - * or destroys a certificate - */ - int referenceCount; - - char nicknameSpace[200]; - char emailAddrSpace[200]; - unsigned char certKeySpace[512]; -}; - -#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 */ - -struct NSSLOWCERTIssuerAndSNStr { - SECItem derIssuer; - SECItem serialNumber; -}; - -typedef SECStatus (* NSSLOWCERTCertCallback)(NSSLOWCERTCertificate *cert, void *arg); - -/* This is the typedef for the callback passed to nsslowcert_OpenCertDB() */ -/* callback to return database name based on version number */ -typedef char * (*NSSLOWCERTDBNameFunc)(void *arg, int dbVersion); - -/* 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 */ - -/* - * Certificate Database related definitions and data structures - */ - -/* version number of certificate database */ -#define CERT_DB_FILE_VERSION 8 -#define CERT_DB_V7_FILE_VERSION 7 -#define CERT_DB_CONTENT_VERSION 2 - -#define SEC_DB_ENTRY_HEADER_LEN 3 -#define SEC_DB_KEY_HEADER_LEN 1 - -/* All database entries have this form: - * - * byte offset field - * ----------- ----- - * 0 version - * 1 type - * 2 flags - */ - -/* database entry types */ -typedef enum { - certDBEntryTypeVersion = 0, - certDBEntryTypeCert = 1, - certDBEntryTypeNickname = 2, - certDBEntryTypeSubject = 3, - certDBEntryTypeRevocation = 4, - certDBEntryTypeKeyRevocation = 5, - certDBEntryTypeSMimeProfile = 6, - certDBEntryTypeContentVersion = 7, - certDBEntryTypeBlob = 8 -} certDBEntryType; - -typedef struct { - certDBEntryType type; - unsigned int version; - unsigned int flags; - PRArenaPool *arena; -} certDBEntryCommon; - -/* - * Certificate entry: - * - * byte offset field - * ----------- ----- - * 0 sslFlags-msb - * 1 sslFlags-lsb - * 2 emailFlags-msb - * 3 emailFlags-lsb - * 4 objectSigningFlags-msb - * 5 objectSigningFlags-lsb - * 6 derCert-len-msb - * 7 derCert-len-lsb - * 8 nickname-len-msb - * 9 nickname-len-lsb - * ... derCert - * ... nickname - * - * NOTE: the nickname string as stored in the database is null terminated, - * in other words, the last byte of the db entry is always 0 - * if a nickname is present. - * NOTE: if nickname is not present, then nickname-len-msb and - * nickname-len-lsb will both be zero. - */ -struct _certDBEntryCert { - certDBEntryCommon common; - certDBEntryCert *next; - NSSLOWCERTCertTrust trust; - SECItem derCert; - char *nickname; - char nicknameSpace[200]; - unsigned char derCertSpace[2048]; -}; - -/* - * Certificate Nickname entry: - * - * byte offset field - * ----------- ----- - * 0 subjectname-len-msb - * 1 subjectname-len-lsb - * 2... subjectname - * - * The database key for this type of entry is a nickname string - * The "subjectname" value is the DER encoded DN of the identity - * that matches this nickname. - */ -typedef struct { - certDBEntryCommon common; - char *nickname; - SECItem subjectName; -} certDBEntryNickname; - -#define DB_NICKNAME_ENTRY_HEADER_LEN 2 - -/* - * Certificate Subject entry: - * - * byte offset field - * ----------- ----- - * 0 ncerts-msb - * 1 ncerts-lsb - * 2 nickname-msb - * 3 nickname-lsb - * 4 emailAddr-msb - * 5 emailAddr-lsb - * ... nickname - * ... emailAddr - * ...+2*i certkey-len-msb - * ...+1+2*i certkey-len-lsb - * ...+2*ncerts+2*i keyid-len-msb - * ...+1+2*ncerts+2*i keyid-len-lsb - * ... certkeys - * ... keyids - * - * The database key for this type of entry is the DER encoded subject name - * The "certkey" value is an array of certificate database lookup keys that - * points to the database entries for the certificates that matche - * this subject. - * - */ -typedef struct _certDBEntrySubject { - certDBEntryCommon common; - SECItem derSubject; - unsigned int ncerts; - char *nickname; - SECItem *certKeys; - SECItem *keyIDs; - char **emailAddrs; - unsigned int nemailAddrs; -} certDBEntrySubject; - -#define DB_SUBJECT_ENTRY_HEADER_LEN 6 - -/* - * Certificate SMIME profile entry: - * - * byte offset field - * ----------- ----- - * 0 subjectname-len-msb - * 1 subjectname-len-lsb - * 2 smimeoptions-len-msb - * 3 smimeoptions-len-lsb - * 4 options-date-len-msb - * 5 options-date-len-lsb - * 6... subjectname - * ... smimeoptions - * ... options-date - * - * The database key for this type of entry is the email address string - * The "subjectname" value is the DER encoded DN of the identity - * that matches this nickname. - * The "smimeoptions" value is a string that represents the algorithm - * capabilities on the remote user. - * The "options-date" is the date that the smime options value was created. - * This is generally the signing time of the signed message that contained - * the options. It is a UTCTime value. - */ -typedef struct { - certDBEntryCommon common; - char *emailAddr; - SECItem subjectName; - SECItem smimeOptions; - SECItem optionsDate; -} certDBEntrySMime; - -#define DB_SMIME_ENTRY_HEADER_LEN 6 - -/* - * Crl/krl entry: - * - * byte offset field - * ----------- ----- - * 0 derCert-len-msb - * 1 derCert-len-lsb - * 2 url-len-msb - * 3 url-len-lsb - * ... derCert - * ... url - * - * NOTE: the url string as stored in the database is null terminated, - * in other words, the last byte of the db entry is always 0 - * if a nickname is present. - * NOTE: if url is not present, then url-len-msb and - * url-len-lsb will both be zero. - */ -#define DB_CRL_ENTRY_HEADER_LEN 4 -struct _certDBEntryRevocation { - certDBEntryCommon common; - SECItem derCrl; - char *url; /* where to load the crl from */ -}; - -/* - * Database Version Entry: - * - * byte offset field - * ----------- ----- - * only the low level header... - * - * The database key for this type of entry is the string "Version" - */ -typedef struct { - certDBEntryCommon common; -} certDBEntryVersion; - -#define SEC_DB_VERSION_KEY "Version" -#define SEC_DB_VERSION_KEY_LEN sizeof(SEC_DB_VERSION_KEY) - -/* - * Database Content Version Entry: - * - * byte offset field - * ----------- ----- - * 0 contentVersion - * - * The database key for this type of entry is the string "ContentVersion" - */ -typedef struct { - certDBEntryCommon common; - char contentVersion; -} certDBEntryContentVersion; - -#define SEC_DB_CONTENT_VERSION_KEY "ContentVersion" -#define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY) - -typedef union { - certDBEntryCommon common; - certDBEntryCert cert; - certDBEntryContentVersion content; - certDBEntryNickname nickname; - certDBEntryRevocation revocation; - certDBEntrySMime smime; - certDBEntrySubject subject; - certDBEntryVersion version; -} certDBEntry; - -/* length of the fixed part of a database entry */ -#define DBCERT_V4_HEADER_LEN 7 -#define DB_CERT_V5_ENTRY_HEADER_LEN 7 -#define DB_CERT_V6_ENTRY_HEADER_LEN 7 -#define DB_CERT_ENTRY_HEADER_LEN 10 - -/* common flags for all types of certificates */ -#define CERTDB_VALID_PEER (1<<0) -#define CERTDB_TRUSTED (1<<1) -#define CERTDB_SEND_WARN (1<<2) -#define CERTDB_VALID_CA (1<<3) -#define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */ -#define CERTDB_NS_TRUSTED_CA (1<<5) -#define CERTDB_USER (1<<6) -#define CERTDB_TRUSTED_CLIENT_CA (1<<7) /* trusted for issuing client certs */ -#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */ -#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */ -#define CERTDB_NOT_TRUSTED (1<<10) /* explicitly don't trust this cert */ -#define CERTDB_TRUSTED_UNKNOWN (1<<11) /* accept trust from another source */ - -/* bits not affected by the CKO_NETSCAPE_TRUST object */ -#define CERTDB_PRESERVE_TRUST_BITS (CERTDB_USER | CERTDB_VALID_PEER | \ - CERTDB_NS_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_INVISIBLE_CA | \ - CERTDB_GOVT_APPROVED_CA) - -#endif /* _PCERTT_H_ */ diff --git a/security/nss/lib/softoken/legacydb/pk11db.c b/security/nss/lib/softoken/legacydb/pk11db.c deleted file mode 100644 index f85a0a6c3..000000000 --- a/security/nss/lib/softoken/legacydb/pk11db.c +++ /dev/null @@ -1,773 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following code handles the storage of PKCS 11 modules used by the - * NSS. This file is written to abstract away how the modules are - * stored so we can deside that later. - */ - -#include "pk11pars.h" -#include "lgdb.h" -#include "mcom_db.h" -#include "secerr.h" - -#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; } - -/* Construct a database key for a given module */ -static SECStatus secmod_MakeKey(DBT *key, char * module) { - int len = 0; - char *commonName; - - commonName = secmod_argGetParamValue("name",module); - if (commonName == NULL) { - commonName = secmod_argGetParamValue("library",module); - } - if (commonName == NULL) return SECFailure; - len = PORT_Strlen(commonName); - key->data = commonName; - key->size = len; - return SECSuccess; -} - -/* free out constructed database key */ -static void -secmod_FreeKey(DBT *key) -{ - if (key->data) { - PORT_Free(key->data); - } - key->data = NULL; - key->size = 0; -} - -typedef struct secmodDataStr secmodData; -typedef struct secmodSlotDataStr secmodSlotData; -struct secmodDataStr { - unsigned char major; - unsigned char minor; - unsigned char nameStart[2]; - unsigned char slotOffset[2]; - unsigned char internal; - unsigned char fips; - unsigned char ssl[8]; - unsigned char trustOrder[4]; - unsigned char cipherOrder[4]; - unsigned char reserved1; - unsigned char isModuleDB; - unsigned char isModuleDBOnly; - unsigned char isCritical; - unsigned char reserved[4]; - unsigned char names[6]; /* enough space for the length fields */ -}; - -struct secmodSlotDataStr { - unsigned char slotID[4]; - unsigned char defaultFlags[4]; - unsigned char timeout[4]; - unsigned char askpw; - unsigned char hasRootCerts; - unsigned char reserved[18]; /* this makes it a round 32 bytes */ -}; - -#define SECMOD_DB_VERSION_MAJOR 0 -#define SECMOD_DB_VERSION_MINOR 6 -#define SECMOD_DB_EXT1_VERSION_MAJOR 0 -#define SECMOD_DB_EXT1_VERSION_MINOR 6 -#define SECMOD_DB_NOUI_VERSION_MAJOR 0 -#define SECMOD_DB_NOUI_VERSION_MINOR 4 - -#define SECMOD_PUTSHORT(dest,src) \ - (dest)[1] = (unsigned char) ((src)&0xff); \ - (dest)[0] = (unsigned char) (((src) >> 8) & 0xff); -#define SECMOD_PUTLONG(dest,src) \ - (dest)[3] = (unsigned char) ((src)&0xff); \ - (dest)[2] = (unsigned char) (((src) >> 8) & 0xff); \ - (dest)[1] = (unsigned char) (((src) >> 16) & 0xff); \ - (dest)[0] = (unsigned char) (((src) >> 24) & 0xff); -#define SECMOD_GETSHORT(src) \ - ((unsigned short) (((src)[0] << 8) | (src)[1])) -#define SECMOD_GETLONG(src) \ - ((unsigned long) (( (unsigned long) (src)[0] << 24) | \ - ( (unsigned long) (src)[1] << 16) | \ - ( (unsigned long) (src)[2] << 8) | \ - (unsigned long) (src)[3])) - -/* - * build a data base entry from a module - */ -static SECStatus -secmod_EncodeData(DBT *data, char * module) -{ - secmodData *encoded = NULL; - secmodSlotData *slot; - unsigned char *dataPtr; - unsigned short len, len2 = 0, len3 = 0; - int count = 0; - unsigned short offset; - int dataLen, i; - unsigned long order; - unsigned long ssl[2]; - char *commonName = NULL , *dllName = NULL, *param = NULL, *nss = NULL; - char *slotParams, *ciphers; - PK11PreSlotInfo *slotInfo = NULL; - SECStatus rv = SECFailure; - - rv = secmod_argParseModuleSpec(module,&dllName,&commonName,¶m,&nss); - if (rv != SECSuccess) return rv; - rv = SECFailure; - - if (commonName == NULL) { - /* set error */ - goto loser; - } - - len = PORT_Strlen(commonName); - if (dllName) { - len2 = PORT_Strlen(dllName); - } - if (param) { - len3 = PORT_Strlen(param); - } - - slotParams = secmod_argGetParamValue("slotParams",nss); - slotInfo = secmod_argParseSlotInfo(NULL,slotParams,&count); - if (slotParams) PORT_Free(slotParams); - - if (count && slotInfo == NULL) { - /* set error */ - goto loser; - } - - dataLen = sizeof(secmodData) + len + len2 + len3 + sizeof(unsigned short) + - count*sizeof(secmodSlotData); - - data->data = (unsigned char *) PORT_ZAlloc(dataLen); - encoded = (secmodData *)data->data; - dataPtr = (unsigned char *) data->data; - data->size = dataLen; - - if (encoded == NULL) { - /* set error */ - goto loser; - } - - encoded->major = SECMOD_DB_VERSION_MAJOR; - encoded->minor = SECMOD_DB_VERSION_MINOR; - encoded->internal = (unsigned char) - (secmod_argHasFlag("flags","internal",nss) ? 1 : 0); - encoded->fips = (unsigned char) - (secmod_argHasFlag("flags","FIPS",nss) ? 1 : 0); - encoded->isModuleDB = (unsigned char) - (secmod_argHasFlag("flags","isModuleDB",nss) ? 1 : 0); - encoded->isModuleDBOnly = (unsigned char) - (secmod_argHasFlag("flags","isModuleDBOnly",nss) ? 1 : 0); - encoded->isCritical = (unsigned char) - (secmod_argHasFlag("flags","critical",nss) ? 1 : 0); - - order = secmod_argReadLong("trustOrder", nss, SECMOD_DEFAULT_TRUST_ORDER, - NULL); - SECMOD_PUTLONG(encoded->trustOrder,order); - order = secmod_argReadLong("cipherOrder", nss, SECMOD_DEFAULT_CIPHER_ORDER, - NULL); - SECMOD_PUTLONG(encoded->cipherOrder,order); - - - ciphers = secmod_argGetParamValue("ciphers",nss); - secmod_argSetNewCipherFlags(&ssl[0], ciphers); - SECMOD_PUTLONG(encoded->ssl,ssl[0]); - SECMOD_PUTLONG(&encoded->ssl[4],ssl[1]); - if (ciphers) PORT_Free(ciphers); - - offset = (unsigned short) &(((secmodData *)0)->names[0]); - SECMOD_PUTSHORT(encoded->nameStart,offset); - offset = offset + len + len2 + len3 + 3*sizeof(unsigned short); - SECMOD_PUTSHORT(encoded->slotOffset,offset); - - - SECMOD_PUTSHORT(&dataPtr[offset],((unsigned short)count)); - slot = (secmodSlotData *)(dataPtr+offset+sizeof(unsigned short)); - - offset = 0; - SECMOD_PUTSHORT(encoded->names,len); - offset += sizeof(unsigned short); - PORT_Memcpy(&encoded->names[offset],commonName,len); - offset += len; - - - SECMOD_PUTSHORT(&encoded->names[offset],len2); - offset += sizeof(unsigned short); - if (len2) PORT_Memcpy(&encoded->names[offset],dllName,len2); - offset += len2; - - SECMOD_PUTSHORT(&encoded->names[offset],len3); - offset += sizeof(unsigned short); - if (len3) PORT_Memcpy(&encoded->names[offset],param,len3); - offset += len3; - - if (count) { - for (i=0; i < count; i++) { - SECMOD_PUTLONG(slot[i].slotID, slotInfo[i].slotID); - SECMOD_PUTLONG(slot[i].defaultFlags, - slotInfo[i].defaultFlags); - SECMOD_PUTLONG(slot[i].timeout,slotInfo[i].timeout); - slot[i].askpw = slotInfo[i].askpw; - slot[i].hasRootCerts = slotInfo[i].hasRootCerts; - PORT_Memset(slot[i].reserved, 0, sizeof(slot[i].reserved)); - } - } - rv = SECSuccess; - -loser: - if (commonName) PORT_Free(commonName); - if (dllName) PORT_Free(dllName); - if (param) PORT_Free(param); - if (slotInfo) PORT_Free(slotInfo); - if (nss) PORT_Free(nss); - return rv; - -} - -static void -secmod_FreeData(DBT *data) -{ - if (data->data) { - PORT_Free(data->data); - } -} - -static void -secmod_FreeSlotStrings(char **slotStrings, int count) -{ - int i; - - for (i=0; i < count; i++) { - if (slotStrings[i]) { - PR_smprintf_free(slotStrings[i]); - slotStrings[i] = NULL; - } - } -} - -/* - * build a module from the data base entry. - */ -static char * -secmod_DecodeData(char *defParams, DBT *data, PRBool *retInternal) -{ - secmodData *encoded; - secmodSlotData *slots; - PLArenaPool *arena; - char *commonName = NULL; - char *dllName = NULL; - char *parameters = NULL; - char *nss; - char *moduleSpec; - char **slotStrings = NULL; - unsigned char *names; - unsigned long slotCount; - unsigned long ssl0 =0; - unsigned long ssl1 =0; - unsigned long slotID; - unsigned long defaultFlags; - unsigned long timeout; - unsigned long trustOrder =SECMOD_DEFAULT_TRUST_ORDER; - unsigned long cipherOrder =SECMOD_DEFAULT_CIPHER_ORDER; - unsigned short len; - unsigned short namesOffset = 0; /* start of the names block */ - unsigned long namesRunningOffset; /* offset to name we are - * currently processing */ - unsigned short slotOffset; - PRBool isOldVersion = PR_FALSE; - PRBool internal; - PRBool isFIPS; - PRBool isModuleDB =PR_FALSE; - PRBool isModuleDBOnly =PR_FALSE; - PRBool extended =PR_FALSE; - int i; - - - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) - return NULL; - -#define CHECK_SIZE(x) \ - if ((unsigned int) data->size < (unsigned int)(x)) goto db_loser - - /* ------------------------------------------------------------- - ** Process the buffer header, which is the secmodData struct. - ** It may be an old or new version. Check the length for each. - */ - - CHECK_SIZE( offsetof(secmodData, trustOrder[0]) ); - - encoded = (secmodData *)data->data; - - internal = (encoded->internal != 0) ? PR_TRUE: PR_FALSE; - isFIPS = (encoded->fips != 0) ? PR_TRUE: PR_FALSE; - - if (retInternal) - *retInternal = internal; - if (internal) { - parameters = PORT_ArenaStrdup(arena,defParams); - if (parameters == NULL) - goto loser; - } - if (internal && (encoded->major == SECMOD_DB_NOUI_VERSION_MAJOR) && - (encoded->minor <= SECMOD_DB_NOUI_VERSION_MINOR)) { - isOldVersion = PR_TRUE; - } - if ((encoded->major == SECMOD_DB_EXT1_VERSION_MAJOR) && - (encoded->minor >= SECMOD_DB_EXT1_VERSION_MINOR)) { - CHECK_SIZE( sizeof(secmodData)); - trustOrder = SECMOD_GETLONG(encoded->trustOrder); - cipherOrder = SECMOD_GETLONG(encoded->cipherOrder); - isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE: PR_FALSE; - isModuleDBOnly = (encoded->isModuleDBOnly != 0) ? PR_TRUE: PR_FALSE; - extended = PR_TRUE; - } - if (internal && !extended) { - trustOrder = 0; - cipherOrder = 100; - } - /* decode SSL cipher enable flags */ - ssl0 = SECMOD_GETLONG(encoded->ssl); - ssl1 = SECMOD_GETLONG(encoded->ssl + 4); - - slotOffset = SECMOD_GETSHORT(encoded->slotOffset); - namesOffset = SECMOD_GETSHORT(encoded->nameStart); - - - /*-------------------------------------------------------------- - ** Now process the variable length set of names. - ** The names have this structure: - ** struct { - ** BYTE commonNameLen[ 2 ]; - ** BYTE commonName [ commonNameLen ]; - ** BTTE libNameLen [ 2 ]; - ** BYTE libName [ libNameLen ]; - ** If it is "extended" it also has these members: - ** BYTE initStringLen[ 2 ]; - ** BYTE initString [ initStringLen ]; - ** } - */ - - namesRunningOffset = namesOffset; - /* copy the module's common name */ - CHECK_SIZE( namesRunningOffset + 2); - names = (unsigned char *)data->data; - len = SECMOD_GETSHORT(names+namesRunningOffset); - - CHECK_SIZE( namesRunningOffset + 2 + len); - commonName = (char*)PORT_ArenaAlloc(arena,len+1); - if (commonName == NULL) - goto loser; - PORT_Memcpy(commonName, names + namesRunningOffset + 2, len); - commonName[len] = 0; - namesRunningOffset += len + 2; - - /* copy the module's shared library file name. */ - CHECK_SIZE( namesRunningOffset + 2); - len = SECMOD_GETSHORT(names + namesRunningOffset); - if (len) { - CHECK_SIZE( namesRunningOffset + 2 + len); - dllName = (char*)PORT_ArenaAlloc(arena,len + 1); - if (dllName == NULL) - goto loser; - PORT_Memcpy(dllName, names + namesRunningOffset + 2, len); - dllName[len] = 0; - } - namesRunningOffset += len + 2; - - /* copy the module's initialization string, if present. */ - if (!internal && extended) { - CHECK_SIZE( namesRunningOffset + 2); - len = SECMOD_GETSHORT(names+namesRunningOffset); - if (len) { - CHECK_SIZE( namesRunningOffset + 2 + len ); - parameters = (char*)PORT_ArenaAlloc(arena,len + 1); - if (parameters == NULL) - goto loser; - PORT_Memcpy(parameters,names + namesRunningOffset + 2, len); - parameters[len] = 0; - } - namesRunningOffset += len + 2; - } - - /* - * Consistency check: Make sure the slot and names blocks don't - * overlap. These blocks can occur in any order, so this check is made - * in 2 parts. First we check the case where the slot block starts - * after the name block. Later, when we have the slot block length, - * we check the case where slot block starts before the name block. - * NOTE: in most cases any overlap will likely be detected by invalid - * data read from the blocks, but it's better to find out sooner - * than later. - */ - if (slotOffset >= namesOffset) { /* slot block starts after name block */ - if (slotOffset < namesRunningOffset) { - goto db_loser; - } - } - - /* ------------------------------------------------------------------ - ** Part 3, process the slot table. - ** This part has this structure: - ** struct { - ** BYTE slotCount [ 2 ]; - ** secmodSlotData [ slotCount ]; - ** { - */ - - CHECK_SIZE( slotOffset + 2 ); - slotCount = SECMOD_GETSHORT((unsigned char *)data->data + slotOffset); - - /* - * Consistency check: Part 2. We now have the slot block length, we can - * check the case where the slotblock procedes the name block. - */ - if (slotOffset < namesOffset) { /* slot block starts before name block */ - if (namesOffset < slotOffset + 2 + slotCount*sizeof(secmodSlotData)) { - goto db_loser; - } - } - - CHECK_SIZE( (slotOffset + 2 + slotCount * sizeof(secmodSlotData))); - slots = (secmodSlotData *) ((unsigned char *)data->data + slotOffset + 2); - - /* slotCount; */ - slotStrings = (char **)PORT_ArenaZAlloc(arena, slotCount * sizeof(char *)); - if (slotStrings == NULL) - goto loser; - for (i=0; i < (int) slotCount; i++, slots++) { - PRBool hasRootCerts =PR_FALSE; - PRBool hasRootTrust =PR_FALSE; - slotID = SECMOD_GETLONG(slots->slotID); - defaultFlags = SECMOD_GETLONG(slots->defaultFlags); - timeout = SECMOD_GETLONG(slots->timeout); - hasRootCerts = slots->hasRootCerts; - if (isOldVersion && internal && (slotID != 2)) { - unsigned long internalFlags= - secmod_argSlotFlags("slotFlags",SECMOD_SLOT_FLAGS); - defaultFlags |= internalFlags; - } - if (hasRootCerts && !extended) { - trustOrder = 100; - } - - slotStrings[i] = secmod_mkSlotString(slotID, defaultFlags, timeout, - (unsigned char)slots->askpw, - hasRootCerts, hasRootTrust); - if (slotStrings[i] == NULL) { - secmod_FreeSlotStrings(slotStrings,i); - goto loser; - } - } - - nss = secmod_mkNSS(slotStrings, slotCount, internal, isFIPS, isModuleDB, - isModuleDBOnly, internal, trustOrder, cipherOrder, - ssl0, ssl1); - secmod_FreeSlotStrings(slotStrings,slotCount); - /* it's permissible (and normal) for nss to be NULL. it simply means - * there are no NSS specific parameters in the database */ - moduleSpec = secmod_mkNewModuleSpec(dllName,commonName,parameters,nss); - PR_smprintf_free(nss); - PORT_FreeArena(arena,PR_TRUE); - return moduleSpec; - -db_loser: - PORT_SetError(SEC_ERROR_BAD_DATABASE); -loser: - PORT_FreeArena(arena,PR_TRUE); - return NULL; -} - -static DB * -secmod_OpenDB(const char *appName, const char *filename, const char *dbName, - PRBool readOnly, PRBool update) -{ - DB *pkcs11db = NULL; - - - if (appName) { - char *secname = PORT_Strdup(filename); - int len = strlen(secname); - int status = RDB_FAIL; - - if (len >= 3 && PORT_Strcmp(&secname[len-3],".db") == 0) { - secname[len-3] = 0; - } - pkcs11db= - rdbopen(appName, "", secname, readOnly ? NO_RDONLY:NO_RDWR, NULL); - if (update && !pkcs11db) { - DB *updatedb; - - pkcs11db = rdbopen(appName, "", secname, NO_CREATE, &status); - if (!pkcs11db) { - if (status == RDB_RETRY) { - pkcs11db= rdbopen(appName, "", secname, - readOnly ? NO_RDONLY:NO_RDWR, NULL); - } - PORT_Free(secname); - return pkcs11db; - } - updatedb = dbopen(dbName, NO_RDONLY, 0600, DB_HASH, 0); - if (updatedb) { - db_Copy(pkcs11db,updatedb); - (*updatedb->close)(updatedb); - } else { - (*pkcs11db->close)(pkcs11db); - PORT_Free(secname); - return NULL; - } - } - PORT_Free(secname); - return pkcs11db; - } - - /* I'm sure we should do more checks here sometime... */ - pkcs11db = dbopen(dbName, readOnly ? NO_RDONLY : NO_RDWR, 0600, DB_HASH, 0); - - /* didn't exist? create it */ - if (pkcs11db == NULL) { - if (readOnly) - return NULL; - - pkcs11db = dbopen( dbName, NO_CREATE, 0600, DB_HASH, 0 ); - if (pkcs11db) - (* pkcs11db->sync)(pkcs11db, 0); - } - return pkcs11db; -} - -static void -secmod_CloseDB(DB *pkcs11db) -{ - (*pkcs11db->close)(pkcs11db); -} - -static char * -secmod_addEscape(const char *string, char quote) -{ - char *newString = 0; - int escapes = 0, size = 0; - const char *src; - char *dest; - - for (src=string; *src ; src++) { - if ((*src == quote) || (*src == '\\')) escapes++; - size++; - } - - newString = PORT_ZAlloc(escapes+size+1); - if (newString == NULL) { - return NULL; - } - - for (src=string, dest=newString; *src; src++,dest++) { - if ((*src == '\\') || (*src == quote)) { - *dest++ = '\\'; - } - *dest = *src; - } - - return newString; -} - -SECStatus legacy_AddSecmodDB(const char *appName, const char *filename, - const char *dbname, char *module, PRBool rw); - -#define SECMOD_STEP 10 -#define SFTK_DEFAULT_INTERNAL_INIT "library= name=\"NSS Internal PKCS #11 Module\" parameters=\"%s\" NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={%s askpw=any timeout=30})\"" -/* - * Read all the existing modules in - */ -char ** -legacy_ReadSecmodDB(const char *appName, const char *filename, - const char *dbname, char *params, PRBool rw) -{ - DBT key,data; - int ret; - DB *pkcs11db = NULL; - char **moduleList = NULL, **newModuleList = NULL; - int moduleCount = 1; - int useCount = SECMOD_STEP; - - moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **)); - if (moduleList == NULL) return NULL; - - pkcs11db = secmod_OpenDB(appName,filename,dbname,PR_TRUE,rw); - if (pkcs11db == NULL) goto done; - - /* read and parse the file or data base */ - ret = (*pkcs11db->seq)(pkcs11db, &key, &data, R_FIRST); - if (ret) goto done; - - - do { - char *moduleString; - PRBool internal = PR_FALSE; - if ((moduleCount+1) >= useCount) { - useCount += SECMOD_STEP; - newModuleList = - (char **)PORT_Realloc(moduleList,useCount*sizeof(char *)); - if (newModuleList == NULL) goto done; - moduleList = newModuleList; - PORT_Memset(&moduleList[moduleCount+1],0, - sizeof(char *)*SECMOD_STEP); - } - moduleString = secmod_DecodeData(params,&data,&internal); - if (internal) { - moduleList[0] = moduleString; - } else { - moduleList[moduleCount] = moduleString; - moduleCount++; - } - } while ( (*pkcs11db->seq)(pkcs11db, &key, &data, R_NEXT) == 0); - -done: - if (!moduleList[0]) { - char * newparams = secmod_addEscape(params,'"'); - if (newparams) { - moduleList[0] = PR_smprintf(SFTK_DEFAULT_INTERNAL_INIT,newparams, - SECMOD_SLOT_FLAGS); - PORT_Free(newparams); - } - } - /* deal with trust cert db here */ - - if (pkcs11db) { - secmod_CloseDB(pkcs11db); - } else if (moduleList[0] && rw) { - legacy_AddSecmodDB(appName,filename,dbname,moduleList[0], rw) ; - } - if (!moduleList[0]) { - PORT_Free(moduleList); - moduleList = NULL; - } - return moduleList; -} - -SECStatus -legacy_ReleaseSecmodDBData(const char *appName, const char *filename, - const char *dbname, char **moduleSpecList, PRBool rw) -{ - if (moduleSpecList) { - char **index; - for(index = moduleSpecList; *index; index++) { - PR_smprintf_free(*index); - } - PORT_Free(moduleSpecList); - } - return SECSuccess; -} - -/* - * Delete a module from the Data Base - */ -SECStatus -legacy_DeleteSecmodDB(const char *appName, const char *filename, - const char *dbname, char *args, PRBool rw) -{ - DBT key; - SECStatus rv = SECFailure; - DB *pkcs11db = NULL; - int ret; - - if (!rw) return SECFailure; - - /* make sure we have a db handle */ - pkcs11db = secmod_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE); - if (pkcs11db == NULL) { - return SECFailure; - } - - rv = secmod_MakeKey(&key,args); - if (rv != SECSuccess) goto done; - rv = SECFailure; - ret = (*pkcs11db->del)(pkcs11db, &key, 0); - secmod_FreeKey(&key); - if (ret != 0) goto done; - - - ret = (*pkcs11db->sync)(pkcs11db, 0); - if (ret == 0) rv = SECSuccess; - -done: - secmod_CloseDB(pkcs11db); - return rv; -} - -/* - * Add a module to the Data base - */ -SECStatus -legacy_AddSecmodDB(const char *appName, const char *filename, - const char *dbname, char *module, PRBool rw) -{ - DBT key,data; - SECStatus rv = SECFailure; - DB *pkcs11db = NULL; - int ret; - - - if (!rw) return SECFailure; - - /* make sure we have a db handle */ - pkcs11db = secmod_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE); - if (pkcs11db == NULL) { - return SECFailure; - } - - rv = secmod_MakeKey(&key,module); - if (rv != SECSuccess) goto done; - rv = secmod_EncodeData(&data,module); - if (rv != SECSuccess) { - secmod_FreeKey(&key); - goto done; - } - rv = SECFailure; - ret = (*pkcs11db->put)(pkcs11db, &key, &data, 0); - secmod_FreeKey(&key); - secmod_FreeData(&data); - if (ret != 0) goto done; - - ret = (*pkcs11db->sync)(pkcs11db, 0); - if (ret == 0) rv = SECSuccess; - -done: - secmod_CloseDB(pkcs11db); - return rv; -} diff --git a/security/nss/lib/softoken/lgglue.c b/security/nss/lib/softoken/lgglue.c deleted file mode 100644 index b5112dd36..000000000 --- a/security/nss/lib/softoken/lgglue.c +++ /dev/null @@ -1,433 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following code handles the storage of PKCS 11 modules used by the - * NSS. This file is written to abstract away how the modules are - * stored so we can deside that later. - */ -#include "sftkdb.h" -#include "sftkdbti.h" -#include "sdb.h" -#include "prsystem.h" -#include "prprf.h" -#include "prenv.h" -#include "lgglue.h" -#include "secerr.h" -#include "softoken.h" - -static LGOpenFunc legacy_glue_open = NULL; -static LGReadSecmodFunc legacy_glue_readSecmod = NULL; -static LGReleaseSecmodFunc legacy_glue_releaseSecmod = NULL; -static LGDeleteSecmodFunc legacy_glue_deleteSecmod = NULL; -static LGAddSecmodFunc legacy_glue_addSecmod = NULL; -static LGShutdownFunc legacy_glue_shutdown = NULL; - -/* - * The following 3 functions duplicate the work done by bl_LoadLibrary. - * We should make bl_LoadLibrary a global and replace the call to - * sftkdb_LoadLibrary(const char *libname) with it. - */ -#ifdef XP_UNIX -#include <unistd.h> -#define LG_MAX_LINKS 20 -static char * -sftkdb_resolvePath(const char *orig) -{ - int count = 0; - int len =0; - int ret = -1; - char *resolved = NULL; - char *source = NULL; - - len = 1025; /* MAX PATH +1*/ - if (strlen(orig)+1 > len) { - /* PATH TOO LONG */ - return NULL; - } - resolved = PORT_Alloc(len); - if (!resolved) { - return NULL; - } - source = PORT_Alloc(len); - if (!source) { - goto loser; - } - PORT_Strcpy(source, orig); - /* Walk down all the links */ - while ( count++ < LG_MAX_LINKS) { - char *tmp; - /* swap our previous sorce out with resolved */ - /* read it */ - ret = readlink(source, resolved, len-1); - if (ret < 0) { - break; - } - resolved[ret] = 0; - tmp = source; source = resolved; resolved = tmp; - } - if (count > 1) { - ret = 0; - } -loser: - if (resolved) { - PORT_Free(resolved); - } - if (ret < 0) { - if (source) { - PORT_Free(source); - source = NULL; - } - } - return source; -} - -#endif - -static PRLibrary * -sftkdb_LoadFromPath(const char *path, const char *libname) -{ - char *c; - int pathLen, nameLen, fullPathLen; - char *fullPathName = NULL; - PRLibSpec libSpec; - PRLibrary *lib = NULL; - - - /* strip of our parent's library name */ - c = strrchr(path, PR_GetDirectorySeparator()); - if (!c) { - return NULL; /* invalid path */ - } - pathLen = (c-path)+1; - nameLen = strlen(libname); - fullPathLen = pathLen + nameLen +1; - fullPathName = (char *)PORT_Alloc(fullPathLen); - if (fullPathName == NULL) { - return NULL; /* memory allocation error */ - } - PORT_Memcpy(fullPathName, path, pathLen); - PORT_Memcpy(fullPathName+pathLen, libname, nameLen); - fullPathName[fullPathLen-1] = 0; - - libSpec.type = PR_LibSpec_Pathname; - libSpec.value.pathname = fullPathName; - lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); - PORT_Free(fullPathName); - return lib; -} - -static PRLibrary * -sftkdb_LoadLibrary(const char *libname) -{ - PRLibrary *lib = NULL; - PRFuncPtr fn_addr; - char *parentLibPath = NULL; - - fn_addr = (PRFuncPtr) &sftkdb_LoadLibrary; - parentLibPath = PR_GetLibraryFilePathname(SOFTOKEN_LIB_NAME, fn_addr); - - if (!parentLibPath) { - goto done; - } - - lib = sftkdb_LoadFromPath(parentLibPath, libname); -#ifdef XP_UNIX - /* handle symbolic link case */ - if (!lib) { - char *trueParentLibPath = sftkdb_resolvePath(parentLibPath); - if (!trueParentLibPath) { - goto done; - } - lib = sftkdb_LoadFromPath(trueParentLibPath, libname); - PORT_Free(trueParentLibPath); - } -#endif - -done: - if (parentLibPath) { - PORT_Free(parentLibPath); - } - - /* still couldn't load it, try the generic path */ - if (!lib) { - PRLibSpec libSpec; - libSpec.type = PR_LibSpec_Pathname; - libSpec.value.pathname = libname; - lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); - } - return lib; -} - -/* - * stub files for legacy db's to be able to encrypt and decrypt - * various keys and attributes. - */ -static SECStatus -sftkdb_encrypt_stub(PRArenaPool *arena, SDB *sdb, SECItem *plainText, - SECItem **cipherText) -{ - SFTKDBHandle *handle = sdb->app_private; - SECStatus rv; - - if (handle == NULL) { - return SECFailure; - } - - /* if we aren't the key handle, try the other handle */ - if (handle->type != SFTK_KEYDB_TYPE) { - handle = handle->peerDB; - } - - /* not a key handle */ - if (handle == NULL || handle->passwordLock == NULL) { - return SECFailure; - } - - PZ_Lock(handle->passwordLock); - if (handle->passwordKey.data == NULL) { - PZ_Unlock(handle->passwordLock); - /* PORT_SetError */ - return SECFailure; - } - - rv = sftkdb_EncryptAttribute(arena, - handle->newKey?handle->newKey:&handle->passwordKey, - plainText, cipherText); - PZ_Unlock(handle->passwordLock); - - return rv; -} - -/* - * stub files for legacy db's to be able to encrypt and decrypt - * various keys and attributes. - */ -static SECStatus -sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText) -{ - SFTKDBHandle *handle = sdb->app_private; - SECStatus rv; - SECItem *oldKey = NULL; - - if (handle == NULL) { - return SECFailure; - } - - /* if we aren't th handle, try the other handle */ - oldKey = handle->oldKey; - if (handle->type != SFTK_KEYDB_TYPE) { - handle = handle->peerDB; - } - - /* not a key handle */ - if (handle == NULL || handle->passwordLock == NULL) { - return SECFailure; - } - - PZ_Lock(handle->passwordLock); - if (handle->passwordKey.data == NULL) { - PZ_Unlock(handle->passwordLock); - /* PORT_SetError */ - return SECFailure; - } - rv = sftkdb_DecryptAttribute( oldKey ? oldKey : &handle->passwordKey, - cipherText, plainText); - PZ_Unlock(handle->passwordLock); - - return rv; -} - -static PRLibrary *legacy_glue_lib = NULL; -static SECStatus -sftkdbLoad_Legacy() -{ - PRLibrary *lib = NULL; - LGSetCryptFunc setCryptFunction = NULL; - - if (legacy_glue_lib) { - return SECSuccess; - } - - lib = sftkdb_LoadLibrary(SHLIB_PREFIX"nssdbm"SHLIB_VERSION"."SHLIB_SUFFIX); - if (lib == NULL) { - return SECFailure; - } - - legacy_glue_open = (LGOpenFunc)PR_FindFunctionSymbol(lib, "legacy_Open"); - legacy_glue_readSecmod = (LGReadSecmodFunc) PR_FindFunctionSymbol(lib, - "legacy_ReadSecmodDB"); - legacy_glue_releaseSecmod = (LGReleaseSecmodFunc) PR_FindFunctionSymbol(lib, - "legacy_ReleaseSecmodDBData"); - legacy_glue_deleteSecmod = (LGDeleteSecmodFunc) PR_FindFunctionSymbol(lib, - "legacy_DeleteSecmodDB"); - legacy_glue_addSecmod = (LGAddSecmodFunc)PR_FindFunctionSymbol(lib, - "legacy_AddSecmodDB"); - legacy_glue_shutdown = (LGShutdownFunc) PR_FindFunctionSymbol(lib, - "legacy_Shutdown"); - setCryptFunction = (LGSetCryptFunc) PR_FindFunctionSymbol(lib, - "legacy_SetCryptFunctions"); - - if (!legacy_glue_open || !legacy_glue_readSecmod || - !legacy_glue_releaseSecmod || !legacy_glue_deleteSecmod || - !legacy_glue_addSecmod || !setCryptFunction) { - PR_UnloadLibrary(lib); - return SECFailure; - } - setCryptFunction(sftkdb_encrypt_stub,sftkdb_decrypt_stub); - legacy_glue_lib = lib; - return SECSuccess; -} - -CK_RV -sftkdbCall_open(const char *dir, const char *certPrefix, const char *keyPrefix, - int certVersion, int keyVersion, int flags, - SDB **certDB, SDB **keyDB) -{ - SECStatus rv; - - rv = sftkdbLoad_Legacy(); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - if (!legacy_glue_open) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - return (*legacy_glue_open)(dir, certPrefix, keyPrefix, - certVersion, keyVersion, - flags, certDB, keyDB); -} - -char ** -sftkdbCall_ReadSecmodDB(const char *appName, const char *filename, - const char *dbname, char *params, PRBool rw) -{ - SECStatus rv; - - rv = sftkdbLoad_Legacy(); - if (rv != SECSuccess) { - return NULL; - } - if (!legacy_glue_readSecmod) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return NULL; - } - return (*legacy_glue_readSecmod)(appName, filename, dbname, params, rw); -} - -SECStatus -sftkdbCall_ReleaseSecmodDBData(const char *appName, - const char *filename, const char *dbname, - char **moduleSpecList, PRBool rw) -{ - SECStatus rv; - - rv = sftkdbLoad_Legacy(); - if (rv != SECSuccess) { - return rv; - } - if (!legacy_glue_releaseSecmod) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - return (*legacy_glue_releaseSecmod)(appName, filename, dbname, - moduleSpecList, rw); -} - -SECStatus -sftkdbCall_DeleteSecmodDB(const char *appName, - const char *filename, const char *dbname, - char *args, PRBool rw) -{ - SECStatus rv; - - rv = sftkdbLoad_Legacy(); - if (rv != SECSuccess) { - return rv; - } - if (!legacy_glue_deleteSecmod) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - return (*legacy_glue_deleteSecmod)(appName, filename, dbname, args, rw); -} - -SECStatus -sftkdbCall_AddSecmodDB(const char *appName, - const char *filename, const char *dbname, - char *module, PRBool rw) -{ - SECStatus rv; - - rv = sftkdbLoad_Legacy(); - if (rv != SECSuccess) { - return rv; - } - if (!legacy_glue_addSecmod) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } - return (*legacy_glue_addSecmod)(appName, filename, dbname, module, rw); -} - -CK_RV -sftkdbCall_Shutdown(void) -{ - CK_RV crv = CKR_OK; - char *disableUnload = NULL; - if (!legacy_glue_lib) { - return CKR_OK; - } - if (legacy_glue_shutdown) { -#ifdef NO_FORK_CHECK - PRBool parentForkedAfterC_Initialize = PR_FALSE; -#endif - crv = (*legacy_glue_shutdown)(parentForkedAfterC_Initialize); - } - disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD"); - if (!disableUnload) { - PR_UnloadLibrary(legacy_glue_lib); - } - legacy_glue_lib = NULL; - legacy_glue_open = NULL; - legacy_glue_readSecmod = NULL; - legacy_glue_releaseSecmod = NULL; - legacy_glue_deleteSecmod = NULL; - legacy_glue_addSecmod = NULL; - return crv; -} - - diff --git a/security/nss/lib/softoken/lgglue.h b/security/nss/lib/softoken/lgglue.h deleted file mode 100644 index 998f30a94..000000000 --- a/security/nss/lib/softoken/lgglue.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * This code defines the glue layer between softoken and the legacy DB library - */ -#include "sdb.h" - -/* - * function prototypes for the callbacks into softoken from the legacyDB - */ - -typedef SECStatus (*LGEncryptFunc)(PRArenaPool *arena, SDB *sdb, - SECItem *plainText, SECItem **cipherText); -typedef SECStatus (*LGDecryptFunc)(SDB *sdb, SECItem *cipherText, - SECItem **plainText); - -/* - * function prototypes for the exported functions. - */ -typedef CK_RV (*LGOpenFunc) (const char *dir, const char *certPrefix, - const char *keyPrefix, - int certVersion, int keyVersion, int flags, - SDB **certDB, SDB **keyDB); -typedef char ** (*LGReadSecmodFunc)(const char *appName, - const char *filename, - const char *dbname, char *params, PRBool rw); -typedef SECStatus (*LGReleaseSecmodFunc)(const char *appName, - const char *filename, - const char *dbname, char **params, PRBool rw); -typedef SECStatus (*LGDeleteSecmodFunc)(const char *appName, - const char *filename, - const char *dbname, char *params, PRBool rw); -typedef SECStatus (*LGAddSecmodFunc)(const char *appName, - const char *filename, - const char *dbname, char *params, PRBool rw); -typedef SECStatus (*LGShutdownFunc)(PRBool forked); -typedef void (*LGSetForkStateFunc)(PRBool); -typedef void (*LGSetCryptFunc)(LGEncryptFunc, LGDecryptFunc); - -/* - * Softoken Glue Functions - */ -CK_RV sftkdbCall_open(const char *dir, const char *certPrefix, - const char *keyPrefix, - int certVersion, int keyVersion, int flags, - SDB **certDB, SDB **keyDB); -char ** sftkdbCall_ReadSecmodDB(const char *appName, const char *filename, - const char *dbname, char *params, PRBool rw); -SECStatus sftkdbCall_ReleaseSecmodDBData(const char *appName, - const char *filename, const char *dbname, - char **moduleSpecList, PRBool rw); -SECStatus sftkdbCall_DeleteSecmodDB(const char *appName, - const char *filename, const char *dbname, - char *args, PRBool rw); -SECStatus sftkdbCall_AddSecmodDB(const char *appName, - const char *filename, const char *dbname, - char *module, PRBool rw); -CK_RV sftkdbCall_Shutdown(void); - diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c deleted file mode 100644 index 4174cef63..000000000 --- a/security/nss/lib/softoken/lowkey.c +++ /dev/null @@ -1,525 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "lowkeyi.h" -#include "secoid.h" -#include "secitem.h" -#include "secder.h" -#include "base64.h" -#include "secasn1.h" -#include "secerr.h" - -#ifdef NSS_ENABLE_ECC -#include "softoken.h" -#endif - -SEC_ASN1_MKSUB(SEC_AnyTemplate) -SEC_ASN1_MKSUB(SEC_BitStringTemplate) -SEC_ASN1_MKSUB(SEC_ObjectIDTemplate) -SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) - -const SEC_ASN1Template nsslowkey_AttributeTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSLOWKEYAttribute) }, - { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) }, - { SEC_ASN1_SET_OF | SEC_ASN1_XTRN , - offsetof(NSSLOWKEYAttribute, attrValue), - SEC_ASN1_SUB(SEC_AnyTemplate) }, - { 0 } -}; - -const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = { - { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate }, -}; -/* ASN1 Templates for new decoder/encoder */ -const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) }, - { SEC_ASN1_INTEGER, - offsetof(NSSLOWKEYPrivateKeyInfo,version) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSLOWKEYPrivateKeyInfo,algorithm), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSLOWKEYPrivateKeyInfo, attributes), - nsslowkey_SetOfAttributeTemplate }, - { 0 } -}; - -const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) }, - { SEC_ASN1_INTEGER, offsetof(PQGParams,prime) }, - { SEC_ASN1_INTEGER, offsetof(PQGParams,subPrime) }, - { SEC_ASN1_INTEGER, offsetof(PQGParams,base) }, - { 0, } -}; - -const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.version) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.modulus) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.publicExponent) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.privateExponent) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime1) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.prime2) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent1) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.exponent2) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.rsa.coefficient) }, - { 0 } -}; - - -const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.publicValue) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) }, - { 0, } -}; - -const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[] = { - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dsa.privateValue) }, -}; - -const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.publicValue) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.privateValue) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.base) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.dh.prime) }, - { 0, } -}; - -#ifdef NSS_ENABLE_ECC - -/* XXX This is just a placeholder for later when we support - * generic curves and need full-blown support for parsing EC - * parameters. For now, we only support named curves in which - * EC params are simply encoded as an object ID and we don't - * use nsslowkey_ECParamsTemplate. - */ -const SEC_ASN1Template nsslowkey_ECParamsTemplate[] = { - { SEC_ASN1_CHOICE, offsetof(ECParams,type), NULL, sizeof(ECParams) }, - { SEC_ASN1_OBJECT_ID, offsetof(ECParams,curveOID), NULL, ec_params_named }, - { 0, } -}; - - -/* NOTE: The SECG specification allows the private key structure - * to contain curve parameters but recommends that they be stored - * in the PrivateKeyAlgorithmIdentifier field of the PrivateKeyInfo - * instead. - */ -const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[] = { - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPrivateKey) }, - { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPrivateKey,u.ec.version) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSLOWKEYPrivateKey,u.ec.privateValue) }, - /* XXX The following template works for now since we only - * support named curves for which the parameters are - * encoded as an object ID. When we support generic curves, - * we'll need to define nsslowkey_ECParamsTemplate - */ -#if 1 - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams.curveOID), - SEC_ASN1_SUB(SEC_ObjectIDTemplate) }, -#else - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(NSSLOWKEYPrivateKey,u.ec.ecParams), - nsslowkey_ECParamsTemplate }, -#endif - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(NSSLOWKEYPrivateKey,u.ec.publicValue), - SEC_ASN1_SUB(SEC_BitStringTemplate) }, - { 0, } -}; -#endif /* NSS_ENABLE_ECC */ -/* - * 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. - */ - -void -prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *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; -} - -void -prepare_low_pqg_params_for_asn1(PQGParams *params) -{ - params->prime.type = siUnsignedInteger; - params->subPrime.type = siUnsignedInteger; - params->base.type = siUnsignedInteger; -} - -void -prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.dsa.publicValue.type = siUnsignedInteger; - 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; -} - -void -prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.dsa.privateValue.type = siUnsignedInteger; -} - -void -prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.dh.prime.type = siUnsignedInteger; - key->u.dh.base.type = siUnsignedInteger; - key->u.dh.publicValue.type = siUnsignedInteger; - key->u.dh.privateValue.type = siUnsignedInteger; -} - -#ifdef NSS_ENABLE_ECC -void -prepare_low_ecparams_for_asn1(ECParams *params) -{ - params->DEREncoding.type = siUnsignedInteger; - params->curveOID.type = siUnsignedInteger; -} - -void -prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key) -{ - key->u.ec.version.type = siUnsignedInteger; - key->u.ec.ecParams.DEREncoding.type = siUnsignedInteger; - key->u.ec.ecParams.curveOID.type = siUnsignedInteger; - key->u.ec.privateValue.type = siUnsignedInteger; - key->u.ec.publicValue.type = siUnsignedInteger; -} -#endif /* NSS_ENABLE_ECC */ - -void -nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *privk) -{ - if (privk && privk->arena) { - PORT_FreeArena(privk->arena, PR_TRUE); - } -} - -void -nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *pubk) -{ - if (pubk && pubk->arena) { - PORT_FreeArena(pubk->arena, PR_FALSE); - } -} -unsigned -nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubk) -{ - unsigned char b0; - - /* interpret modulus length as key strength... in - * fortezza that's the public key length */ - - switch (pubk->keyType) { - case NSSLOWKEYRSAKey: - b0 = pubk->u.rsa.modulus.data[0]; - return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; - default: - break; - } - return 0; -} - -unsigned -nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privk) -{ - - unsigned char b0; - - switch (privk->keyType) { - case NSSLOWKEYRSAKey: - b0 = privk->u.rsa.modulus.data[0]; - return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len - 1; - default: - break; - } - return 0; -} - -NSSLOWKEYPublicKey * -nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) -{ - NSSLOWKEYPublicKey *pubk; - PLArenaPool *arena; - - - arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - switch(privk->keyType) { - case NSSLOWKEYRSAKey: - case NSSLOWKEYNullKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof (NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - if (privk->keyType == NSSLOWKEYNullKey) return pubk; - rv = SECITEM_CopyItem(arena, &pubk->u.rsa.modulus, - &privk->u.rsa.modulus); - if (rv == SECSuccess) { - rv = SECITEM_CopyItem (arena, &pubk->u.rsa.publicExponent, - &privk->u.rsa.publicExponent); - if (rv == SECSuccess) - return pubk; - } - } else { - PORT_SetError (SEC_ERROR_NO_MEMORY); - } - break; - case NSSLOWKEYDSAKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue, - &privk->u.dsa.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.prime, - &privk->u.dsa.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.subPrime, - &privk->u.dsa.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dsa.params.base, - &privk->u.dsa.params.base); - if (rv == SECSuccess) return pubk; - } - break; - case NSSLOWKEYDHKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue, - &privk->u.dh.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dh.prime, - &privk->u.dh.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, &pubk->u.dh.base, - &privk->u.dh.base); - if (rv == SECSuccess) return pubk; - } - break; -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPublicKey)); - if (pubk != NULL) { - SECStatus rv; - - pubk->arena = arena; - pubk->keyType = privk->keyType; - rv = SECITEM_CopyItem(arena, &pubk->u.ec.publicValue, - &privk->u.ec.publicValue); - if (rv != SECSuccess) break; - pubk->u.ec.ecParams.arena = arena; - /* Copy the rest of the params */ - rv = EC_CopyParams(arena, &(pubk->u.ec.ecParams), - &(privk->u.ec.ecParams)); - if (rv == SECSuccess) return pubk; - } - break; -#endif /* NSS_ENABLE_ECC */ - /* No Fortezza in Low Key implementations (Fortezza keys aren't - * stored in our data base */ - default: - break; - } - - PORT_FreeArena (arena, PR_FALSE); - return NULL; -} - -NSSLOWKEYPrivateKey * -nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey) -{ - NSSLOWKEYPrivateKey *returnKey = NULL; - SECStatus rv = SECFailure; - PLArenaPool *poolp; - - if(!privKey) { - return NULL; - } - - poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if(!poolp) { - return NULL; - } - - returnKey = (NSSLOWKEYPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(NSSLOWKEYPrivateKey)); - if(!returnKey) { - rv = SECFailure; - goto loser; - } - - returnKey->keyType = privKey->keyType; - returnKey->arena = poolp; - - switch(privKey->keyType) { - case NSSLOWKEYRSAKey: - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.modulus), - &(privKey->u.rsa.modulus)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.version), - &(privKey->u.rsa.version)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.publicExponent), - &(privKey->u.rsa.publicExponent)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.privateExponent), - &(privKey->u.rsa.privateExponent)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime1), - &(privKey->u.rsa.prime1)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.prime2), - &(privKey->u.rsa.prime2)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent1), - &(privKey->u.rsa.exponent1)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.exponent2), - &(privKey->u.rsa.exponent2)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.rsa.coefficient), - &(privKey->u.rsa.coefficient)); - if(rv != SECSuccess) break; - break; - case NSSLOWKEYDSAKey: - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.publicValue), - &(privKey->u.dsa.publicValue)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.privateValue), - &(privKey->u.dsa.privateValue)); - if(rv != SECSuccess) break; - returnKey->u.dsa.params.arena = poolp; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.prime), - &(privKey->u.dsa.params.prime)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.subPrime), - &(privKey->u.dsa.params.subPrime)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dsa.params.base), - &(privKey->u.dsa.params.base)); - if(rv != SECSuccess) break; - break; - case NSSLOWKEYDHKey: - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.publicValue), - &(privKey->u.dh.publicValue)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.privateValue), - &(privKey->u.dh.privateValue)); - if(rv != SECSuccess) break; - returnKey->u.dsa.params.arena = poolp; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.prime), - &(privKey->u.dh.prime)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.dh.base), - &(privKey->u.dh.base)); - if(rv != SECSuccess) break; - break; -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.version), - &(privKey->u.ec.version)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.publicValue), - &(privKey->u.ec.publicValue)); - if(rv != SECSuccess) break; - rv = SECITEM_CopyItem(poolp, &(returnKey->u.ec.privateValue), - &(privKey->u.ec.privateValue)); - if(rv != SECSuccess) break; - returnKey->u.ec.ecParams.arena = poolp; - /* Copy the rest of the params */ - rv = EC_CopyParams(poolp, &(returnKey->u.ec.ecParams), - &(privKey->u.ec.ecParams)); - if (rv != SECSuccess) break; - break; -#endif /* NSS_ENABLE_ECC */ - default: - rv = SECFailure; - } - -loser: - - if(rv != SECSuccess) { - PORT_FreeArena(poolp, PR_TRUE); - returnKey = NULL; - } - - return returnKey; -} diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h deleted file mode 100644 index 9c13bfa10..000000000 --- a/security/nss/lib/softoken/lowkeyi.h +++ /dev/null @@ -1,108 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#ifndef _LOWKEYI_H_ -#define _LOWKEYI_H_ - -#include "prtypes.h" -#include "seccomon.h" -#include "secoidt.h" -#include "lowkeyti.h" - -SEC_BEGIN_PROTOS - -/* - * 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. - */ -extern void prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_pqg_params_for_asn1(PQGParams *params); -extern void prepare_low_dsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -#ifdef NSS_ENABLE_ECC -extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key); -extern void prepare_low_ecparams_for_asn1(ECParams *params); -#endif /* NSS_ENABLE_ECC */ - -/* -** Destroy a private key object. -** "key" the object -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void nsslowkey_DestroyPrivateKey(NSSLOWKEYPrivateKey *key); - -/* -** Destroy a public key object. -** "key" the object -** "freeit" if PR_TRUE then free the object as well as its sub-objects -*/ -extern void nsslowkey_DestroyPublicKey(NSSLOWKEYPublicKey *key); - -/* -** Return the modulus length of "pubKey". -*/ -extern unsigned int nsslowkey_PublicModulusLen(NSSLOWKEYPublicKey *pubKey); - - -/* -** Return the modulus length of "privKey". -*/ -extern unsigned int nsslowkey_PrivateModulusLen(NSSLOWKEYPrivateKey *privKey); - - -/* -** Convert a low private key "privateKey" into a public low key -*/ -extern NSSLOWKEYPublicKey - *nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privateKey); - -/* Make a copy of a low private key in it's own arena. - * a return of NULL indicates an error. - */ -extern NSSLOWKEYPrivateKey * -nsslowkey_CopyPrivateKey(NSSLOWKEYPrivateKey *privKey); - - -SEC_END_PROTOS - -#endif /* _LOWKEYI_H_ */ diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h deleted file mode 100644 index 15bb9730a..000000000 --- a/security/nss/lib/softoken/lowkeyti.h +++ /dev/null @@ -1,127 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef _LOWKEYTI_H_ -#define _LOWKEYTI_H_ 1 - -#include "blapit.h" -#include "prtypes.h" -#include "plarena.h" -#include "secitem.h" -#include "secasn1t.h" -#include "secoidt.h" - -/* -** Typedef for callback to get a password "key". -*/ -extern const SEC_ASN1Template nsslowkey_PQGParamsTemplate[]; -extern const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[]; -extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[]; -extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyExportTemplate[]; -extern const SEC_ASN1Template nsslowkey_DHPrivateKeyTemplate[]; -extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[]; -#ifdef NSS_ENABLE_ECC -#define NSSLOWKEY_EC_PRIVATE_KEY_VERSION 1 /* as per SECG 1 C.4 */ -extern const SEC_ASN1Template nsslowkey_ECParamsTemplate[]; -extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[]; -#endif /* NSS_ENABLE_ECC */ - -extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[]; -extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[]; - -/* - * PKCS #8 attributes - */ -struct NSSLOWKEYAttributeStr { - SECItem attrType; - SECItem *attrValue; -}; -typedef struct NSSLOWKEYAttributeStr NSSLOWKEYAttribute; - -/* -** A PKCS#8 private key info object -*/ -struct NSSLOWKEYPrivateKeyInfoStr { - PLArenaPool *arena; - SECItem version; - SECAlgorithmID algorithm; - SECItem privateKey; - NSSLOWKEYAttribute **attributes; -}; -typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo; -#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */ - -typedef enum { - NSSLOWKEYNullKey = 0, - NSSLOWKEYRSAKey = 1, - NSSLOWKEYDSAKey = 2, - NSSLOWKEYDHKey = 4, - NSSLOWKEYECKey = 5 -} NSSLOWKEYType; - -/* -** An RSA public key object. -*/ -struct NSSLOWKEYPublicKeyStr { - PLArenaPool *arena; - NSSLOWKEYType keyType ; - union { - RSAPublicKey rsa; - DSAPublicKey dsa; - DHPublicKey dh; - ECPublicKey ec; - } u; -}; -typedef struct NSSLOWKEYPublicKeyStr NSSLOWKEYPublicKey; - -/* -** Low Level private key object -** This is only used by the raw Crypto engines (crypto), keydb (keydb), -** and PKCS #11. Everyone else uses the high level key structure. -*/ -struct NSSLOWKEYPrivateKeyStr { - PLArenaPool *arena; - NSSLOWKEYType keyType; - union { - RSAPrivateKey rsa; - DSAPrivateKey dsa; - DHPrivateKey dh; - ECPrivateKey ec; - } u; -}; -typedef struct NSSLOWKEYPrivateKeyStr NSSLOWKEYPrivateKey; - -#endif /* _LOWKEYTI_H_ */ diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c deleted file mode 100644 index f91839836..000000000 --- a/security/nss/lib/softoken/lowpbe.c +++ /dev/null @@ -1,1410 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "plarena.h" - -#include "seccomon.h" -#include "secitem.h" -#include "secport.h" -#include "hasht.h" -#include "pkcs11t.h" -#include "blapi.h" -#include "hasht.h" -#include "secasn1.h" -#include "secder.h" -#include "lowpbe.h" -#include "secoid.h" -#include "alghmac.h" -#include "softoken.h" -#include "secerr.h" - -SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) - -/* 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. - */ -static const SEC_ASN1Template NSSPKCS5PBEParameterTemplate[] = -{ - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(NSSPKCS5PBEParameter) }, - { SEC_ASN1_OCTET_STRING, - offsetof(NSSPKCS5PBEParameter, salt) }, - { SEC_ASN1_INTEGER, - offsetof(NSSPKCS5PBEParameter, iteration) }, - { 0 } -}; - -static const SEC_ASN1Template NSSPKCS5PKCS12V2PBEParameterTemplate[] = -{ - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) }, - { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) }, - { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) }, - { 0 } -}; - - -/* PKCS5 v2 */ - -struct nsspkcs5V2PBEParameterStr { - SECAlgorithmID keyParams; /* parameters of the key generation */ - SECAlgorithmID algParams; /* paramters for the encryption or mac op */ -}; - -typedef struct nsspkcs5V2PBEParameterStr nsspkcs5V2PBEParameter; -#define PBKDF2 - -#ifdef PBKDF2 -static const SEC_ASN1Template NSSPKCS5V2PBES2ParameterTemplate[] = -{ - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(nsspkcs5V2PBEParameter) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(nsspkcs5V2PBEParameter, keyParams), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(nsspkcs5V2PBEParameter, algParams), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { 0 } -}; - -static const SEC_ASN1Template NSSPKCS5V2PBEParameterTemplate[] = -{ - { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) }, - /* this is really a choice, but since we don't understand any other - *choice, just inline it. */ - { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) }, - { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) }, - { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, keyLength) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(NSSPKCS5PBEParameter, prfAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { 0 } -}; -#endif - -SECStatus -nsspkcs5_HashBuf(const SECHashObject *hashObj, unsigned char *dest, - unsigned char *src, int len) -{ - void *ctx; - unsigned int retLen; - - ctx = hashObj->create(); - if(ctx == NULL) { - return SECFailure; - } - hashObj->begin(ctx); - hashObj->update(ctx, src, len); - hashObj->end(ctx, dest, &retLen, hashObj->length); - hashObj->destroy(ctx, PR_TRUE); - return SECSuccess; -} - -/* generate bits using any hash - */ -static SECItem * -nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd, - int iter, PRBool faulty3DES) -{ - SECItem *hash = NULL, *pre_hash = NULL; - SECStatus rv = SECFailure; - - if((salt == NULL) || (pwd == NULL) || (iter < 0)) { - return NULL; - } - - hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - - if((hash != NULL) && (pre_hash != NULL)) { - int i, ph_len; - - ph_len = hashObj->length; - if((salt->len + pwd->len) > hashObj->length) { - ph_len = salt->len + pwd->len; - } - - rv = SECFailure; - - /* allocate buffers */ - hash->len = hashObj->length; - hash->data = (unsigned char *)PORT_ZAlloc(hash->len); - pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len); - - /* in pbeSHA1TripleDESCBC there was an allocation error that made - * it into the caller. We do not want to propagate those errors - * further, so we are doing it correctly, but reading the old method. - */ - if (faulty3DES) { - pre_hash->len = ph_len; - } else { - pre_hash->len = salt->len + pwd->len; - } - - /* preform hash */ - if ((hash->data != NULL) && (pre_hash->data != NULL)) { - rv = SECSuccess; - /* check for 0 length password */ - if(pwd->len > 0) { - PORT_Memcpy(pre_hash->data, pwd->data, pwd->len); - } - if(salt->len > 0) { - PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len); - } - for(i = 0; ((i < iter) && (rv == SECSuccess)); i++) { - rv = nsspkcs5_HashBuf(hashObj, hash->data, - pre_hash->data, pre_hash->len); - if(rv != SECFailure) { - pre_hash->len = hashObj->length; - PORT_Memcpy(pre_hash->data, hash->data, hashObj->length); - } - } - } - } - - if(pre_hash != NULL) { - SECITEM_FreeItem(pre_hash, PR_TRUE); - } - - if((rv != SECSuccess) && (hash != NULL)) { - SECITEM_FreeItem(hash, PR_TRUE); - hash = NULL; - } - - return hash; -} - -/* this bit generation routine is described in PKCS 12 and the proposed - * extensions to PKCS 5. an initial hash is generated following the - * instructions laid out in PKCS 5. If the number of bits generated is - * insufficient, then the method discussed in the proposed extensions to - * PKCS 5 in PKCS 12 are used. This extension makes use of the HMAC - * function. And the P_Hash function from the TLS standard. - */ -static SECItem * -nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param, - SECItem *init_hash, unsigned int bytes_needed) -{ - SECItem *ret_bits = NULL; - int hash_size = 0; - unsigned int i; - unsigned int hash_iter; - unsigned int dig_len; - SECStatus rv = SECFailure; - unsigned char *state = NULL; - unsigned int state_len; - HMACContext *cx = NULL; - - hash_size = hashObj->length; - hash_iter = (bytes_needed + (unsigned int)hash_size - 1) / hash_size; - - /* allocate return buffer */ - ret_bits = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if(ret_bits == NULL) - return NULL; - ret_bits->data = (unsigned char *)PORT_ZAlloc((hash_iter * hash_size) + 1); - ret_bits->len = (hash_iter * hash_size); - if(ret_bits->data == NULL) { - PORT_Free(ret_bits); - return NULL; - } - - /* allocate intermediate hash buffer. 8 is for the 8 bytes of - * data which are added based on iteration number - */ - - if ((unsigned int)hash_size > pbe_param->salt.len) { - state_len = hash_size; - } else { - state_len = pbe_param->salt.len; - } - state = (unsigned char *)PORT_ZAlloc(state_len); - if(state == NULL) { - rv = SECFailure; - goto loser; - } - if(pbe_param->salt.len > 0) { - PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len); - } - - cx = HMAC_Create(hashObj, init_hash->data, init_hash->len, PR_TRUE); - if (cx == NULL) { - rv = SECFailure; - goto loser; - } - - for(i = 0; i < hash_iter; i++) { - - /* generate output bits */ - HMAC_Begin(cx); - HMAC_Update(cx, state, state_len); - HMAC_Update(cx, pbe_param->salt.data, pbe_param->salt.len); - rv = HMAC_Finish(cx, ret_bits->data + (i * hash_size), - &dig_len, hash_size); - if (rv != SECSuccess) - goto loser; - PORT_Assert((unsigned int)hash_size == dig_len); - - /* generate new state */ - HMAC_Begin(cx); - HMAC_Update(cx, state, state_len); - rv = HMAC_Finish(cx, state, &state_len, state_len); - if (rv != SECSuccess) - goto loser; - PORT_Assert(state_len == dig_len); - } - -loser: - if (state != NULL) - PORT_ZFree(state, state_len); - HMAC_Destroy(cx, PR_TRUE); - - if(rv != SECSuccess) { - SECITEM_ZfreeItem(ret_bits, PR_TRUE); - ret_bits = NULL; - } - - return ret_bits; -} - -/* generate bits for the key and iv determination. if enough bits - * are not generated using PKCS 5, then we need to generate more bits - * based on the extension proposed in PKCS 12 - */ -static SECItem * -nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj, - NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PRBool faulty3DES) -{ - SECItem * hash = NULL; - SECItem * newHash = NULL; - int bytes_needed; - int bytes_available; - - bytes_needed = pbe_param->ivLen + pbe_param->keyLen; - bytes_available = hashObj->length; - - hash = nsspkcs5_PBKDF1(hashObj, &pbe_param->salt, pwitem, - pbe_param->iter, faulty3DES); - - if(hash == NULL) { - return NULL; - } - - if(bytes_needed <= bytes_available) { - return hash; - } - - newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed); - if (hash != newHash) - SECITEM_FreeItem(hash, PR_TRUE); - return newHash; -} - -#ifdef PBKDF2 - -/* - * PBDKDF2 is PKCS #5 v2.0 it's currently not used by NSS - */ -static void -do_xor(unsigned char *dest, unsigned char *src, int len) -{ - /* use byt xor, not all platforms are happy about inaligned - * integer fetches */ - while (len--) { - *dest = *dest ^ *src; - dest++; - src++; - } -} - -static SECStatus -nsspkcs5_PBKFD2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt, - int iterations, unsigned int i, unsigned char *T) -{ - int j; - HMACContext *cx = NULL; - unsigned int hLen = hashobj->length; - SECStatus rv = SECFailure; - unsigned char *last = NULL; - unsigned int lastLength = salt->len + 4; - unsigned int lastBufLength; - - cx=HMAC_Create(hashobj,pwitem->data,pwitem->len,PR_FALSE); - if (cx == NULL) { - goto loser; - } - PORT_Memset(T,0,hLen); - lastBufLength = PR_MAX(lastLength, hLen); - last = PORT_Alloc(lastBufLength); - if (last == NULL) { - goto loser; - } - PORT_Memcpy(last,salt->data,salt->len); - last[salt->len ] = (i >> 24) & 0xff; - last[salt->len+1] = (i >> 16) & 0xff; - last[salt->len+2] = (i >> 8) & 0xff; - last[salt->len+3] = i & 0xff; - - /* NOTE: we need at least one iteration to return success! */ - for (j=0; j < iterations; j++) { - HMAC_Begin(cx); - HMAC_Update(cx,last,lastLength); - rv =HMAC_Finish(cx,last,&lastLength,hLen); - if (rv !=SECSuccess) { - break; - } - do_xor(T,last,hLen); - } -loser: - if (cx) { - HMAC_Destroy(cx, PR_TRUE); - } - if (last) { - PORT_ZFree(last,lastBufLength); - } - return rv; -} - -static SECItem * -nsspkcs5_PBKDF2(const SECHashObject *hashobj, NSSPKCS5PBEParameter *pbe_param, - SECItem *pwitem) -{ - int iterations = pbe_param->iter; - int bytesNeeded = pbe_param->keyLen; - unsigned int dkLen = bytesNeeded; - unsigned int hLen = hashobj->length; - unsigned int nblocks = (dkLen+hLen-1) / hLen; - unsigned int i; - unsigned char *rp; - unsigned char *T = NULL; - SECItem *result = NULL; - SECItem *salt = &pbe_param->salt; - SECStatus rv = SECFailure; - - result = SECITEM_AllocItem(NULL,NULL,nblocks*hLen); - if (result == NULL) { - return NULL; - } - - T = PORT_Alloc(hLen); - if (T == NULL) { - goto loser; - } - - for (i=1,rp=result->data; i <= nblocks ; i++, rp +=hLen) { - rv = nsspkcs5_PBKFD2_F(hashobj,pwitem,salt,iterations,i,T); - if (rv != SECSuccess) { - break; - } - PORT_Memcpy(rp,T,hLen); - } - -loser: - if (T) { - PORT_ZFree(T,hLen); - } - if (rv != SECSuccess) { - SECITEM_FreeItem(result,PR_TRUE); - result = NULL; - } else { - result->len = dkLen; - } - - return result; -} -#endif - -#define HMAC_BUFFER 64 -#define NSSPBE_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y)) -#define NSSPBE_MIN(x,y) ((x) < (y) ? (x) : (y)) -/* - * This is the extended PBE function defined by the final PKCS #12 spec. - */ -static SECItem * -nsspkcs5_PKCS12PBE(const SECHashObject *hashObject, - NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, - PBEBitGenID bitGenPurpose, unsigned int bytesNeeded) -{ - PRArenaPool *arena = NULL; - unsigned int SLen,PLen; - unsigned int hashLength = hashObject->length; - unsigned char *S, *P; - SECItem *A = NULL, B, D, I; - SECItem *salt = &pbe_param->salt; - unsigned int c,i = 0; - unsigned int hashLen; - int iter; - unsigned char *iterBuf; - void *hash = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if(!arena) { - return NULL; - } - - /* how many hash object lengths are needed */ - c = (bytesNeeded + (hashLength-1))/hashLength; - - /* initialize our buffers */ - D.len = HMAC_BUFFER; - /* B and D are the same length, use one alloc go get both */ - D.data = (unsigned char*)PORT_ArenaZAlloc(arena, D.len*2); - B.len = D.len; - B.data = D.data + D.len; - - /* if all goes well, A will be returned, so don't use our temp arena */ - A = SECITEM_AllocItem(NULL,NULL,c*hashLength); - if (A == NULL) { - goto loser; - } - - SLen = NSSPBE_ROUNDUP(salt->len,HMAC_BUFFER); - PLen = NSSPBE_ROUNDUP(pwitem->len,HMAC_BUFFER); - I.len = SLen+PLen; - I.data = (unsigned char*)PORT_ArenaZAlloc(arena, I.len); - if (I.data == NULL) { - goto loser; - } - - /* S & P are only used to initialize I */ - S = I.data; - P = S + SLen; - - PORT_Memset(D.data, (char)bitGenPurpose, D.len); - if (SLen) { - for (i=0; i < SLen; i += salt->len) { - PORT_Memcpy(S+i, salt->data, NSSPBE_MIN(SLen-i,salt->len)); - } - } - if (PLen) { - for (i=0; i < PLen; i += pwitem->len) { - PORT_Memcpy(P+i, pwitem->data, NSSPBE_MIN(PLen-i,pwitem->len)); - } - } - - iterBuf = (unsigned char*)PORT_ArenaZAlloc(arena,hashLength); - if (iterBuf == NULL) { - goto loser; - } - - hash = hashObject->create(); - if(!hash) { - goto loser; - } - /* calculate the PBE now */ - for(i = 0; i < c; i++) { - int Bidx; /* must be signed or the for loop won't terminate */ - unsigned int k, j; - unsigned char *Ai = A->data+i*hashLength; - - - for(iter = 0; iter < pbe_param->iter; iter++) { - hashObject->begin(hash); - - if (iter) { - hashObject->update(hash, iterBuf, hashLen); - } else { - hashObject->update(hash, D.data, D.len); - hashObject->update(hash, I.data, I.len); - } - - hashObject->end(hash, iterBuf, &hashLen, hashObject->length); - if(hashLen != hashObject->length) { - break; - } - } - - PORT_Memcpy(Ai, iterBuf, hashLength); - for (Bidx = 0; Bidx < B.len; Bidx += hashLength) { - PORT_Memcpy(B.data+Bidx,iterBuf,NSSPBE_MIN(B.len-Bidx,hashLength)); - } - - k = I.len/B.len; - for(j = 0; j < k; j++) { - unsigned int q, carryBit; - unsigned char *Ij = I.data + j*B.len; - - /* (Ij = Ij+B+1) */ - for (Bidx = (B.len-1), q=1, carryBit=0; Bidx >= 0; Bidx--,q=0) { - q += (unsigned int)Ij[Bidx]; - q += (unsigned int)B.data[Bidx]; - q += carryBit; - - carryBit = (q > 0xff); - Ij[Bidx] = (unsigned char)(q & 0xff); - } - } - } -loser: - if (hash) { - hashObject->destroy(hash, PR_TRUE); - } - if(arena) { - PORT_FreeArena(arena, PR_TRUE); - } - - if (A) { - /* if i != c, then we didn't complete the loop above and must of failed - * somwhere along the way */ - if (i != c) { - SECITEM_ZfreeItem(A,PR_TRUE); - A = NULL; - } else { - A->len = bytesNeeded; - } - } - - return A; -} - -/* - * generate key as per PKCS 5 - */ -SECItem * -nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, - SECItem *iv, PRBool faulty3DES) -{ - SECItem *hash = NULL, *key = NULL; - const SECHashObject *hashObj; - PRBool getIV = PR_FALSE; - - if((pbe_param == NULL) || (pwitem == NULL)) { - return NULL; - } - - key = SECITEM_AllocItem(NULL,NULL,pbe_param->keyLen); - if (key == NULL) { - return NULL; - } - - if (iv && (pbe_param->ivLen) && (iv->data == NULL)) { - getIV = PR_TRUE; - iv->data = (unsigned char *)PORT_Alloc(pbe_param->ivLen); - if (iv->data == NULL) { - goto loser; - } - iv->len = pbe_param->ivLen; - } - - hashObj = HASH_GetRawHashObject(pbe_param->hashType); - switch (pbe_param->pbeType) { - case NSSPKCS5_PBKDF1: - hash = nsspkcs5_PBKDF1Extended(hashObj,pbe_param,pwitem,faulty3DES); - if (hash == NULL) { - goto loser; - } - PORT_Assert(hash->len >= key->len+(getIV ? iv->len : 0)); - if (getIV) { - PORT_Memcpy(iv->data, hash->data+(hash->len - iv->len),iv->len); - } - - break; -#ifdef PBKDF2 - case NSSPKCS5_PBKDF2: - hash = nsspkcs5_PBKDF2(hashObj,pbe_param,pwitem); - if (getIV) { - PORT_Memcpy(iv->data, pbe_param->ivData, iv->len); - } - break; -#endif - case NSSPKCS5_PKCS12_V2: - if (getIV) { - hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem, - pbeBitGenCipherIV,iv->len); - if (hash == NULL) { - goto loser; - } - PORT_Memcpy(iv->data,hash->data,iv->len); - SECITEM_ZfreeItem(hash,PR_TRUE); - hash = NULL; - } - hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem, - pbe_param->keyID,key->len); - default: - break; - } - - if (hash == NULL) { - goto loser; - } - - if (pbe_param->is2KeyDES) { - PORT_Memcpy(key->data, hash->data, (key->len * 2) / 3); - PORT_Memcpy(&(key->data[(key->len * 2) / 3]), key->data, - key->len / 3); - } else { - PORT_Memcpy(key->data, hash->data, key->len); - } - - SECITEM_ZfreeItem(hash, PR_TRUE); - return key; - -loser: - if (getIV && iv->data) { - PORT_ZFree(iv->data,iv->len); - iv->data = NULL; - } - - SECITEM_ZfreeItem(key, PR_TRUE); - return NULL; -} - -static SECStatus -nsspkcs5_FillInParam(SECOidTag algorithm, NSSPKCS5PBEParameter *pbe_param) -{ - PRBool skipType = PR_FALSE; - - pbe_param->keyLen = 5; - pbe_param->ivLen = 8; - pbe_param->hashType = HASH_AlgSHA1; - pbe_param->pbeType = NSSPKCS5_PBKDF1; - pbe_param->encAlg = SEC_OID_RC2_CBC; - pbe_param->is2KeyDES = PR_FALSE; - switch(algorithm) { - /* DES3 Algorithms */ - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: - pbe_param->is2KeyDES = PR_TRUE; - /* fall through */ - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: - pbe_param->pbeType = NSSPKCS5_PKCS12_V2; - /* fall through */ - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: - pbe_param->keyLen = 24; - pbe_param->encAlg = SEC_OID_DES_EDE3_CBC; - break; - - /* DES Algorithms */ - case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: - pbe_param->hashType = HASH_AlgMD2; - goto finish_des; - case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: - pbe_param->hashType = HASH_AlgMD5; - /* fall through */ - case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: -finish_des: - pbe_param->keyLen = 8; - pbe_param->encAlg = SEC_OID_DES_CBC; - break; - - /* RC2 Algorithms */ - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: - pbe_param->keyLen = 16; - /* fall through */ - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: - pbe_param->pbeType = NSSPKCS5_PKCS12_V2; - break; - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: - pbe_param->keyLen = 16; - /* fall through */ - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: - break; - - /* RC4 algorithms */ - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: - skipType = PR_TRUE; - /* fall through */ - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: - pbe_param->keyLen = 16; - /* fall through */ - case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: - if (!skipType) { - pbe_param->pbeType = NSSPKCS5_PKCS12_V2; - } - /* fall through */ - case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: - pbe_param->ivLen = 0; - pbe_param->encAlg = SEC_OID_RC4; - break; - -#ifdef PBKDF2 - case SEC_OID_PKCS5_PBKDF2: - case SEC_OID_PKCS5_PBES2: - case SEC_OID_PKCS5_PBMAC1: - /* everything else will be filled in by the template */ - pbe_param->ivLen = 0; - pbe_param->pbeType = NSSPKCS5_PBKDF2; - pbe_param->encAlg = SEC_OID_PKCS5_PBKDF2; - pbe_param->keyLen = 0; /* needs to be set by caller after return */ - break; -#endif - - default: - return SECFailure; - } - - return SECSuccess; -} - -/* decode the algid and generate a PKCS 5 parameter from it - */ -NSSPKCS5PBEParameter * -nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator) -{ - PRArenaPool *arena = NULL; - NSSPKCS5PBEParameter *pbe_param = NULL; - SECStatus rv = SECFailure; - - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) - return NULL; - - /* allocate memory for the parameter */ - pbe_param = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena, - sizeof(NSSPKCS5PBEParameter)); - - if (pbe_param == NULL) { - goto loser; - } - - pbe_param->poolp = arena; - - rv = nsspkcs5_FillInParam(alg, pbe_param); - if (rv != SECSuccess) { - goto loser; - } - - pbe_param->iter = iterator; - if (salt) { - rv = SECITEM_CopyItem(arena,&pbe_param->salt,salt); - } - - /* default key gen */ - pbe_param->keyID = pbeBitGenCipherKey; - -loser: - if (rv != SECSuccess) { - PORT_FreeArena(arena, PR_TRUE); - pbe_param = NULL; - } - - return pbe_param; -} - -/* - * find the hash type needed to implement a specific HMAC. - * OID definitions are from pkcs 5 v2.0 and 2.1 - */ -HASH_HashType -HASH_FromHMACOid(SECOidTag hmac) -{ - switch (hmac) { - case SEC_OID_HMAC_SHA1: - return HASH_AlgSHA1; - case SEC_OID_HMAC_SHA256: - return HASH_AlgSHA256; - case SEC_OID_HMAC_SHA384: - return HASH_AlgSHA384; - case SEC_OID_HMAC_SHA512: - return HASH_AlgSHA512; - case SEC_OID_HMAC_SHA224: - default: - break; - } - return HASH_AlgNULL; -} - -/* decode the algid and generate a PKCS 5 parameter from it - */ -NSSPKCS5PBEParameter * -nsspkcs5_AlgidToParam(SECAlgorithmID *algid) -{ - NSSPKCS5PBEParameter *pbe_param = NULL; - nsspkcs5V2PBEParameter pbev2_param; - SECOidTag algorithm; - SECStatus rv = SECFailure; - - if (algid == NULL) { - return NULL; - } - - algorithm = SECOID_GetAlgorithmTag(algid); - if (algorithm == SEC_OID_UNKNOWN) { - goto loser; - } - - pbe_param = nsspkcs5_NewParam(algorithm, NULL, 1); - if (pbe_param == NULL) { - goto loser; - } - - /* decode parameter */ - rv = SECFailure; - switch (pbe_param->pbeType) { - case NSSPKCS5_PBKDF1: - rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, - NSSPKCS5PBEParameterTemplate, &algid->parameters); - break; - case NSSPKCS5_PKCS12_V2: - rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, - NSSPKCS5PKCS12V2PBEParameterTemplate, &algid->parameters); - break; -#ifdef PBKDF2 - case NSSPKCS5_PBKDF2: - PORT_Memset(&pbev2_param,0, sizeof(pbev2_param)); - /* just the PBE */ - if (algorithm == SEC_OID_PKCS5_PBKDF2) { - rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, - NSSPKCS5V2PBEParameterTemplate, &algid->parameters); - } else { - /* PBE data an others */ - rv = SEC_ASN1DecodeItem(pbe_param->poolp, &pbev2_param, - NSSPKCS5V2PBES2ParameterTemplate, &algid->parameters); - if (rv != SECSuccess) { - break; - } - pbe_param->encAlg = SECOID_GetAlgorithmTag(&pbev2_param.algParams); - rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, - NSSPKCS5V2PBEParameterTemplate, - &pbev2_param.keyParams.parameters); - if (rv != SECSuccess) { - break; - } - pbe_param->keyLen = DER_GetInteger(&pbe_param->keyLength); - } - /* we we are encrypting, save any iv's */ - if (algorithm == SEC_OID_PKCS5_PBES2) { - pbe_param->ivLen = pbev2_param.algParams.parameters.len; - pbe_param->ivData = pbev2_param.algParams.parameters.data; - } - pbe_param->hashType = - HASH_FromHMACOid(SECOID_GetAlgorithmTag(&pbe_param->prfAlg)); - if (pbe_param->hashType == HASH_AlgNULL) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rv = SECFailure; - } - break; -#endif - } - -loser: - if (rv == SECSuccess) { - pbe_param->iter = DER_GetInteger(&pbe_param->iteration); - } else { - nsspkcs5_DestroyPBEParameter(pbe_param); - pbe_param = NULL; - } - - return pbe_param; -} - -/* destroy a pbe parameter. it assumes that the parameter was - * generated using the appropriate create function and therefor - * contains an arena pool. - */ -void -nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param) -{ - if (pbe_param != NULL) { - PORT_FreeArena(pbe_param->poolp, PR_FALSE); - } -} - - -/* crypto routines */ -/* perform DES encryption and decryption. these routines are called - * by nsspkcs5_CipherData. In the case of an error, NULL is returned. - */ -static SECItem * -sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des, - PRBool encrypt) -{ - SECItem *dest; - SECItem *dup_src; - SECStatus rv = SECFailure; - int pad; - - if((src == NULL) || (key == NULL) || (iv == NULL)) - return NULL; - - dup_src = SECITEM_DupItem(src); - if(dup_src == NULL) { - return NULL; - } - - if(encrypt != PR_FALSE) { - void *dummy; - - dummy = CBC_PadBuffer(NULL, dup_src->data, - dup_src->len, &dup_src->len, 8 /* DES_BLOCK_SIZE */); - if(dummy == NULL) { - SECITEM_FreeItem(dup_src, PR_TRUE); - return NULL; - } - dup_src->data = (unsigned char*)dummy; - } - - dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if(dest != NULL) { - /* allocate with over flow */ - dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64); - if(dest->data != NULL) { - DESContext *ctxt; - ctxt = DES_CreateContext(key->data, iv->data, - (triple_des ? NSS_DES_EDE3_CBC : NSS_DES_CBC), - encrypt); - - if(ctxt != NULL) { - rv = (encrypt ? DES_Encrypt : DES_Decrypt)( - ctxt, dest->data, &dest->len, - dup_src->len + 64, dup_src->data, dup_src->len); - - /* remove padding -- assumes 64 bit blocks */ - if((encrypt == PR_FALSE) && (rv == SECSuccess)) { - pad = dest->data[dest->len-1]; - if((pad > 0) && (pad <= 8)) { - if(dest->data[dest->len-pad] != pad) { - rv = SECFailure; - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - } else { - dest->len -= pad; - } - } else { - rv = SECFailure; - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - } - } - DES_DestroyContext(ctxt, PR_TRUE); - } - } - } - - if(rv == SECFailure) { - if(dest != NULL) { - SECITEM_FreeItem(dest, PR_TRUE); - } - dest = NULL; - } - - if(dup_src != NULL) { - SECITEM_FreeItem(dup_src, PR_TRUE); - } - - return dest; -} - -/* perform aes encryption/decryption if an error occurs, NULL is returned - */ -static SECItem * -sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des, - PRBool encrypt) -{ - SECItem *dest; - SECItem *dup_src; - SECStatus rv = SECFailure; - int pad; - - if((src == NULL) || (key == NULL) || (iv == NULL)) - return NULL; - - dup_src = SECITEM_DupItem(src); - if(dup_src == NULL) { - return NULL; - } - - if(encrypt != PR_FALSE) { - void *dummy; - - dummy = CBC_PadBuffer(NULL, dup_src->data, - dup_src->len, &dup_src->len,AES_BLOCK_SIZE); - if(dummy == NULL) { - SECITEM_FreeItem(dup_src, PR_TRUE); - return NULL; - } - dup_src->data = (unsigned char*)dummy; - } - - dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if(dest != NULL) { - /* allocate with over flow */ - dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64); - if(dest->data != NULL) { - AESContext *ctxt; - ctxt = AES_CreateContext(key->data, iv->data, - NSS_AES_CBC, encrypt, key->len, 16); - - if(ctxt != NULL) { - rv = (encrypt ? AES_Encrypt : AES_Decrypt)( - ctxt, dest->data, &dest->len, - dup_src->len + 64, dup_src->data, dup_src->len); - - /* remove padding -- assumes 64 bit blocks */ - if((encrypt == PR_FALSE) && (rv == SECSuccess)) { - pad = dest->data[dest->len-1]; - if((pad > 0) && (pad <= 16)) { - if(dest->data[dest->len-pad] != pad) { - rv = SECFailure; - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - } else { - dest->len -= pad; - } - } else { - rv = SECFailure; - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - } - } - AES_DestroyContext(ctxt, PR_TRUE); - } - } - } - - if(rv == SECFailure) { - if(dest != NULL) { - SECITEM_FreeItem(dest, PR_TRUE); - } - dest = NULL; - } - - if(dup_src != NULL) { - SECITEM_FreeItem(dup_src, PR_TRUE); - } - - return dest; -} - -/* perform rc2 encryption/decryption if an error occurs, NULL is returned - */ -static SECItem * -sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy, - PRBool encrypt) -{ - SECItem *dest; - SECItem *dup_src; - SECStatus rv = SECFailure; - int pad; - - if((src == NULL) || (key == NULL) || (iv == NULL)) { - return NULL; - } - - dup_src = SECITEM_DupItem(src); - if(dup_src == NULL) { - return NULL; - } - - if(encrypt != PR_FALSE) { - void *dummy; - - dummy = CBC_PadBuffer(NULL, dup_src->data, - dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */); - if(dummy == NULL) { - SECITEM_FreeItem(dup_src, PR_TRUE); - return NULL; - } - dup_src->data = (unsigned char*)dummy; - } - - dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if(dest != NULL) { - dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64); - if(dest->data != NULL) { - RC2Context *ctxt; - - ctxt = RC2_CreateContext(key->data, key->len, iv->data, - NSS_RC2_CBC, key->len); - - if(ctxt != NULL) { - rv = (encrypt ? RC2_Encrypt: RC2_Decrypt)( - ctxt, dest->data, &dest->len, - dup_src->len + 64, dup_src->data, dup_src->len); - - /* assumes 8 byte blocks -- remove padding */ - if((rv == SECSuccess) && (encrypt != PR_TRUE)) { - pad = dest->data[dest->len-1]; - if((pad > 0) && (pad <= 8)) { - if(dest->data[dest->len-pad] != pad) { - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - rv = SECFailure; - } else { - dest->len -= pad; - } - } else { - PORT_SetError(SEC_ERROR_BAD_PASSWORD); - rv = SECFailure; - } - } - - } - } - } - - if((rv != SECSuccess) && (dest != NULL)) { - SECITEM_FreeItem(dest, PR_TRUE); - dest = NULL; - } - - if(dup_src != NULL) { - SECITEM_FreeItem(dup_src, PR_TRUE); - } - - return dest; -} - -/* perform rc4 encryption and decryption */ -static SECItem * -sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op, - PRBool encrypt) -{ - SECItem *dest; - SECStatus rv = SECFailure; - - if((src == NULL) || (key == NULL) || (iv == NULL)) { - return NULL; - } - - dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); - if(dest != NULL) { - dest->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) * - (src->len + 64)); - if(dest->data != NULL) { - RC4Context *ctxt; - - ctxt = RC4_CreateContext(key->data, key->len); - if(ctxt) { - rv = (encrypt ? RC4_Encrypt : RC4_Decrypt)( - ctxt, dest->data, &dest->len, - src->len + 64, src->data, src->len); - RC4_DestroyContext(ctxt, PR_TRUE); - } - } - } - - if((rv != SECSuccess) && (dest)) { - SECITEM_FreeItem(dest, PR_TRUE); - dest = NULL; - } - - return dest; -} -/* function pointer template for crypto functions */ -typedef SECItem *(* pkcs5_crypto_func)(SECItem *key, SECItem *iv, - SECItem *src, PRBool op1, PRBool op2); - -/* performs the cipher operation on the src and returns the result. - * if an error occurs, NULL is returned. - * - * a null length password is allowed. this corresponds to encrypting - * the data with ust the salt. - */ -/* change this to use PKCS 11? */ -SECItem * -nsspkcs5_CipherData(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, - SECItem *src, PRBool encrypt, PRBool *update) -{ - SECItem *key = NULL, iv; - SECItem *dest = NULL; - PRBool tripleDES = PR_TRUE; - pkcs5_crypto_func cryptof; - - iv.data = NULL; - - if (update) { - *update = PR_FALSE; - } - - if ((pwitem == NULL) || (src == NULL)) { - return NULL; - } - - /* get key, and iv */ - key = nsspkcs5_ComputeKeyAndIV(pbe_param, pwitem, &iv, PR_FALSE); - if(key == NULL) { - return NULL; - } - - switch(pbe_param->encAlg) { - /* PKCS 5 v2 only */ - case SEC_OID_AES_128_CBC: - case SEC_OID_AES_192_CBC: - case SEC_OID_AES_256_CBC: - cryptof = sec_pkcs5_aes; - break; - case SEC_OID_DES_EDE3_CBC: - cryptof = sec_pkcs5_des; - tripleDES = PR_TRUE; - break; - case SEC_OID_DES_CBC: - cryptof = sec_pkcs5_des; - tripleDES = PR_FALSE; - break; - case SEC_OID_RC2_CBC: - cryptof = sec_pkcs5_rc2; - break; - case SEC_OID_RC4: - cryptof = sec_pkcs5_rc4; - break; - default: - cryptof = NULL; - break; - } - - if (cryptof == NULL) { - goto loser; - } - - dest = (*cryptof)(key, &iv, src, tripleDES, encrypt); - /* - * it's possible for some keys and keydb's to claim to - * be triple des when they're really des. In this case - * we simply try des. If des works we set the update flag - * so the key db knows it needs to update all it's entries. - * The case can only happen on decrypted of a - * SEC_OID_DES_EDE3_CBD. - */ - if ((dest == NULL) && (encrypt == PR_FALSE) && - (pbe_param->encAlg == SEC_OID_DES_EDE3_CBC)) { - dest = (*cryptof)(key, &iv, src, PR_FALSE, encrypt); - if (update && (dest != NULL)) *update = PR_TRUE; - } - -loser: - if (key != NULL) { - SECITEM_ZfreeItem(key, PR_TRUE); - } - if (iv.data != NULL) { - SECITEM_ZfreeItem(&iv, PR_FALSE); - } - - return dest; -} - -/* 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 * -nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm, - NSSPKCS5PBEParameter *pbe_param) -{ - SECAlgorithmID *algid, *ret_algid = NULL; - SECItem der_param; - nsspkcs5V2PBEParameter pkcs5v2_param; - - SECStatus rv = SECFailure; - void *dummy = NULL; - - if (arena == NULL) { - return NULL; - } - - der_param.data = NULL; - der_param.len = 0; - - /* generate the algorithm id */ - algid = (SECAlgorithmID *)PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID)); - if (algid == NULL) { - goto loser; - } - - if (pbe_param->iteration.data == NULL) { - dummy = SEC_ASN1EncodeInteger(pbe_param->poolp,&pbe_param->iteration, - pbe_param->iter); - if (dummy == NULL) { - goto loser; - } - } - switch (pbe_param->pbeType) { - case NSSPKCS5_PBKDF1: - dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param, - NSSPKCS5PBEParameterTemplate); - break; - case NSSPKCS5_PKCS12_V2: - dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param, - NSSPKCS5PKCS12V2PBEParameterTemplate); - break; -#ifdef PBKDF2 - case NSSPKCS5_PBKDF2: - if (pbe_param->keyLength.data == NULL) { - dummy = SEC_ASN1EncodeInteger(pbe_param->poolp, - &pbe_param->keyLength, pbe_param->keyLen); - if (dummy == NULL) { - goto loser; - } - } - PORT_Memset(&pkcs5v2_param, 0, sizeof(pkcs5v2_param)); - dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param, - NSSPKCS5V2PBEParameterTemplate); - if (dummy == NULL) { - break; - } - dummy = NULL; - rv = SECOID_SetAlgorithmID(arena, &pkcs5v2_param.keyParams, - SEC_OID_PKCS5_PBKDF2, &der_param); - if (rv != SECSuccess) { - break; - } - der_param.data = pbe_param->ivData; - der_param.len = pbe_param->ivLen; - rv = SECOID_SetAlgorithmID(arena, &pkcs5v2_param.algParams, - pbe_param->encAlg, pbe_param->ivLen ? &der_param : NULL); - if (rv != SECSuccess) { - break; - } - dummy = SEC_ASN1EncodeItem(arena, &der_param, &pkcs5v2_param, - NSSPKCS5V2PBES2ParameterTemplate); - break; -#endif - default: - break; - } - - if (dummy == NULL) { - goto loser; - } - - rv = SECOID_SetAlgorithmID(arena, algid, algorithm, &der_param); - if (rv != SECSuccess) { - goto loser; - } - - ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID)); - if (ret_algid == NULL) { - goto loser; - } - - rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid); - if (rv != SECSuccess) { - SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE); - ret_algid = NULL; - } - -loser: - - return ret_algid; -} diff --git a/security/nss/lib/softoken/lowpbe.h b/security/nss/lib/softoken/lowpbe.h deleted file mode 100644 index 974b2fa4f..000000000 --- a/security/nss/lib/softoken/lowpbe.h +++ /dev/null @@ -1,140 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _SECPKCS5_H_ -#define _SECPKCS5_H_ - -#include "plarena.h" -#include "secitem.h" -#include "seccomon.h" -#include "secoidt.h" -#include "hasht.h" - -typedef SECItem * (* SEC_PKCS5GetPBEPassword)(void *arg); - -/* used for V2 PKCS 12 Draft Spec */ -typedef enum { - pbeBitGenIDNull = 0, - pbeBitGenCipherKey = 0x01, - pbeBitGenCipherIV = 0x02, - pbeBitGenIntegrityKey = 0x03 -} PBEBitGenID; - -typedef enum { - NSSPKCS5_PBKDF1 = 0, - NSSPKCS5_PBKDF2 = 1, - NSSPKCS5_PKCS12_V2 = 2 -} NSSPKCS5PBEType; - -typedef struct NSSPKCS5PBEParameterStr NSSPKCS5PBEParameter; - -struct NSSPKCS5PBEParameterStr { - PRArenaPool *poolp; - SECItem salt; /* octet string */ - SECItem iteration; /* integer */ - SECItem keyLength; /* integer */ - - /* used locally */ - int iter; - int keyLen; - int ivLen; - unsigned char *ivData; - HASH_HashType hashType; - NSSPKCS5PBEType pbeType; - SECAlgorithmID prfAlg; - PBEBitGenID keyID; - SECOidTag encAlg; - PRBool is2KeyDES; -}; - - -SEC_BEGIN_PROTOS -/* Create a PKCS5 Algorithm ID - * The algorithm ID is set up using the PKCS #5 parameter structure - * algorithm is the PBE algorithm ID for the desired algorithm - * pbe is a pbe param block with all the info needed to create the - * algorithm id. - * If an error occurs or the algorithm specified is not supported - * or is not a password based encryption algorithm, NULL is returned. - * Otherwise, a pointer to the algorithm id is returned. - */ -extern SECAlgorithmID * -nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm, - NSSPKCS5PBEParameter *pbe); - -/* - * Convert an Algorithm ID to a PBE Param. - * NOTE: this does not suppport PKCS 5 v2 because it's only used for the - * keyDB which only support PKCS 5 v1, PFX, and PKCS 12. - */ -NSSPKCS5PBEParameter * -nsspkcs5_AlgidToParam(SECAlgorithmID *algid); - -/* - * Convert an Algorithm ID to a PBE Param. - * NOTE: this does not suppport PKCS 5 v2 because it's only used for the - * keyDB which only support PKCS 5 v1, PFX, and PKCS 12. - */ -NSSPKCS5PBEParameter * -nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator); - - -/* Encrypt/Decrypt data using password based encryption. - * algid is the PBE algorithm identifier, - * pwitem is the password, - * src is the source for encryption/decryption, - * encrypt is PR_TRUE for encryption, PR_FALSE for decryption. - * The key and iv are generated based upon PKCS #5 then the src - * is either encrypted or decrypted. If an error occurs, NULL - * is returned, otherwise the ciphered contents is returned. - */ -extern SECItem * -nsspkcs5_CipherData(NSSPKCS5PBEParameter *, SECItem *pwitem, - SECItem *src, PRBool encrypt, PRBool *update); - -extern SECItem * -nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *, SECItem *pwitem, - SECItem *iv, PRBool faulty3DES); - -/* Destroys PBE parameter */ -extern void -nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *param); - -HASH_HashType HASH_FromHMACOid(SECOidTag oid); - -SEC_END_PROTOS - -#endif diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn deleted file mode 100644 index 1a47046f2..000000000 --- a/security/nss/lib/softoken/manifest.mn +++ /dev/null @@ -1,99 +0,0 @@ -# -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# 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 the Initial Developer are Copyright (C) 1994-2000 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** -CORE_DEPTH = ../../.. - -MODULE = nss -DIRS = legacydb - -REQUIRES = dbm - -LIBRARY_NAME = softokn -LIBRARY_VERSION = 3 -MAPFILE = $(OBJDIR)/softokn.def - -DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DSOFTOKEN_LIB_NAME=\"$(notdir $(SHARED_LIBRARY))\" -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\" - -ifdef MOZILLA_CLIENT -INCLUDES += -I$(DIST)/include/sqlite3 -endif - -EXPORTS = \ - secmodt.h \ - $(NULL) - -PRIVATE_EXPORTS = \ - lgglue.h \ - lowkeyi.h \ - lowkeyti.h \ - pk11pars.h \ - pkcs11ni.h \ - softoken.h \ - softoknt.h \ - softkver.h \ - sdb.h \ - sftkdbt.h \ - pk11init.h \ - $(NULL) - -CSRCS = \ - ecdecode.c \ - fipsaudt.c \ - fipstest.c \ - fipstokn.c \ - lgglue.c \ - lowkey.c \ - lowpbe.c \ - padbuf.c \ - pkcs11.c \ - pkcs11c.c \ - pkcs11u.c \ - rsawrapr.c \ - sdb.c \ - sftkdb.c \ - sftkmod.c \ - sftkpars.c \ - sftkpwd.c \ - softkver.c \ - tlsprf.c \ - $(NULL) - -ifdef SQLITE_UNSAFE_THREADS -DEFINES += -DSQLITE_UNSAFE_THREADS -endif - -# This part of the code, including all sub-dirs, can be optimized for size -export ALLOW_OPT_CODE_SIZE = 1 diff --git a/security/nss/lib/softoken/padbuf.c b/security/nss/lib/softoken/padbuf.c deleted file mode 100644 index 8c43fa287..000000000 --- a/security/nss/lib/softoken/padbuf.c +++ /dev/null @@ -1,81 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "blapit.h" -#include "secport.h" -#include "secerr.h" - -/* - * Prepare a buffer for any padded CBC encryption algorithm, growing to the - * appropriate boundary and filling with the appropriate padding. - * blockSize must be a power of 2. - * - * NOTE: If arena is non-NULL, we re-allocate from there, otherwise - * we assume (and use) XP memory (re)allocation. - */ -unsigned char * -CBC_PadBuffer(PRArenaPool *arena, unsigned char *inbuf, unsigned int inlen, - unsigned int *outlen, int blockSize) -{ - unsigned char *outbuf; - unsigned int des_len; - unsigned int i; - unsigned char des_pad_len; - - /* - * We need from 1 to blockSize bytes -- we *always* grow. - * The extra bytes contain the value of the length of the padding: - * if we have 2 bytes of padding, then the padding is "0x02, 0x02". - */ - des_len = (inlen + blockSize) & ~(blockSize - 1); - - if (arena != NULL) { - outbuf = (unsigned char*)PORT_ArenaGrow (arena, inbuf, inlen, des_len); - } else { - outbuf = (unsigned char*)PORT_Realloc (inbuf, des_len); - } - - if (outbuf == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); - return NULL; - } - - des_pad_len = des_len - inlen; - for (i = inlen; i < des_len; i++) - outbuf[i] = des_pad_len; - - *outlen = des_len; - return outbuf; -} diff --git a/security/nss/lib/softoken/pk11init.h b/security/nss/lib/softoken/pk11init.h deleted file mode 100644 index d91a0d37f..000000000 --- a/security/nss/lib/softoken/pk11init.h +++ /dev/null @@ -1,55 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * 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? */ -}; - -#endif /* _PK11_INIT_H_ 1 */ diff --git a/security/nss/lib/softoken/pk11pars.h b/security/nss/lib/softoken/pk11pars.h deleted file mode 100644 index 20e2c3cb6..000000000 --- a/security/nss/lib/softoken/pk11pars.h +++ /dev/null @@ -1,872 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following handles the loading, unloading and management of - * various PCKS #11 modules - */ - - -/* - * this header file contains routines for parsing PKCS #11 module spec - * strings. It contains 'C' code and should only be included in one module. - * Currently it is included in both softoken and the wrapper. - */ -#include <ctype.h> -#include "pkcs11.h" -#include "seccomon.h" -#include "prprf.h" -#include "secmodt.h" -#include "pk11init.h" - -#define SECMOD_ARG_LIBRARY_PARAMETER "library=" -#define SECMOD_ARG_NAME_PARAMETER "name=" -#define SECMOD_ARG_MODULE_PARAMETER "parameters=" -#define SECMOD_ARG_NSS_PARAMETER "NSS=" -#define SECMOD_ARG_FORTEZZA_FLAG "FORTEZZA" -#define SECMOD_ARG_ESCAPE '\\' - -struct secmodargSlotFlagTable { - char *name; - int len; - unsigned long value; -}; - -#define SECMOD_DEFAULT_CIPHER_ORDER 0 -#define SECMOD_DEFAULT_TRUST_ORDER 50 - - -#define SECMOD_ARG_ENTRY(arg,flag) \ -{ #arg , sizeof(#arg)-1, flag } -static struct secmodargSlotFlagTable secmod_argSlotFlagTable[] = { - SECMOD_ARG_ENTRY(RSA,SECMOD_RSA_FLAG), - SECMOD_ARG_ENTRY(DSA,SECMOD_RSA_FLAG), - SECMOD_ARG_ENTRY(RC2,SECMOD_RC4_FLAG), - SECMOD_ARG_ENTRY(RC4,SECMOD_RC2_FLAG), - SECMOD_ARG_ENTRY(DES,SECMOD_DES_FLAG), - SECMOD_ARG_ENTRY(DH,SECMOD_DH_FLAG), - SECMOD_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG), - SECMOD_ARG_ENTRY(RC5,SECMOD_RC5_FLAG), - SECMOD_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG), - SECMOD_ARG_ENTRY(MD5,SECMOD_MD5_FLAG), - SECMOD_ARG_ENTRY(MD2,SECMOD_MD2_FLAG), - SECMOD_ARG_ENTRY(SSL,SECMOD_SSL_FLAG), - SECMOD_ARG_ENTRY(TLS,SECMOD_TLS_FLAG), - SECMOD_ARG_ENTRY(AES,SECMOD_AES_FLAG), - SECMOD_ARG_ENTRY(Camellia,SECMOD_CAMELLIA_FLAG), - SECMOD_ARG_ENTRY(SEED,SECMOD_SEED_FLAG), - SECMOD_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG), - SECMOD_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG), -}; - -#define SECMOD_HANDLE_STRING_ARG(param,target,value,command) \ - if (PORT_Strncasecmp(param,value,sizeof(value)-1) == 0) { \ - param += sizeof(value)-1; \ - if (target) PORT_Free(target); \ - target = secmod_argFetchValue(param,&next); \ - param += next; \ - command ;\ - } else - -#define SECMOD_HANDLE_FINAL_ARG(param) \ - { param = secmod_argSkipParameter(param); } param = secmod_argStrip(param); - - -static int secmod_argSlotFlagTableSize = - sizeof(secmod_argSlotFlagTable)/sizeof(secmod_argSlotFlagTable[0]); - - -static PRBool secmod_argGetPair(char c) { - switch (c) { - case '\'': return c; - case '\"': return c; - case '<': return '>'; - case '{': return '}'; - case '[': return ']'; - case '(': return ')'; - default: break; - } - return ' '; -} - -static PRBool secmod_argIsBlank(char c) { - return isspace(c); -} - -static PRBool secmod_argIsEscape(char c) { - return c == '\\'; -} - -static PRBool secmod_argIsQuote(char c) { - switch (c) { - case '\'': - case '\"': - case '<': - case '{': /* } end curly to keep vi bracket matching working */ - case '(': /* ) */ - case '[': /* ] */ return PR_TRUE; - default: break; - } - return PR_FALSE; -} - -static PRBool secmod_argHasChar(char *v, char c) -{ - for ( ;*v; v++) { - if (*v == c) return PR_TRUE; - } - return PR_FALSE; -} - -static PRBool secmod_argHasBlanks(char *v) -{ - for ( ;*v; v++) { - if (secmod_argIsBlank(*v)) return PR_TRUE; - } - return PR_FALSE; -} - -static char *secmod_argStrip(char *c) { - while (*c && secmod_argIsBlank(*c)) c++; - return c; -} - -static char * -secmod_argFindEnd(char *string) { - char endChar = ' '; - PRBool lastEscape = PR_FALSE; - - if (secmod_argIsQuote(*string)) { - endChar = secmod_argGetPair(*string); - string++; - } - - for (;*string; string++) { - if (lastEscape) { - lastEscape = PR_FALSE; - continue; - } - if (secmod_argIsEscape(*string) && !lastEscape) { - lastEscape = PR_TRUE; - continue; - } - if ((endChar == ' ') && secmod_argIsBlank(*string)) break; - if (*string == endChar) { - break; - } - } - - return string; -} - -static char * -secmod_argFetchValue(char *string, int *pcount) -{ - char *end = secmod_argFindEnd(string); - char *retString, *copyString; - PRBool lastEscape = PR_FALSE; - int len; - - len = end - string; - if (len == 0) { - *pcount = 0; - return NULL; - } - - copyString = retString = (char *)PORT_Alloc(len+1); - - if (*end) len++; - *pcount = len; - if (retString == NULL) return NULL; - - - if (secmod_argIsQuote(*string)) string++; - for (; string < end; string++) { - if (secmod_argIsEscape(*string) && !lastEscape) { - lastEscape = PR_TRUE; - continue; - } - lastEscape = PR_FALSE; - *copyString++ = *string; - } - *copyString = 0; - return retString; -} - -static char * -secmod_argSkipParameter(char *string) -{ - char *end; - /* look for the end of the <name>= */ - for (;*string; string++) { - if (*string == '=') { string++; break; } - if (secmod_argIsBlank(*string)) return(string); - } - - end = secmod_argFindEnd(string); - if (*end) end++; - return end; -} - - -static SECStatus -secmod_argParseModuleSpec(char *modulespec, char **lib, char **mod, - char **parameters, char **nss) -{ - int next; - modulespec = secmod_argStrip(modulespec); - - *lib = *mod = *parameters = *nss = 0; - - while (*modulespec) { - SECMOD_HANDLE_STRING_ARG(modulespec,*lib,SECMOD_ARG_LIBRARY_PARAMETER,;) - SECMOD_HANDLE_STRING_ARG(modulespec,*mod,SECMOD_ARG_NAME_PARAMETER,;) - SECMOD_HANDLE_STRING_ARG(modulespec,*parameters, - SECMOD_ARG_MODULE_PARAMETER,;) - SECMOD_HANDLE_STRING_ARG(modulespec,*nss,SECMOD_ARG_NSS_PARAMETER,;) - SECMOD_HANDLE_FINAL_ARG(modulespec) - } - return SECSuccess; -} - - -static char * -secmod_argGetParamValue(char *paramName,char *parameters) -{ - char searchValue[256]; - int paramLen = strlen(paramName); - char *returnValue = NULL; - int next; - - if ((parameters == NULL) || (*parameters == 0)) return NULL; - - PORT_Assert(paramLen+2 < sizeof(searchValue)); - - PORT_Strcpy(searchValue,paramName); - PORT_Strcat(searchValue,"="); - while (*parameters) { - if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) { - parameters += paramLen+1; - returnValue = secmod_argFetchValue(parameters,&next); - break; - } else { - parameters = secmod_argSkipParameter(parameters); - } - parameters = secmod_argStrip(parameters); - } - return returnValue; -} - - -static char * -secmod_argNextFlag(char *flags) -{ - for (; *flags ; flags++) { - if (*flags == ',') { - flags++; - break; - } - } - return flags; -} - -static PRBool -secmod_argHasFlag(char *label, char *flag, char *parameters) -{ - char *flags,*index; - int len = strlen(flag); - PRBool found = PR_FALSE; - - flags = secmod_argGetParamValue(label,parameters); - if (flags == NULL) return PR_FALSE; - - for (index=flags; *index; index=secmod_argNextFlag(index)) { - if (PORT_Strncasecmp(index,flag,len) == 0) { - found=PR_TRUE; - break; - } - } - PORT_Free(flags); - return found; -} - -static void -secmod_argSetNewCipherFlags(unsigned long *newCiphers,char *cipherList) -{ - newCiphers[0] = newCiphers[1] = 0; - if ((cipherList == NULL) || (*cipherList == 0)) return; - - for (;*cipherList; cipherList=secmod_argNextFlag(cipherList)) { - if (PORT_Strncasecmp(cipherList,SECMOD_ARG_FORTEZZA_FLAG, - sizeof(SECMOD_ARG_FORTEZZA_FLAG)-1) == 0) { - newCiphers[0] |= SECMOD_FORTEZZA_FLAG; - } - - /* add additional flags here as necessary */ - /* direct bit mapping escape */ - if (*cipherList == 0) { - if (cipherList[1] == 'l') { - newCiphers[1] |= atoi(&cipherList[2]); - } else { - newCiphers[0] |= atoi(&cipherList[2]); - } - } - } -} - - -/* - * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal - */ -static long -secmod_argDecodeNumber(char *num) -{ - int radix = 10; - unsigned long value = 0; - long retValue = 0; - int sign = 1; - int digit; - - if (num == NULL) return retValue; - - num = secmod_argStrip(num); - - if (*num == '-') { - sign = -1; - num++; - } - - if (*num == '0') { - radix = 8; - num++; - if ((*num == 'x') || (*num == 'X')) { - radix = 16; - num++; - } - } - - - for ( ;*num; num++ ) { - if (isdigit(*num)) { - digit = *num - '0'; - } else if ((*num >= 'a') && (*num <= 'f')) { - digit = *num - 'a' + 10; - } else if ((*num >= 'A') && (*num <= 'F')) { - digit = *num - 'A' + 10; - } else { - break; - } - if (digit >= radix) break; - value = value*radix + digit; - } - - retValue = ((int) value) * sign; - return retValue; -} - -static long -secmod_argReadLong(char *label,char *params, long defValue, PRBool *isdefault) -{ - char *value; - long retValue; - if (isdefault) *isdefault = PR_FALSE; - - value = secmod_argGetParamValue(label,params); - if (value == NULL) { - if (isdefault) *isdefault = PR_TRUE; - return defValue; - } - retValue = secmod_argDecodeNumber(value); - if (value) PORT_Free(value); - - return retValue; -} - - -static unsigned long -secmod_argSlotFlags(char *label,char *params) -{ - char *flags,*index; - unsigned long retValue = 0; - int i; - PRBool all = PR_FALSE; - - flags = secmod_argGetParamValue(label,params); - if (flags == NULL) return 0; - - if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE; - - for (index=flags; *index; index=secmod_argNextFlag(index)) { - for (i=0; i < secmod_argSlotFlagTableSize; i++) { - if (all || (PORT_Strncasecmp(index, secmod_argSlotFlagTable[i].name, - secmod_argSlotFlagTable[i].len) == 0)) { - retValue |= secmod_argSlotFlagTable[i].value; - } - } - } - PORT_Free(flags); - return retValue; -} - - -static void -secmod_argDecodeSingleSlotInfo(char *name, char *params, - PK11PreSlotInfo *slotInfo) -{ - char *askpw; - - slotInfo->slotID=secmod_argDecodeNumber(name); - slotInfo->defaultFlags=secmod_argSlotFlags("slotFlags",params); - slotInfo->timeout=secmod_argReadLong("timeout",params, 0, NULL); - - askpw = secmod_argGetParamValue("askpw",params); - slotInfo->askpw = 0; - - if (askpw) { - if (PORT_Strcasecmp(askpw,"every") == 0) { - slotInfo->askpw = -1; - } else if (PORT_Strcasecmp(askpw,"timeout") == 0) { - slotInfo->askpw = 1; - } - PORT_Free(askpw); - slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS; - } - slotInfo->hasRootCerts = secmod_argHasFlag("rootFlags", "hasRootCerts", - params); - slotInfo->hasRootTrust = secmod_argHasFlag("rootFlags", "hasRootTrust", - params); -} - -static char * -secmod_argGetName(char *inString, int *next) -{ - char *name=NULL; - char *string; - int len; - - /* look for the end of the <name>= */ - for (string = inString;*string; string++) { - if (*string == '=') { break; } - if (secmod_argIsBlank(*string)) break; - } - - len = string - inString; - - *next = len; - if (*string == '=') (*next) += 1; - if (len > 0) { - name = PORT_Alloc(len+1); - PORT_Strncpy(name,inString,len); - name[len] = 0; - } - return name; -} - -static PK11PreSlotInfo * -secmod_argParseSlotInfo(PRArenaPool *arena, char *slotParams, int *retCount) -{ - char *slotIndex; - PK11PreSlotInfo *slotInfo = NULL; - int i=0,count = 0,next; - - *retCount = 0; - if ((slotParams == NULL) || (*slotParams == 0)) return NULL; - - /* first count the number of slots */ - for (slotIndex = secmod_argStrip(slotParams); *slotIndex; - slotIndex = secmod_argStrip(secmod_argSkipParameter(slotIndex))) { - count++; - } - - /* get the data structures */ - if (arena) { - slotInfo = (PK11PreSlotInfo *) - PORT_ArenaAlloc(arena,count*sizeof(PK11PreSlotInfo)); - PORT_Memset(slotInfo,0,count*sizeof(PK11PreSlotInfo)); - } else { - slotInfo = (PK11PreSlotInfo *) - PORT_ZAlloc(count*sizeof(PK11PreSlotInfo)); - } - if (slotInfo == NULL) return NULL; - - for (slotIndex = secmod_argStrip(slotParams), i = 0; - *slotIndex && i < count ; ) { - char *name; - name = secmod_argGetName(slotIndex,&next); - slotIndex += next; - - if (!secmod_argIsBlank(*slotIndex)) { - char *args = secmod_argFetchValue(slotIndex,&next); - slotIndex += next; - if (args) { - secmod_argDecodeSingleSlotInfo(name,args,&slotInfo[i]); - i++; - PORT_Free(args); - } - } - if (name) PORT_Free(name); - slotIndex = secmod_argStrip(slotIndex); - } - *retCount = i; - return slotInfo; -} - -static char *secmod_nullString = ""; - -static char * -secmod_formatValue(PRArenaPool *arena, char *value, char quote) -{ - char *vp,*vp2,*retval; - int size = 0, escapes = 0; - - for (vp=value; *vp ;vp++) { - if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) escapes++; - size++; - } - if (arena) { - retval = PORT_ArenaZAlloc(arena,size+escapes+1); - } else { - retval = PORT_ZAlloc(size+escapes+1); - } - if (retval == NULL) return NULL; - vp2 = retval; - for (vp=value; *vp; vp++) { - if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) - *vp2++ = SECMOD_ARG_ESCAPE; - *vp2++ = *vp; - } - return retval; -} - -static char *secmod_formatPair(char *name,char *value, char quote) -{ - char openQuote = quote; - char closeQuote = secmod_argGetPair(quote); - char *newValue = NULL; - char *returnValue; - PRBool need_quote = PR_FALSE; - - if (!value || (*value == 0)) return secmod_nullString; - - if (secmod_argHasBlanks(value) || secmod_argIsQuote(value[0])) - need_quote=PR_TRUE; - - if ((need_quote && secmod_argHasChar(value,closeQuote)) - || secmod_argHasChar(value,SECMOD_ARG_ESCAPE)) { - value = newValue = secmod_formatValue(NULL, value,quote); - if (newValue == NULL) return secmod_nullString; - } - if (need_quote) { - returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote); - } else { - returnValue = PR_smprintf("%s=%s",name,value); - } - if (returnValue == NULL) returnValue = secmod_nullString; - - if (newValue) PORT_Free(newValue); - - return returnValue; -} - -static char *secmod_formatIntPair(char *name, unsigned long value, - unsigned long def) -{ - char *returnValue; - - if (value == def) return secmod_nullString; - - returnValue = PR_smprintf("%s=%d",name,value); - - return returnValue; -} - -static void -secmod_freePair(char *pair) -{ - if (pair && pair != secmod_nullString) { - PR_smprintf_free(pair); - } -} - -#define MAX_FLAG_SIZE sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\ - sizeof("moduleDBOnly")+sizeof("critical") -static char * -secmod_mkNSSFlags(PRBool internal, PRBool isFIPS, - PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical) -{ - char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE); - PRBool first = PR_TRUE; - - PORT_Memset(flags,0,MAX_FLAG_SIZE); - if (internal) { - PORT_Strcat(flags,"internal"); - first = PR_FALSE; - } - if (isFIPS) { - if (!first) PORT_Strcat(flags,","); - PORT_Strcat(flags,"FIPS"); - first = PR_FALSE; - } - if (isModuleDB) { - if (!first) PORT_Strcat(flags,","); - PORT_Strcat(flags,"moduleDB"); - first = PR_FALSE; - } - if (isModuleDBOnly) { - if (!first) PORT_Strcat(flags,","); - PORT_Strcat(flags,"moduleDBOnly"); - first = PR_FALSE; - } - if (isCritical) { - if (!first) PORT_Strcat(flags,","); - PORT_Strcat(flags,"critical"); - first = PR_FALSE; - } - return flags; -} - -static char * -secmod_mkCipherFlags(unsigned long ssl0, unsigned long ssl1) -{ - char *cipher = NULL; - int i; - - for (i=0; i < sizeof(ssl0)*8; i++) { - if (ssl0 & (1<<i)) { - char *string; - if ((1<<i) == SECMOD_FORTEZZA_FLAG) { - string = PR_smprintf("%s","FORTEZZA"); - } else { - string = PR_smprintf("0h0x%08x",1<<i); - } - if (cipher) { - char *tmp; - tmp = PR_smprintf("%s,%s",cipher,string); - PR_smprintf_free(cipher); - PR_smprintf_free(string); - cipher = tmp; - } else { - cipher = string; - } - } - } - for (i=0; i < sizeof(ssl0)*8; i++) { - if (ssl1 & (1<<i)) { - if (cipher) { - char *tmp; - tmp = PR_smprintf("%s,0l0x%08x",cipher,1<<i); - PR_smprintf_free(cipher); - cipher = tmp; - } else { - cipher = PR_smprintf("0l0x%08x",1<<i); - } - } - } - - return cipher; -} - -static char * -secmod_mkSlotFlags(unsigned long defaultFlags) -{ - char *flags=NULL; - int i,j; - - for (i=0; i < sizeof(defaultFlags)*8; i++) { - if (defaultFlags & (1<<i)) { - char *string = NULL; - - for (j=0; j < secmod_argSlotFlagTableSize; j++) { - if (secmod_argSlotFlagTable[j].value == ( 1UL << i )) { - string = secmod_argSlotFlagTable[j].name; - break; - } - } - if (string) { - if (flags) { - char *tmp; - tmp = PR_smprintf("%s,%s",flags,string); - PR_smprintf_free(flags); - flags = tmp; - } else { - flags = PR_smprintf("%s",string); - } - } - } - } - - return flags; -} - -#define SECMOD_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts")+sizeof("hasRootTrust") - -static char * -secmod_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust) -{ - char *flags= (char *)PORT_ZAlloc(SECMOD_MAX_ROOT_FLAG_SIZE); - PRBool first = PR_TRUE; - - PORT_Memset(flags,0,SECMOD_MAX_ROOT_FLAG_SIZE); - if (hasRootCerts) { - PORT_Strcat(flags,"hasRootCerts"); - first = PR_FALSE; - } - if (hasRootTrust) { - if (!first) PORT_Strcat(flags,","); - PORT_Strcat(flags,"hasRootTrust"); - first = PR_FALSE; - } - return flags; -} - -static char * -secmod_mkSlotString(unsigned long slotID, unsigned long defaultFlags, - unsigned long timeout, unsigned char askpw_in, - PRBool hasRootCerts, PRBool hasRootTrust) { - char *askpw,*flags,*rootFlags,*slotString; - char *flagPair,*rootFlagsPair; - - switch (askpw_in) { - case 0xff: - askpw = "every"; - break; - case 1: - askpw = "timeout"; - break; - default: - askpw = "any"; - break; - } - flags = secmod_mkSlotFlags(defaultFlags); - rootFlags = secmod_mkRootFlags(hasRootCerts,hasRootTrust); - flagPair=secmod_formatPair("slotFlags",flags,'\''); - rootFlagsPair=secmod_formatPair("rootFlags",rootFlags,'\''); - if (flags) PR_smprintf_free(flags); - if (rootFlags) PORT_Free(rootFlags); - if (defaultFlags & PK11_OWN_PW_DEFAULTS) { - slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]", - (PRUint32)slotID,flagPair,askpw,timeout, - rootFlagsPair); - } else { - slotString = PR_smprintf("0x%08lx=[%s %s]", - (PRUint32)slotID,flagPair,rootFlagsPair); - } - secmod_freePair(flagPair); - secmod_freePair(rootFlagsPair); - return slotString; -} - -static char * -secmod_mkNSS(char **slotStrings, int slotCount, PRBool internal, PRBool isFIPS, - PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical, - unsigned long trustOrder, unsigned long cipherOrder, - unsigned long ssl0, unsigned long ssl1) { - int slotLen, i; - char *slotParams, *ciphers, *nss, *nssFlags, *tmp; - char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair; - - - /* now let's build up the string - * first the slot infos - */ - slotLen=0; - for (i=0; i < (int)slotCount; i++) { - slotLen += PORT_Strlen(slotStrings[i])+1; - } - slotLen += 1; /* space for the final NULL */ - - slotParams = (char *)PORT_ZAlloc(slotLen); - PORT_Memset(slotParams,0,slotLen); - for (i=0; i < (int)slotCount; i++) { - PORT_Strcat(slotParams,slotStrings[i]); - PORT_Strcat(slotParams," "); - PR_smprintf_free(slotStrings[i]); - slotStrings[i]=NULL; - } - - /* - * now the NSS structure - */ - nssFlags = secmod_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly, - isCritical); - /* for now only the internal module is critical */ - ciphers = secmod_mkCipherFlags(ssl0, ssl1); - - trustOrderPair=secmod_formatIntPair("trustOrder",trustOrder, - SECMOD_DEFAULT_TRUST_ORDER); - cipherOrderPair=secmod_formatIntPair("cipherOrder",cipherOrder, - SECMOD_DEFAULT_CIPHER_ORDER); - slotPair=secmod_formatPair("slotParams",slotParams,'{'); /* } */ - if (slotParams) PORT_Free(slotParams); - cipherPair=secmod_formatPair("ciphers",ciphers,'\''); - if (ciphers) PR_smprintf_free(ciphers); - flagPair=secmod_formatPair("Flags",nssFlags,'\''); - if (nssFlags) PORT_Free(nssFlags); - nss = PR_smprintf("%s %s %s %s %s",trustOrderPair, - cipherOrderPair,slotPair,cipherPair,flagPair); - secmod_freePair(trustOrderPair); - secmod_freePair(cipherOrderPair); - secmod_freePair(slotPair); - secmod_freePair(cipherPair); - secmod_freePair(flagPair); - tmp = secmod_argStrip(nss); - if (*tmp == '\0') { - PR_smprintf_free(nss); - nss = NULL; - } - return nss; -} - -static char * -secmod_mkNewModuleSpec(char *dllName, char *commonName, char *parameters, - char *NSS) { - char *moduleSpec; - char *lib,*name,*param,*nss; - - /* - * now the final spec - */ - lib = secmod_formatPair("library",dllName,'\"'); - name = secmod_formatPair("name",commonName,'\"'); - param = secmod_formatPair("parameters",parameters,'\"'); - nss = secmod_formatPair("NSS",NSS,'\"'); - moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss); - secmod_freePair(lib); - secmod_freePair(name); - secmod_freePair(param); - secmod_freePair(nss); - return (moduleSpec); -} - diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c deleted file mode 100644 index c5c2a8e2b..000000000 --- a/security/nss/lib/softoken/pkcs11.c +++ /dev/null @@ -1,4420 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Stephen Henson <stephen.henson@gemplus.com> - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * This file implements PKCS 11 on top of our existing security modules - * - * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. - * This implementation has two slots: - * slot 1 is our generic crypto support. It does not require login. - * It supports Public Key ops, and all they bulk ciphers and hashes. - * It can also support Private Key ops for imported Private keys. It does - * not have any token storage. - * slot 2 is our private key support. It requires a login before use. It - * can store Private Keys and Certs as token objects. Currently only private - * keys and their associated Certificates are saved on the token. - * - * In this implementation, session objects are only visible to the session - * that created or generated them. - */ -#include "seccomon.h" -#include "secitem.h" -#include "pkcs11.h" -#include "pkcs11i.h" -#include "softoken.h" -#include "lowkeyi.h" -#include "blapi.h" -#include "secder.h" -#include "secport.h" -#include "secrng.h" -#include "prtypes.h" -#include "nspr.h" -#include "softkver.h" -#include "secoid.h" -#include "sftkdb.h" -#include "sftkpars.h" -#include "ec.h" -#include "secasn1.h" - -PRBool parentForkedAfterC_Initialize; - -#ifndef NO_FORK_CHECK - -PRBool sftkForkCheckDisabled; - -#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED) -PRBool forked = PR_FALSE; -#endif - -#if defined(CHECK_FORK_GETPID) || defined(CHECK_FORK_MIXED) -#include <unistd.h> -pid_t myPid; -#endif - -#ifdef CHECK_FORK_MIXED -#include <sys/systeminfo.h> -PRBool usePthread_atfork; -#endif - -#endif - -/* - * ******************** Static data ******************************* - */ - -/* The next three strings must be exactly 32 characters long */ -static char *manufacturerID = "Mozilla Foundation "; -static char manufacturerID_space[33]; -static char *libraryDescription = "NSS Internal Crypto Services "; -static char libraryDescription_space[33]; - -/* - * In FIPS mode, we disallow login attempts for 1 second after a login - * failure so that there are at most 60 login attempts per minute. - */ -static PRIntervalTime loginWaitTime; -static PRUint32 minSessionObjectHandle = 1U; - -#define __PASTE(x,y) x##y - -/* - * we renamed all our internal functions, get the correct - * definitions for them... - */ -#undef CK_PKCS11_FUNCTION_INFO -#undef CK_NEED_ARG_LIST - -#define CK_EXTERN extern -#define CK_PKCS11_FUNCTION_INFO(func) \ - CK_RV __PASTE(NS,func) -#define CK_NEED_ARG_LIST 1 - -#include "pkcs11f.h" - - - -/* build the crypto module table */ -static const CK_FUNCTION_LIST sftk_funcList = { - { 1, 10 }, - -#undef CK_PKCS11_FUNCTION_INFO -#undef CK_NEED_ARG_LIST - -#define CK_PKCS11_FUNCTION_INFO(func) \ - __PASTE(NS,func), -#include "pkcs11f.h" - -}; - -#undef CK_PKCS11_FUNCTION_INFO -#undef CK_NEED_ARG_LIST - - -#undef __PASTE - -/* List of DES Weak Keys */ -typedef unsigned char desKey[8]; -static const desKey sftk_desWeakTable[] = { -#ifdef noParity - /* weak */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, - { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, - { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }, - /* semi-weak */ - { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, - { 0xfe, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0xfe }, - - { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, - { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, - - { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x0f, 0x00, 0x0f }, - { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, - - { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, - { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, - - { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, - { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, - - { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, - { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, -#else - /* weak */ - { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, - { 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e }, - { 0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1 }, - { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }, - - /* semi-weak */ - { 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe }, - { 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01 }, - - { 0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1 }, - { 0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e }, - - { 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1 }, - { 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01 }, - - { 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, - { 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e }, - - { 0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e }, - { 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01 }, - - { 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe }, - { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1 } -#endif -}; - - -static const int sftk_desWeakTableSize = sizeof(sftk_desWeakTable)/ - sizeof(sftk_desWeakTable[0]); - -/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns - * that byte with the proper parity bit set */ -static const unsigned char parityTable[256] = { -/* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */ -/* E */ 0x01,0x02,0x04,0x07,0x08,0x0b,0x0d,0x0e, -/* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */ -/* O */ 0x10,0x13,0x15,0x16,0x19,0x1a,0x1c,0x1f, -/* Odd....0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e */ -/* O */ 0x20,0x23,0x25,0x26,0x29,0x2a,0x2c,0x2f, -/* Even...0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e */ -/* E */ 0x31,0x32,0x34,0x37,0x38,0x3b,0x3d,0x3e, -/* Odd....0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e */ -/* O */ 0x40,0x43,0x45,0x46,0x49,0x4a,0x4c,0x4f, -/* Even...0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e */ -/* E */ 0x51,0x52,0x54,0x57,0x58,0x5b,0x5d,0x5e, -/* Even...0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e */ -/* E */ 0x61,0x62,0x64,0x67,0x68,0x6b,0x6d,0x6e, -/* Odd....0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e */ -/* O */ 0x70,0x73,0x75,0x76,0x79,0x7a,0x7c,0x7f, -/* Odd....0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e */ -/* O */ 0x80,0x83,0x85,0x86,0x89,0x8a,0x8c,0x8f, -/* Even...0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e */ -/* E */ 0x91,0x92,0x94,0x97,0x98,0x9b,0x9d,0x9e, -/* Even...0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae */ -/* E */ 0xa1,0xa2,0xa4,0xa7,0xa8,0xab,0xad,0xae, -/* Odd....0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe */ -/* O */ 0xb0,0xb3,0xb5,0xb6,0xb9,0xba,0xbc,0xbf, -/* Even...0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce */ -/* E */ 0xc1,0xc2,0xc4,0xc7,0xc8,0xcb,0xcd,0xce, -/* Odd....0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde */ -/* O */ 0xd0,0xd3,0xd5,0xd6,0xd9,0xda,0xdc,0xdf, -/* Odd....0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee */ -/* O */ 0xe0,0xe3,0xe5,0xe6,0xe9,0xea,0xec,0xef, -/* Even...0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe */ -/* E */ 0xf1,0xf2,0xf4,0xf7,0xf8,0xfb,0xfd,0xfe, -}; - -/* Mechanisms */ -struct mechanismList { - CK_MECHANISM_TYPE type; - CK_MECHANISM_INFO info; - PRBool privkey; -}; - -/* - * the following table includes a complete list of mechanism defined by - * PKCS #11 version 2.01. Those Mechanisms not supported by this PKCS #11 - * module are ifdef'ed out. - */ -#define CKF_EN_DE CKF_ENCRYPT | CKF_DECRYPT -#define CKF_WR_UN CKF_WRAP | CKF_UNWRAP -#define CKF_SN_VR CKF_SIGN | CKF_VERIFY -#define CKF_SN_RE CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER - -#define CKF_EN_DE_WR_UN CKF_EN_DE | CKF_WR_UN -#define CKF_SN_VR_RE CKF_SN_VR | CKF_SN_RE -#define CKF_DUZ_IT_ALL CKF_EN_DE_WR_UN | CKF_SN_VR_RE - -#define CKF_EC_PNU CKF_EC_FP | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS - -#define CKF_EC_BPNU CKF_EC_F_2M | CKF_EC_PNU - -#define CK_MAX 0xffffffff - -static const struct mechanismList mechanisms[] = { - - /* - * PKCS #11 Mechanism List. - * - * The first argument is the PKCS #11 Mechanism we support. - * The second argument is Mechanism info structure. It includes: - * The minimum key size, - * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs. - * in bytes for RC5, AES, Camellia, and CAST* - * ignored for DES*, IDEA and FORTEZZA based - * The maximum key size, - * in bits for RSA, DSA, DH, EC*, KEA, RC2 and RC4 * algs. - * in bytes for RC5, AES, Camellia, and CAST* - * ignored for DES*, IDEA and FORTEZZA based - * Flags - * What operations are supported by this mechanism. - * The third argument is a bool which tells if this mechanism is - * supported in the database token. - * - */ - - /* ------------------------- RSA Operations ---------------------------*/ - {CKM_RSA_PKCS_KEY_PAIR_GEN,{RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_GENERATE_KEY_PAIR},PR_TRUE}, - {CKM_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_DUZ_IT_ALL}, PR_TRUE}, -#ifdef SFTK_RSA9796_SUPPORTED - {CKM_RSA_9796, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_DUZ_IT_ALL}, PR_TRUE}, -#endif - {CKM_RSA_X_509, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_DUZ_IT_ALL}, PR_TRUE}, - /* -------------- RSA Multipart Signing Operations -------------------- */ - {CKM_MD2_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_SN_VR}, PR_TRUE}, - {CKM_MD5_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_SN_VR}, PR_TRUE}, - {CKM_SHA1_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_SN_VR}, PR_TRUE}, - {CKM_SHA256_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_SN_VR}, PR_TRUE}, - {CKM_SHA384_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_SN_VR}, PR_TRUE}, - {CKM_SHA512_RSA_PKCS, {RSA_MIN_MODULUS_BITS,CK_MAX, - CKF_SN_VR}, PR_TRUE}, - /* ------------------------- DSA Operations --------------------------- */ - {CKM_DSA_KEY_PAIR_GEN, {DSA_MIN_P_BITS, DSA_MAX_P_BITS, - CKF_GENERATE_KEY_PAIR}, PR_TRUE}, - {CKM_DSA, {DSA_MIN_P_BITS, DSA_MAX_P_BITS, - CKF_SN_VR}, PR_TRUE}, - {CKM_DSA_SHA1, {DSA_MIN_P_BITS, DSA_MAX_P_BITS, - CKF_SN_VR}, PR_TRUE}, - /* -------------------- Diffie Hellman Operations --------------------- */ - /* no diffie hellman yet */ - {CKM_DH_PKCS_KEY_PAIR_GEN, {DH_MIN_P_BITS, DH_MAX_P_BITS, - CKF_GENERATE_KEY_PAIR}, PR_TRUE}, - {CKM_DH_PKCS_DERIVE, {DH_MIN_P_BITS, DH_MAX_P_BITS, - CKF_DERIVE}, PR_TRUE}, -#ifdef NSS_ENABLE_ECC - /* -------------------- Elliptic Curve Operations --------------------- */ - {CKM_EC_KEY_PAIR_GEN, {112, 571, CKF_GENERATE_KEY_PAIR|CKF_EC_BPNU}, PR_TRUE}, - {CKM_ECDH1_DERIVE, {112, 571, CKF_DERIVE|CKF_EC_BPNU}, PR_TRUE}, - {CKM_ECDSA, {112, 571, CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE}, - {CKM_ECDSA_SHA1, {112, 571, CKF_SN_VR|CKF_EC_BPNU}, PR_TRUE}, -#endif /* NSS_ENABLE_ECC */ - /* ------------------------- RC2 Operations --------------------------- */ - {CKM_RC2_KEY_GEN, {1, 128, CKF_GENERATE}, PR_TRUE}, - {CKM_RC2_ECB, {1, 128, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_RC2_CBC, {1, 128, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_RC2_MAC, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_RC2_MAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_RC2_CBC_PAD, {1, 128, CKF_EN_DE_WR_UN}, PR_TRUE}, - /* ------------------------- RC4 Operations --------------------------- */ - {CKM_RC4_KEY_GEN, {1, 256, CKF_GENERATE}, PR_FALSE}, - {CKM_RC4, {1, 256, CKF_EN_DE_WR_UN}, PR_FALSE}, - /* ------------------------- DES Operations --------------------------- */ - {CKM_DES_KEY_GEN, { 8, 8, CKF_GENERATE}, PR_TRUE}, - {CKM_DES_ECB, { 8, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_DES_CBC, { 8, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_DES_MAC, { 8, 8, CKF_SN_VR}, PR_TRUE}, - {CKM_DES_MAC_GENERAL, { 8, 8, CKF_SN_VR}, PR_TRUE}, - {CKM_DES_CBC_PAD, { 8, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_DES2_KEY_GEN, {24, 24, CKF_GENERATE}, PR_TRUE}, - {CKM_DES3_KEY_GEN, {24, 24, CKF_GENERATE}, PR_TRUE }, - {CKM_DES3_ECB, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE }, - {CKM_DES3_CBC, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE }, - {CKM_DES3_MAC, {24, 24, CKF_SN_VR}, PR_TRUE }, - {CKM_DES3_MAC_GENERAL, {24, 24, CKF_SN_VR}, PR_TRUE }, - {CKM_DES3_CBC_PAD, {24, 24, CKF_EN_DE_WR_UN}, PR_TRUE }, - /* ------------------------- CDMF Operations --------------------------- */ - {CKM_CDMF_KEY_GEN, {8, 8, CKF_GENERATE}, PR_TRUE}, - {CKM_CDMF_ECB, {8, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CDMF_CBC, {8, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CDMF_MAC, {8, 8, CKF_SN_VR}, PR_TRUE}, - {CKM_CDMF_MAC_GENERAL, {8, 8, CKF_SN_VR}, PR_TRUE}, - {CKM_CDMF_CBC_PAD, {8, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - /* ------------------------- AES Operations --------------------------- */ - {CKM_AES_KEY_GEN, {16, 32, CKF_GENERATE}, PR_TRUE}, - {CKM_AES_ECB, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_AES_CBC, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_AES_MAC, {16, 32, CKF_SN_VR}, PR_TRUE}, - {CKM_AES_MAC_GENERAL, {16, 32, CKF_SN_VR}, PR_TRUE}, - {CKM_AES_CBC_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - /* ------------------------- Camellia Operations --------------------- */ - {CKM_CAMELLIA_KEY_GEN, {16, 32, CKF_GENERATE}, PR_TRUE}, - {CKM_CAMELLIA_ECB, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAMELLIA_CBC, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAMELLIA_MAC, {16, 32, CKF_SN_VR}, PR_TRUE}, - {CKM_CAMELLIA_MAC_GENERAL, {16, 32, CKF_SN_VR}, PR_TRUE}, - {CKM_CAMELLIA_CBC_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - /* ------------------------- SEED Operations --------------------------- */ - {CKM_SEED_KEY_GEN, {16, 16, CKF_GENERATE}, PR_TRUE}, - {CKM_SEED_ECB, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_SEED_CBC, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_SEED_MAC, {16, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_SEED_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_SEED_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - /* ------------------------- Hashing Operations ----------------------- */ - {CKM_MD2, {0, 0, CKF_DIGEST}, PR_FALSE}, - {CKM_MD2_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_MD2_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_MD5, {0, 0, CKF_DIGEST}, PR_FALSE}, - {CKM_MD5_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_MD5_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA_1, {0, 0, CKF_DIGEST}, PR_FALSE}, - {CKM_SHA_1_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA_1_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA256, {0, 0, CKF_DIGEST}, PR_FALSE}, - {CKM_SHA256_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA256_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA384, {0, 0, CKF_DIGEST}, PR_FALSE}, - {CKM_SHA384_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA384_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA512, {0, 0, CKF_DIGEST}, PR_FALSE}, - {CKM_SHA512_HMAC, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_SHA512_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_TRUE}, - {CKM_TLS_PRF_GENERAL, {0, 512, CKF_SN_VR}, PR_FALSE}, - /* ------------------------- CAST Operations --------------------------- */ -#ifdef NSS_SOFTOKEN_DOES_CAST - /* Cast operations are not supported ( yet? ) */ - {CKM_CAST_KEY_GEN, {1, 8, CKF_GENERATE}, PR_TRUE}, - {CKM_CAST_ECB, {1, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST_CBC, {1, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST_MAC, {1, 8, CKF_SN_VR}, PR_TRUE}, - {CKM_CAST_MAC_GENERAL, {1, 8, CKF_SN_VR}, PR_TRUE}, - {CKM_CAST_CBC_PAD, {1, 8, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST3_KEY_GEN, {1, 16, CKF_GENERATE}, PR_TRUE}, - {CKM_CAST3_ECB, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST3_CBC, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST3_MAC, {1, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_CAST3_MAC_GENERAL, {1, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_CAST3_CBC_PAD, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST5_KEY_GEN, {1, 16, CKF_GENERATE}, PR_TRUE}, - {CKM_CAST5_ECB, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST5_CBC, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_CAST5_MAC, {1, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_CAST5_MAC_GENERAL, {1, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_CAST5_CBC_PAD, {1, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, -#endif -#if NSS_SOFTOKEN_DOES_RC5 - /* ------------------------- RC5 Operations --------------------------- */ - {CKM_RC5_KEY_GEN, {1, 32, CKF_GENERATE}, PR_TRUE}, - {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_RC5_CBC, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_RC5_MAC, {1, 32, CKF_SN_VR}, PR_TRUE}, - {CKM_RC5_MAC_GENERAL, {1, 32, CKF_SN_VR}, PR_TRUE}, - {CKM_RC5_CBC_PAD, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, -#endif -#ifdef NSS_SOFTOKEN_DOES_IDEA - /* ------------------------- IDEA Operations -------------------------- */ - {CKM_IDEA_KEY_GEN, {16, 16, CKF_GENERATE}, PR_TRUE}, - {CKM_IDEA_ECB, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_IDEA_CBC, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_IDEA_MAC, {16, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_IDEA_MAC_GENERAL, {16, 16, CKF_SN_VR}, PR_TRUE}, - {CKM_IDEA_CBC_PAD, {16, 16, CKF_EN_DE_WR_UN}, PR_TRUE}, -#endif - /* --------------------- Secret Key Operations ------------------------ */ - {CKM_GENERIC_SECRET_KEY_GEN, {1, 32, CKF_GENERATE}, PR_TRUE}, - {CKM_CONCATENATE_BASE_AND_KEY, {1, 32, CKF_GENERATE}, PR_FALSE}, - {CKM_CONCATENATE_BASE_AND_DATA, {1, 32, CKF_GENERATE}, PR_FALSE}, - {CKM_CONCATENATE_DATA_AND_BASE, {1, 32, CKF_GENERATE}, PR_FALSE}, - {CKM_XOR_BASE_AND_DATA, {1, 32, CKF_GENERATE}, PR_FALSE}, - {CKM_EXTRACT_KEY_FROM_KEY, {1, 32, CKF_DERIVE}, PR_FALSE}, - /* ---------------------- SSL Key Derivations ------------------------- */ - {CKM_SSL3_PRE_MASTER_KEY_GEN, {48, 48, CKF_GENERATE}, PR_FALSE}, - {CKM_SSL3_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE}, - {CKM_SSL3_MASTER_KEY_DERIVE_DH, {8, 128, CKF_DERIVE}, PR_FALSE}, - {CKM_SSL3_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE}, - {CKM_SSL3_MD5_MAC, { 0, 16, CKF_DERIVE}, PR_FALSE}, - {CKM_SSL3_SHA1_MAC, { 0, 20, CKF_DERIVE}, PR_FALSE}, - {CKM_MD5_KEY_DERIVATION, { 0, 16, CKF_DERIVE}, PR_FALSE}, - {CKM_MD2_KEY_DERIVATION, { 0, 16, CKF_DERIVE}, PR_FALSE}, - {CKM_SHA1_KEY_DERIVATION, { 0, 20, CKF_DERIVE}, PR_FALSE}, - {CKM_TLS_MASTER_KEY_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE}, - {CKM_TLS_MASTER_KEY_DERIVE_DH, {8, 128, CKF_DERIVE}, PR_FALSE}, - {CKM_TLS_KEY_AND_MAC_DERIVE, {48, 48, CKF_DERIVE}, PR_FALSE}, - /* ---------------------- PBE Key Derivations ------------------------ */ - {CKM_PBE_MD2_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE}, - {CKM_PBE_MD5_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE}, - /* ------------------ NETSCAPE PBE Key Derivations ------------------- */ - {CKM_NETSCAPE_PBE_SHA1_DES_CBC, { 8, 8, CKF_GENERATE}, PR_TRUE}, - {CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, {24,24, CKF_GENERATE}, PR_TRUE}, - {CKM_PBE_SHA1_DES3_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE}, - {CKM_PBE_SHA1_DES2_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE}, - {CKM_PBE_SHA1_RC2_40_CBC, {40,40, CKF_GENERATE}, PR_TRUE}, - {CKM_PBE_SHA1_RC2_128_CBC, {128,128, CKF_GENERATE}, PR_TRUE}, - {CKM_PBE_SHA1_RC4_40, {40,40, CKF_GENERATE}, PR_TRUE}, - {CKM_PBE_SHA1_RC4_128, {128,128, CKF_GENERATE}, PR_TRUE}, - {CKM_PBA_SHA1_WITH_SHA1_HMAC, {20,20, CKF_GENERATE}, PR_TRUE}, - {CKM_PKCS5_PBKD2, {1,256, CKF_GENERATE}, PR_TRUE}, - {CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN, {20,20, CKF_GENERATE}, PR_TRUE}, - {CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE}, - {CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE}, - /* ------------------ AES Key Wrap (also encrypt) ------------------- */ - {CKM_NETSCAPE_AES_KEY_WRAP, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, - {CKM_NETSCAPE_AES_KEY_WRAP_PAD, {16, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, -}; -static const CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]); - -/* sigh global so fipstokn can read it */ -PRBool nsc_init = PR_FALSE; - -#if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED) - -#include <pthread.h> - -static void ForkedChild(void) -{ - if (nsc_init || nsf_init) { - forked = PR_TRUE; - } -} - -#endif - -static char * -sftk_setStringName(const char *inString, char *buffer, int buffer_length, PRBool nullTerminate) -{ - int full_length, string_length; - - full_length = nullTerminate ? buffer_length -1 : buffer_length; - string_length = PORT_Strlen(inString); - /* - * shorten the string, respecting utf8 encoding - * to do so, we work backward from the end - * bytes looking from the end are either: - * - ascii [0x00,0x7f] - * - the [2-n]th byte of a multibyte sequence - * [0x3F,0xBF], i.e, most significant 2 bits are '10' - * - the first byte of a multibyte sequence [0xC0,0xFD], - * i.e, most significant 2 bits are '11' - * - * When the string is too long, we lop off any trailing '10' bytes, - * if any. When these are all eliminated we lop off - * one additional byte. Thus if we lopped any '10' - * we'll be lopping a '11' byte (the first byte of the multibyte sequence), - * otherwise we're lopping off an ascii character. - * - * To test for '10' bytes, we first AND it with - * 11000000 (0xc0) so that we get 10000000 (0x80) if and only if - * the byte starts with 10. We test for equality. - */ - while ( string_length > full_length ) { - /* need to shorten */ - while ( string_length > 0 && - ((inString[string_length-1]&(char)0xc0) == (char)0x80)) { - /* lop off '10' byte */ - string_length--; - } - /* - * test string_length in case bad data is received - * and string consisted of all '10' bytes, - * avoiding any infinite loop - */ - if ( string_length ) { - /* remove either '11' byte or an asci byte */ - string_length--; - } - } - PORT_Memset(buffer,' ',full_length); - if (nullTerminate) { - buffer[full_length] = 0; - } - PORT_Memcpy(buffer,inString,string_length); - return buffer; -} -/* - * Configuration utils - */ -static CK_RV -sftk_configure(const char *man, const char *libdes) -{ - - /* make sure the internationalization was done correctly... */ - if (man) { - manufacturerID = sftk_setStringName(man,manufacturerID_space, - sizeof(manufacturerID_space), PR_TRUE); - } - if (libdes) { - libraryDescription = sftk_setStringName(libdes, - libraryDescription_space, sizeof(libraryDescription_space), - PR_TRUE); - } - - return CKR_OK; -} - -/* - * ******************** Password Utilities ******************************* - */ - -/* - * see if the key DB password is enabled - */ -static PRBool -sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb) -{ - PRBool pwenabled; - - pwenabled = PR_FALSE; - if (sftkdb_HasPasswordSet(keydb) == SECSuccess) { - PRBool tokenRemoved = PR_FALSE; - SECStatus rv = sftkdb_CheckPassword(keydb, "", &tokenRemoved); - if (tokenRemoved) { - sftk_CloseAllSessions(slot, PR_FALSE); - } - return (rv == SECSuccess); - } - - return pwenabled; -} - -/* - * ******************** Object Creation Utilities *************************** - */ - - -/* Make sure a given attribute exists. If it doesn't, initialize it to - * value and len - */ -CK_RV -sftk_defaultAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type,void *value, - unsigned int len) -{ - if ( !sftk_hasAttribute(object, type)) { - return sftk_AddAttributeType(object,type,value,len); - } - return CKR_OK; -} - -/* - * check the consistancy and initialize a Data Object - */ -static CK_RV -sftk_handleDataObject(SFTKSession *session,SFTKObject *object) -{ - CK_RV crv; - - /* first reject private and token data objects */ - if (sftk_isTrue(object,CKA_PRIVATE) || sftk_isTrue(object,CKA_TOKEN)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* now just verify the required date fields */ - crv = sftk_defaultAttribute(object,CKA_APPLICATION,NULL,0); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_VALUE,NULL,0); - if (crv != CKR_OK) return crv; - - return CKR_OK; -} - -/* - * check the consistancy and initialize a Certificate Object - */ -static CK_RV -sftk_handleCertObject(SFTKSession *session,SFTKObject *object) -{ - CK_CERTIFICATE_TYPE type; - SFTKAttribute *attribute; - CK_RV crv; - - /* certificates must have a type */ - if ( !sftk_hasAttribute(object,CKA_CERTIFICATE_TYPE) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - /* we can't store any certs private */ - if (sftk_isTrue(object,CKA_PRIVATE)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* We only support X.509 Certs for now */ - attribute = sftk_FindAttribute(object,CKA_CERTIFICATE_TYPE); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - type = *(CK_CERTIFICATE_TYPE *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - - if (type != CKC_X_509) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* X.509 Certificate */ - - /* make sure we have a cert */ - if ( !sftk_hasAttribute(object,CKA_VALUE) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - /* in PKCS #11, Subject is a required field */ - if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - /* in PKCS #11, Issuer is a required field */ - if ( !sftk_hasAttribute(object,CKA_ISSUER) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - /* in PKCS #11, Serial is a required field */ - if ( !sftk_hasAttribute(object,CKA_SERIAL_NUMBER) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - /* add it to the object */ - object->objectInfo = NULL; - object->infoFree = (SFTKFree) NULL; - - /* now just verify the required date fields */ - crv = sftk_defaultAttribute(object, CKA_ID, NULL, 0); - if (crv != CKR_OK) { return crv; } - - if (sftk_isTrue(object,CKA_TOKEN)) { - SFTKSlot *slot = session->slot; - SFTKDBHandle *certHandle = sftk_getCertDB(slot); - - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - crv = sftkdb_write(certHandle, object, &object->handle); - sftk_freeDB(certHandle); - return crv; - } - - return CKR_OK; -} - -/* - * check the consistancy and initialize a Trust Object - */ -static CK_RV -sftk_handleTrustObject(SFTKSession *session,SFTKObject *object) -{ - /* we can't store any certs private */ - if (sftk_isTrue(object,CKA_PRIVATE)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* certificates must have a type */ - if ( !sftk_hasAttribute(object,CKA_ISSUER) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object,CKA_SERIAL_NUMBER) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object,CKA_CERT_SHA1_HASH) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object,CKA_CERT_MD5_HASH) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - if (sftk_isTrue(object,CKA_TOKEN)) { - SFTKSlot *slot = session->slot; - SFTKDBHandle *certHandle = sftk_getCertDB(slot); - CK_RV crv; - - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - crv = sftkdb_write(certHandle, object, &object->handle); - sftk_freeDB(certHandle); - return crv; - } - - return CKR_OK; -} - -/* - * check the consistancy and initialize a Trust Object - */ -static CK_RV -sftk_handleSMimeObject(SFTKSession *session,SFTKObject *object) -{ - - /* we can't store any certs private */ - if (sftk_isTrue(object,CKA_PRIVATE)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* certificates must have a type */ - if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object,CKA_NETSCAPE_EMAIL) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - if (sftk_isTrue(object,CKA_TOKEN)) { - SFTKSlot *slot = session->slot; - SFTKDBHandle *certHandle; - CK_RV crv; - - PORT_Assert(slot); - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - - certHandle = sftk_getCertDB(slot); - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - crv = sftkdb_write(certHandle, object, &object->handle); - sftk_freeDB(certHandle); - return crv; - } - - return CKR_OK; -} - -/* - * check the consistancy and initialize a Trust Object - */ -static CK_RV -sftk_handleCrlObject(SFTKSession *session,SFTKObject *object) -{ - - /* we can't store any certs private */ - if (sftk_isTrue(object,CKA_PRIVATE)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* certificates must have a type */ - if ( !sftk_hasAttribute(object,CKA_SUBJECT) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object,CKA_VALUE) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - if (sftk_isTrue(object,CKA_TOKEN)) { - SFTKSlot *slot = session->slot; - SFTKDBHandle *certHandle = sftk_getCertDB(slot); - CK_RV crv; - - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - crv = sftkdb_write(certHandle, object, &object->handle); - sftk_freeDB(certHandle); - return crv; - } - - return CKR_OK; -} - -/* - * check the consistancy and initialize a Public Key Object - */ -static CK_RV -sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object, - CK_KEY_TYPE key_type) -{ - CK_BBOOL encrypt = CK_TRUE; - CK_BBOOL recover = CK_TRUE; - CK_BBOOL wrap = CK_TRUE; - CK_BBOOL derive = CK_FALSE; - CK_BBOOL verify = CK_TRUE; - CK_RV crv; - - switch (key_type) { - case CKK_RSA: - crv = sftk_ConstrainAttribute(object, CKA_MODULUS, - RSA_MIN_MODULUS_BITS, 0, 0); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_ConstrainAttribute(object, CKA_PUBLIC_EXPONENT, 2, 0, 0); - if (crv != CKR_OK) { - return crv; - } - break; - case CKK_DSA: - crv = sftk_ConstrainAttribute(object, CKA_SUBPRIME, - DSA_Q_BITS, DSA_Q_BITS, 0); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_ConstrainAttribute(object, CKA_PRIME, - DSA_MIN_P_BITS, DSA_MAX_P_BITS, 64); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_ConstrainAttribute(object, CKA_BASE, 1, DSA_MAX_P_BITS, 0); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_ConstrainAttribute(object, CKA_VALUE, 1, DSA_MAX_P_BITS, 0); - if (crv != CKR_OK) { - return crv; - } - encrypt = CK_FALSE; - recover = CK_FALSE; - wrap = CK_FALSE; - break; - case CKK_DH: - crv = sftk_ConstrainAttribute(object, CKA_PRIME, - DH_MIN_P_BITS, DH_MAX_P_BITS, 0); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_ConstrainAttribute(object, CKA_BASE, 1, DH_MAX_P_BITS, 0); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_ConstrainAttribute(object, CKA_VALUE, 1, DH_MAX_P_BITS, 0); - if (crv != CKR_OK) { - return crv; - } - verify = CK_FALSE; - derive = CK_TRUE; - encrypt = CK_FALSE; - recover = CK_FALSE; - wrap = CK_FALSE; - break; -#ifdef NSS_ENABLE_ECC - case CKK_EC: - if ( !sftk_hasAttribute(object, CKA_EC_PARAMS)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_EC_POINT)) { - return CKR_TEMPLATE_INCOMPLETE; - } - derive = CK_TRUE; /* for ECDH */ - verify = CK_TRUE; /* for ECDSA */ - encrypt = CK_FALSE; - recover = CK_FALSE; - wrap = CK_FALSE; - break; -#endif /* NSS_ENABLE_ECC */ - default: - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* make sure the required fields exist */ - crv = sftk_defaultAttribute(object,CKA_SUBJECT,NULL,0); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_VERIFY,&verify,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_VERIFY_RECOVER, - &recover,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - - object->objectInfo = sftk_GetPubKey(object,key_type, &crv); - if (object->objectInfo == NULL) { - return crv; - } - object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey; - - if (sftk_isTrue(object,CKA_TOKEN)) { - SFTKSlot *slot = session->slot; - SFTKDBHandle *certHandle = sftk_getCertDB(slot); - - if (certHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - crv = sftkdb_write(certHandle, object, &object->handle); - sftk_freeDB(certHandle); - return crv; - } - - return CKR_OK; -} - -static NSSLOWKEYPrivateKey * -sftk_mkPrivKey(SFTKObject *object,CK_KEY_TYPE key, CK_RV *rvp); - -/* - * check the consistancy and initialize a Private Key Object - */ -static CK_RV -sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE key_type) -{ - CK_BBOOL cktrue = CK_TRUE; - CK_BBOOL encrypt = CK_TRUE; - CK_BBOOL sign = CK_FALSE; - CK_BBOOL recover = CK_TRUE; - CK_BBOOL wrap = CK_TRUE; - CK_BBOOL derive = CK_TRUE; - CK_BBOOL ckfalse = CK_FALSE; - SECItem mod; - CK_RV crv; - - switch (key_type) { - case CKK_RSA: - if ( !sftk_hasAttribute(object, CKA_MODULUS)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_PUBLIC_EXPONENT)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_PRIVATE_EXPONENT)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_PRIME_1)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_PRIME_2)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_EXPONENT_1)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_EXPONENT_2)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_COEFFICIENT)) { - return CKR_TEMPLATE_INCOMPLETE; - } - /* make sure Netscape DB attribute is set correctly */ - crv = sftk_Attribute2SSecItem(NULL, &mod, object, CKA_MODULUS); - if (crv != CKR_OK) return crv; - crv = sftk_forceAttribute(object, CKA_NETSCAPE_DB, - sftk_item_expand(&mod)); - if (mod.data) PORT_Free(mod.data); - if (crv != CKR_OK) return crv; - - sign = CK_TRUE; - derive = CK_FALSE; - break; - case CKK_DSA: - if ( !sftk_hasAttribute(object, CKA_SUBPRIME)) { - return CKR_TEMPLATE_INCOMPLETE; - } - sign = CK_TRUE; - derive = CK_FALSE; - /* fall through */ - case CKK_DH: - if ( !sftk_hasAttribute(object, CKA_PRIME)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_BASE)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_VALUE)) { - return CKR_TEMPLATE_INCOMPLETE; - } - encrypt = CK_FALSE; - recover = CK_FALSE; - wrap = CK_FALSE; - break; -#ifdef NSS_ENABLE_ECC - case CKK_EC: - if ( !sftk_hasAttribute(object, CKA_EC_PARAMS)) { - return CKR_TEMPLATE_INCOMPLETE; - } - if ( !sftk_hasAttribute(object, CKA_VALUE)) { - return CKR_TEMPLATE_INCOMPLETE; - } - encrypt = CK_FALSE; - sign = CK_TRUE; - recover = CK_FALSE; - wrap = CK_FALSE; - break; -#endif /* NSS_ENABLE_ECC */ - default: - return CKR_ATTRIBUTE_VALUE_INVALID; - } - crv = sftk_defaultAttribute(object,CKA_SUBJECT,NULL,0); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_SENSITIVE,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_SIGN,&sign,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_SIGN_RECOVER,&recover, - sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_UNWRAP,&wrap,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - /* the next two bits get modified only in the key gen and token cases */ - crv = sftk_forceAttribute(object,CKA_ALWAYS_SENSITIVE, - &ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_forceAttribute(object,CKA_NEVER_EXTRACTABLE, - &ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - - /* should we check the non-token RSA private keys? */ - - if (sftk_isTrue(object,CKA_TOKEN)) { - SFTKSlot *slot = session->slot; - SFTKDBHandle *keyHandle = sftk_getKeyDB(slot); - CK_RV crv; - - if (keyHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - crv = sftkdb_write(keyHandle, object, &object->handle); - sftk_freeDB(keyHandle); - return crv; - } else { - object->objectInfo = sftk_mkPrivKey(object,key_type,&crv); - if (object->objectInfo == NULL) return crv; - object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey; - } - return CKR_OK; -} - -/* forward declare the DES formating function for handleSecretKey */ -void sftk_FormatDESKey(unsigned char *key, int length); - -/* Validate secret key data, and set defaults */ -static CK_RV -validateSecretKey(SFTKSession *session, SFTKObject *object, - CK_KEY_TYPE key_type, PRBool isFIPS) -{ - CK_RV crv; - CK_BBOOL cktrue = CK_TRUE; - CK_BBOOL ckfalse = CK_FALSE; - SFTKAttribute *attribute = NULL; - unsigned long requiredLen; - - crv = sftk_defaultAttribute(object,CKA_SENSITIVE, - isFIPS?&cktrue:&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_EXTRACTABLE, - &cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_ENCRYPT,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_DECRYPT,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_SIGN,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_VERIFY,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_WRAP,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_UNWRAP,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - - if ( !sftk_hasAttribute(object, CKA_VALUE)) { - return CKR_TEMPLATE_INCOMPLETE; - } - /* the next two bits get modified only in the key gen and token cases */ - crv = sftk_forceAttribute(object,CKA_ALWAYS_SENSITIVE, - &ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_forceAttribute(object,CKA_NEVER_EXTRACTABLE, - &ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - - /* some types of keys have a value length */ - crv = CKR_OK; - switch (key_type) { - /* force CKA_VALUE_LEN to be set */ - case CKK_GENERIC_SECRET: - case CKK_RC2: - case CKK_RC4: -#if NSS_SOFTOKEN_DOES_RC5 - case CKK_RC5: -#endif -#ifdef NSS_SOFTOKEN_DOES_CAST - case CKK_CAST: - case CKK_CAST3: - case CKK_CAST5: -#endif -#if NSS_SOFTOKEN_DOES_IDEA - case CKK_IDEA: -#endif - attribute = sftk_FindAttribute(object,CKA_VALUE); - /* shouldn't happen */ - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - crv = sftk_forceAttribute(object, CKA_VALUE_LEN, - &attribute->attrib.ulValueLen, sizeof(CK_ULONG)); - sftk_FreeAttribute(attribute); - break; - /* force the value to have the correct parity */ - case CKK_DES: - case CKK_DES2: - case CKK_DES3: - case CKK_CDMF: - attribute = sftk_FindAttribute(object,CKA_VALUE); - /* shouldn't happen */ - if (attribute == NULL) - return CKR_TEMPLATE_INCOMPLETE; - requiredLen = sftk_MapKeySize(key_type); - if (attribute->attrib.ulValueLen != requiredLen) { - sftk_FreeAttribute(attribute); - return CKR_KEY_SIZE_RANGE; - } - sftk_FormatDESKey((unsigned char*)attribute->attrib.pValue, - attribute->attrib.ulValueLen); - sftk_FreeAttribute(attribute); - break; - case CKK_AES: - attribute = sftk_FindAttribute(object,CKA_VALUE); - /* shouldn't happen */ - if (attribute == NULL) - return CKR_TEMPLATE_INCOMPLETE; - if (attribute->attrib.ulValueLen != 16 && - attribute->attrib.ulValueLen != 24 && - attribute->attrib.ulValueLen != 32) { - sftk_FreeAttribute(attribute); - return CKR_KEY_SIZE_RANGE; - } - crv = sftk_forceAttribute(object, CKA_VALUE_LEN, - &attribute->attrib.ulValueLen, sizeof(CK_ULONG)); - sftk_FreeAttribute(attribute); - break; - default: - break; - } - - return crv; -} - -/* - * check the consistancy and initialize a Secret Key Object - */ -static CK_RV -sftk_handleSecretKeyObject(SFTKSession *session,SFTKObject *object, - CK_KEY_TYPE key_type, PRBool isFIPS) -{ - CK_RV crv; - - /* First validate and set defaults */ - crv = validateSecretKey(session, object, key_type, isFIPS); - if (crv != CKR_OK) goto loser; - - /* If the object is a TOKEN object, store in the database */ - if (sftk_isTrue(object,CKA_TOKEN)) { - SFTKSlot *slot = session->slot; - SFTKDBHandle *keyHandle = sftk_getKeyDB(slot); - CK_RV crv; - - if (keyHandle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - crv = sftkdb_write(keyHandle, object, &object->handle); - sftk_freeDB(keyHandle); - return crv; - } - -loser: - - return crv; -} - -/* - * check the consistancy and initialize a Key Object - */ -static CK_RV -sftk_handleKeyObject(SFTKSession *session, SFTKObject *object) -{ - SFTKAttribute *attribute; - CK_KEY_TYPE key_type; - CK_BBOOL ckfalse = CK_FALSE; - CK_RV crv; - - /* verify the required fields */ - if ( !sftk_hasAttribute(object,CKA_KEY_TYPE) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - /* now verify the common fields */ - crv = sftk_defaultAttribute(object,CKA_ID,NULL,0); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_START_DATE,NULL,0); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_END_DATE,NULL,0); - if (crv != CKR_OK) return crv; - /* CKA_DERIVE is common to all keys, but it's default value is - * key dependent */ - crv = sftk_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - - /* get the key type */ - attribute = sftk_FindAttribute(object,CKA_KEY_TYPE); - if (!attribute) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - - switch (object->objclass) { - case CKO_PUBLIC_KEY: - return sftk_handlePublicKeyObject(session,object,key_type); - case CKO_PRIVATE_KEY: - return sftk_handlePrivateKeyObject(session,object,key_type); - case CKO_SECRET_KEY: - /* make sure the required fields exist */ - return sftk_handleSecretKeyObject(session,object,key_type, - (PRBool)(session->slot->slotID == FIPS_SLOT_ID)); - default: - break; - } - return CKR_ATTRIBUTE_VALUE_INVALID; -} - -/* - * check the consistancy and Verify a DSA Parameter Object - */ -static CK_RV -sftk_handleDSAParameterObject(SFTKSession *session, SFTKObject *object) -{ - SFTKAttribute *primeAttr = NULL; - SFTKAttribute *subPrimeAttr = NULL; - SFTKAttribute *baseAttr = NULL; - SFTKAttribute *seedAttr = NULL; - SFTKAttribute *hAttr = NULL; - SFTKAttribute *attribute; - CK_RV crv = CKR_TEMPLATE_INCOMPLETE; - PQGParams params; - PQGVerify vfy, *verify = NULL; - SECStatus result,rv; - - primeAttr = sftk_FindAttribute(object,CKA_PRIME); - if (primeAttr == NULL) goto loser; - params.prime.data = primeAttr->attrib.pValue; - params.prime.len = primeAttr->attrib.ulValueLen; - - subPrimeAttr = sftk_FindAttribute(object,CKA_SUBPRIME); - if (subPrimeAttr == NULL) goto loser; - params.subPrime.data = subPrimeAttr->attrib.pValue; - params.subPrime.len = subPrimeAttr->attrib.ulValueLen; - - baseAttr = sftk_FindAttribute(object,CKA_BASE); - if (baseAttr == NULL) goto loser; - params.base.data = baseAttr->attrib.pValue; - params.base.len = baseAttr->attrib.ulValueLen; - - attribute = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_COUNTER); - if (attribute != NULL) { - vfy.counter = *(CK_ULONG *) attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - - seedAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_SEED); - if (seedAttr == NULL) goto loser; - vfy.seed.data = seedAttr->attrib.pValue; - vfy.seed.len = seedAttr->attrib.ulValueLen; - - hAttr = sftk_FindAttribute(object, CKA_NETSCAPE_PQG_H); - if (hAttr == NULL) goto loser; - vfy.h.data = hAttr->attrib.pValue; - vfy.h.len = hAttr->attrib.ulValueLen; - - verify = &vfy; - } - - crv = CKR_FUNCTION_FAILED; - rv = PQG_VerifyParams(¶ms,verify,&result); - if (rv == SECSuccess) { - crv = (result== SECSuccess) ? CKR_OK : CKR_ATTRIBUTE_VALUE_INVALID; - } - -loser: - if (hAttr) sftk_FreeAttribute(hAttr); - if (seedAttr) sftk_FreeAttribute(seedAttr); - if (baseAttr) sftk_FreeAttribute(baseAttr); - if (subPrimeAttr) sftk_FreeAttribute(subPrimeAttr); - if (primeAttr) sftk_FreeAttribute(primeAttr); - - return crv; -} - -/* - * check the consistancy and initialize a Key Parameter Object - */ -static CK_RV -sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object) -{ - SFTKAttribute *attribute; - CK_KEY_TYPE key_type; - CK_BBOOL ckfalse = CK_FALSE; - CK_RV crv; - - /* verify the required fields */ - if ( !sftk_hasAttribute(object,CKA_KEY_TYPE) ) { - return CKR_TEMPLATE_INCOMPLETE; - } - - /* now verify the common fields */ - crv = sftk_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - - /* get the key type */ - attribute = sftk_FindAttribute(object,CKA_KEY_TYPE); - if (!attribute) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - - switch (key_type) { - case CKK_DSA: - return sftk_handleDSAParameterObject(session,object); - - default: - break; - } - return CKR_KEY_TYPE_INCONSISTENT; -} - -/* - * Handle Object does all the object consistancy checks, automatic attribute - * generation, attribute defaulting, etc. If handleObject succeeds, the object - * will be assigned an object handle, and the object installed in the session - * or stored in the DB. - */ -CK_RV -sftk_handleObject(SFTKObject *object, SFTKSession *session) -{ - SFTKSlot *slot = session->slot; - SFTKAttribute *attribute; - SFTKObject *duplicateObject = NULL; - CK_OBJECT_HANDLE handle; - CK_BBOOL ckfalse = CK_FALSE; - CK_BBOOL cktrue = CK_TRUE; - CK_RV crv; - - /* make sure all the base object types are defined. If not set the - * defaults */ - crv = sftk_defaultAttribute(object,CKA_TOKEN,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_PRIVATE,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_LABEL,NULL,0); - if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_MODIFIABLE,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) return crv; - - /* don't create a private object if we aren't logged in */ - if ((!slot->isLoggedIn) && (slot->needLogin) && - (sftk_isTrue(object,CKA_PRIVATE))) { - return CKR_USER_NOT_LOGGED_IN; - } - - - if (((session->info.flags & CKF_RW_SESSION) == 0) && - (sftk_isTrue(object,CKA_TOKEN))) { - return CKR_SESSION_READ_ONLY; - } - - /* Assign a unique SESSION object handle to every new object, - * whether it is a session object or a token object. - * At this point, all new objects are structured as session objects. - * Objects with the CKA_TOKEN attribute true will be turned into - * token objects and will have a token object handle assigned to - * them by a call to sftk_mkHandle in the handler for each object - * class, invoked below. - * - * It may be helpful to note/remember that - * sftk_narrowToXxxObject uses sftk_isToken, - * sftk_isToken examines the sign bit of the object's handle, but - * sftk_isTrue(...,CKA_TOKEN) examines the CKA_TOKEN attribute. - */ - do { - PRUint32 wrappedAround; - - duplicateObject = NULL; - PZ_Lock(slot->objectLock); - wrappedAround = slot->sessionObjectHandleCount & SFTK_TOKEN_MASK; - handle = slot->sessionObjectHandleCount & ~SFTK_TOKEN_MASK; - if (!handle) /* don't allow zero handle */ - handle = minSessionObjectHandle; - slot->sessionObjectHandleCount = (handle + 1U) | wrappedAround; - /* Is there already a session object with this handle? */ - if (wrappedAround) { - sftkqueue_find(duplicateObject, handle, slot->sessObjHashTable, \ - slot->sessObjHashSize); - } - PZ_Unlock(slot->objectLock); - } while (duplicateObject != NULL); - object->handle = handle; - - /* get the object class */ - attribute = sftk_FindAttribute(object,CKA_CLASS); - if (attribute == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - object->objclass = *(CK_OBJECT_CLASS *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - - /* Now handle the specific object class. - * At this point, all objects are session objects, and the session - * number must be passed to the object class handlers. - */ - switch (object->objclass) { - case CKO_DATA: - crv = sftk_handleDataObject(session,object); - break; - case CKO_CERTIFICATE: - crv = sftk_handleCertObject(session,object); - break; - case CKO_NETSCAPE_TRUST: - crv = sftk_handleTrustObject(session,object); - break; - case CKO_NETSCAPE_CRL: - crv = sftk_handleCrlObject(session,object); - break; - case CKO_NETSCAPE_SMIME: - crv = sftk_handleSMimeObject(session,object); - break; - case CKO_PRIVATE_KEY: - case CKO_PUBLIC_KEY: - case CKO_SECRET_KEY: - crv = sftk_handleKeyObject(session,object); - break; - case CKO_KG_PARAMETERS: - crv = sftk_handleKeyParameterObject(session,object); - break; - default: - crv = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - - /* can't fail from here on out unless the pk_handlXXX functions have - * failed the request */ - if (crv != CKR_OK) { - return crv; - } - - /* Now link the object into the slot and session structures. - * If the object has a true CKA_TOKEN attribute, the above object - * class handlers will have set the sign bit in the object handle, - * causing the following test to be true. - */ - if (sftk_isToken(object->handle)) { - sftk_convertSessionToToken(object); - } else { - object->slot = slot; - sftk_AddObject(session,object); - } - - return CKR_OK; -} - -/* - * ******************** Public Key Utilities *************************** - */ -/* Generate a low public key structure from an object */ -NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,CK_KEY_TYPE key_type, - CK_RV *crvp) -{ - NSSLOWKEYPublicKey *pubKey; - PLArenaPool *arena; - CK_RV crv; - - if (object->objclass != CKO_PUBLIC_KEY) { - *crvp = CKR_KEY_TYPE_INCONSISTENT; - return NULL; - } - - if (sftk_isToken(object->handle)) { -/* ferret out the token object handle */ - } - - /* If we already have a key, use it */ - if (object->objectInfo) { - *crvp = CKR_OK; - return (NSSLOWKEYPublicKey *)object->objectInfo; - } - - /* allocate the structure */ - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - *crvp = CKR_HOST_MEMORY; - return NULL; - } - - pubKey = (NSSLOWKEYPublicKey *) - PORT_ArenaAlloc(arena,sizeof(NSSLOWKEYPublicKey)); - if (pubKey == NULL) { - PORT_FreeArena(arena,PR_FALSE); - *crvp = CKR_HOST_MEMORY; - return NULL; - } - - /* fill in the structure */ - pubKey->arena = arena; - switch (key_type) { - case CKK_RSA: - pubKey->keyType = NSSLOWKEYRSAKey; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.rsa.modulus, - object,CKA_MODULUS); - if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.rsa.publicExponent, - object,CKA_PUBLIC_EXPONENT); - break; - case CKK_DSA: - pubKey->keyType = NSSLOWKEYDSAKey; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.params.prime, - object,CKA_PRIME); - if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.params.subPrime, - object,CKA_SUBPRIME); - if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.params.base, - object,CKA_BASE); - if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dsa.publicValue, - object,CKA_VALUE); - break; - case CKK_DH: - pubKey->keyType = NSSLOWKEYDHKey; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dh.prime, - object,CKA_PRIME); - if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dh.base, - object,CKA_BASE); - if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.dh.publicValue, - object,CKA_VALUE); - break; -#ifdef NSS_ENABLE_ECC - case CKK_EC: - pubKey->keyType = NSSLOWKEYECKey; - crv = sftk_Attribute2SSecItem(arena, - &pubKey->u.ec.ecParams.DEREncoding, - object,CKA_EC_PARAMS); - if (crv != CKR_OK) break; - - /* Fill out the rest of the ecParams structure - * based on the encoded params - */ - if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding, - &pubKey->u.ec.ecParams) != SECSuccess) { - crv = CKR_DOMAIN_PARAMS_INVALID; - break; - } - - crv = sftk_Attribute2SSecItem(arena,&pubKey->u.ec.publicValue, - object,CKA_EC_POINT); - if (crv == CKR_OK) { - int keyLen,curveLen; - - curveLen = (pubKey->u.ec.ecParams.fieldID.size +7)/8; - keyLen = (2*curveLen)+1; - - /* special note: We can't just use the first byte to determine - * between these 2 cases because both EC_POINT_FORM_UNCOMPRESSED - * and SEC_ASN1_OCTET_STRING are 0x04 */ - - /* handle the non-DER encoded case (UNCOMPRESSED only) */ - if (pubKey->u.ec.publicValue.data[0] == EC_POINT_FORM_UNCOMPRESSED - && pubKey->u.ec.publicValue.len == keyLen) { - break; /* key was not DER encoded, no need to unwrap */ - } - - /* if we ever support compressed, handle it here */ - - /* handle the encoded case */ - if ((pubKey->u.ec.publicValue.data[0] == SEC_ASN1_OCTET_STRING) - && pubKey->u.ec.publicValue.len > keyLen) { - SECItem publicValue; - SECStatus rv; - - rv = SEC_QuickDERDecodeItem(arena, &publicValue, - SEC_ASN1_GET(SEC_OctetStringTemplate), - &pubKey->u.ec.publicValue); - /* nope, didn't decode correctly */ - if ((rv != SECSuccess) - || (publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) - || (publicValue.len != keyLen)) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - /* replace our previous with the decoded key */ - pubKey->u.ec.publicValue = publicValue; - break; - } - crv = CKR_ATTRIBUTE_VALUE_INVALID; - } - break; -#endif /* NSS_ENABLE_ECC */ - default: - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - *crvp = crv; - if (crv != CKR_OK) { - PORT_FreeArena(arena,PR_FALSE); - return NULL; - } - - object->objectInfo = pubKey; - object->infoFree = (SFTKFree) nsslowkey_DestroyPublicKey; - return pubKey; -} - -/* make a private key from a verified object */ -static NSSLOWKEYPrivateKey * -sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) -{ - NSSLOWKEYPrivateKey *privKey; - SFTKItemTemplate itemTemplate[SFTK_MAX_ITEM_TEMPLATE]; - int itemTemplateCount = 0; - PLArenaPool *arena; - CK_RV crv = CKR_OK; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - *crvp = CKR_HOST_MEMORY; - return NULL; - } - - privKey = (NSSLOWKEYPrivateKey *) - PORT_ArenaZAlloc(arena,sizeof(NSSLOWKEYPrivateKey)); - if (privKey == NULL) { - PORT_FreeArena(arena,PR_FALSE); - *crvp = CKR_HOST_MEMORY; - return NULL; - } - - /* in future this would be a switch on key_type */ - privKey->arena = arena; - switch (key_type) { - case CKK_RSA: - privKey->keyType = NSSLOWKEYRSAKey; - - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.modulus,CKA_MODULUS); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.publicExponent, CKA_PUBLIC_EXPONENT); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.privateExponent, CKA_PRIVATE_EXPONENT); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.prime1, CKA_PRIME_1); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.prime2, CKA_PRIME_2); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.exponent1, CKA_EXPONENT_1); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.exponent2, CKA_EXPONENT_2); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.rsa.coefficient, CKA_COEFFICIENT); - itemTemplateCount++; - rv = DER_SetUInteger(privKey->arena, &privKey->u.rsa.version, - NSSLOWKEY_PRIVATE_KEY_INFO_VERSION); - if (rv != SECSuccess) crv = CKR_HOST_MEMORY; - break; - - case CKK_DSA: - privKey->keyType = NSSLOWKEYDSAKey; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.dsa.params.prime, CKA_PRIME); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.dsa.params.subPrime, CKA_SUBPRIME); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.dsa.params.base, CKA_BASE); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.dsa.privateValue, CKA_VALUE); - itemTemplateCount++; - /* privKey was zero'd so public value is already set to NULL, 0 - * if we don't set it explicitly */ - break; - - case CKK_DH: - privKey->keyType = NSSLOWKEYDHKey; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.dh.prime, CKA_PRIME); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.dh.base, CKA_BASE); - itemTemplateCount++; - SFTK_SET_ITEM_TEMPLATE(itemTemplate, itemTemplateCount, - &privKey->u.dh.privateValue, CKA_VALUE); - itemTemplateCount++; - /* privKey was zero'd so public value is already set to NULL, 0 - * if we don't set it explicitly */ - break; - -#ifdef NSS_ENABLE_ECC - case CKK_EC: - privKey->keyType = NSSLOWKEYECKey; - crv = sftk_Attribute2SSecItem(arena, - &privKey->u.ec.ecParams.DEREncoding, - object,CKA_EC_PARAMS); - if (crv != CKR_OK) break; - - /* Fill out the rest of the ecParams structure - * based on the encoded params - */ - if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding, - &privKey->u.ec.ecParams) != SECSuccess) { - crv = CKR_DOMAIN_PARAMS_INVALID; - break; - } - crv = sftk_Attribute2SSecItem(arena,&privKey->u.ec.privateValue, - object,CKA_VALUE); - if (crv != CKR_OK) break; - - if (sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { - crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue, - object, CKA_NETSCAPE_DB); - if (crv != CKR_OK) break; - /* privKey was zero'd so public value is already set to NULL, 0 - * if we don't set it explicitly */ - } - rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version, - NSSLOWKEY_EC_PRIVATE_KEY_VERSION); - if (rv != SECSuccess) crv = CKR_HOST_MEMORY; - break; -#endif /* NSS_ENABLE_ECC */ - - default: - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - if (crv == CKR_OK && itemTemplateCount != 0) { - PORT_Assert(itemTemplateCount > 0); - PORT_Assert(itemTemplateCount <= SFTK_MAX_ITEM_TEMPLATE); - crv = sftk_MultipleAttribute2SecItem(arena, object, itemTemplate, - itemTemplateCount); - } - *crvp = crv; - if (crv != CKR_OK) { - PORT_FreeArena(arena,PR_FALSE); - return NULL; - } - return privKey; -} - - -/* Generate a low private key structure from an object */ -NSSLOWKEYPrivateKey * -sftk_GetPrivKey(SFTKObject *object,CK_KEY_TYPE key_type, CK_RV *crvp) -{ - NSSLOWKEYPrivateKey *priv = NULL; - - if (object->objclass != CKO_PRIVATE_KEY) { - *crvp = CKR_KEY_TYPE_INCONSISTENT; - return NULL; - } - if (object->objectInfo) { - *crvp = CKR_OK; - return (NSSLOWKEYPrivateKey *)object->objectInfo; - } - - priv = sftk_mkPrivKey(object, key_type, crvp); - object->objectInfo = priv; - object->infoFree = (SFTKFree) nsslowkey_DestroyPrivateKey; - return priv; -} - -/* - **************************** Symetric Key utils ************************ - */ -/* - * set the DES key with parity bits correctly - */ -void -sftk_FormatDESKey(unsigned char *key, int length) -{ - int i; - - /* format the des key */ - for (i=0; i < length; i++) { - key[i] = parityTable[key[i]>>1]; - } -} - -/* - * check a des key (des2 or des3 subkey) for weak keys. - */ -PRBool -sftk_CheckDESKey(unsigned char *key) -{ - int i; - - /* format the des key with parity */ - sftk_FormatDESKey(key, 8); - - for (i=0; i < sftk_desWeakTableSize; i++) { - if (PORT_Memcmp(key,sftk_desWeakTable[i],8) == 0) { - return PR_TRUE; - } - } - return PR_FALSE; -} - -/* - * check if a des or triple des key is weak. - */ -PRBool -sftk_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type) -{ - - switch(key_type) { - case CKK_DES: - return sftk_CheckDESKey(key); - case CKM_DES2_KEY_GEN: - if (sftk_CheckDESKey(key)) return PR_TRUE; - return sftk_CheckDESKey(&key[8]); - case CKM_DES3_KEY_GEN: - if (sftk_CheckDESKey(key)) return PR_TRUE; - if (sftk_CheckDESKey(&key[8])) return PR_TRUE; - return sftk_CheckDESKey(&key[16]); - default: - break; - } - return PR_FALSE; -} - - -/********************************************************************** - * - * Start of PKCS 11 functions - * - **********************************************************************/ - - -/* return the function list */ -CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) -{ - CHECK_FORK(); - - *pFunctionList = (CK_FUNCTION_LIST_PTR) &sftk_funcList; - return CKR_OK; -} - -/* return the function list */ -CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) -{ - CHECK_FORK(); - - return NSC_GetFunctionList(pFunctionList); -} - -static PLHashNumber -sftk_HashNumber(const void *key) -{ - return (PLHashNumber) key; -} - -/* - * eventually I'd like to expunge all occurances of XXX_SLOT_ID and - * just go with the info in the slot. This is one place, however, - * where it might be a little difficult. - */ -const char * -sftk_getDefTokName(CK_SLOT_ID slotID) -{ - static char buf[33]; - - switch (slotID) { - case NETSCAPE_SLOT_ID: - return "NSS Generic Crypto Services "; - case PRIVATE_KEY_SLOT_ID: - return "NSS Certificate DB "; - case FIPS_SLOT_ID: - return "NSS FIPS 140-2 Certificate DB "; - default: - break; - } - sprintf(buf,"NSS Application Token %08x ",(unsigned int) slotID); - return buf; -} - -const char * -sftk_getDefSlotName(CK_SLOT_ID slotID) -{ - static char buf[65]; - - switch (slotID) { - case NETSCAPE_SLOT_ID: - return - "NSS Internal Cryptographic Services "; - case PRIVATE_KEY_SLOT_ID: - return - "NSS User Private Key and Certificate Services "; - case FIPS_SLOT_ID: - return - "NSS FIPS 140-2 User Private Key Services "; - default: - break; - } - sprintf(buf, - "NSS Application Slot %08x ", - (unsigned int) slotID); - return buf; -} - -static CK_ULONG nscSlotCount[2] = {0 , 0}; -static CK_SLOT_ID_PTR nscSlotList[2] = {NULL, NULL}; -static CK_ULONG nscSlotListSize[2] = {0, 0}; -static PLHashTable *nscSlotHashTable[2] = {NULL, NULL}; - -static int -sftk_GetModuleIndex(CK_SLOT_ID slotID) -{ - if ((slotID == FIPS_SLOT_ID) || (slotID >= SFTK_MIN_FIPS_USER_SLOT_ID)) { - return NSC_FIPS_MODULE; - } - return NSC_NON_FIPS_MODULE; -} - -/* look up a slot structure from the ID (used to be a macro when we only - * had two slots) */ -/* if all is true, return the slot even if it has been 'unloaded' */ -/* if all is false, only return the slots which are present */ -SFTKSlot * -sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all) -{ - SFTKSlot *slot; - int index = sftk_GetModuleIndex(slotID); - - if (nscSlotHashTable[index] == NULL) return NULL; - slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index], - (void *)slotID); - /* cleared slots shouldn't 'show up' */ - if (slot && !all && !slot->present) slot = NULL; - return slot; -} - -SFTKSlot * -sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle) -{ - CK_ULONG slotIDIndex = (handle >> 24) & 0x7f; - CK_ULONG moduleIndex = (handle >> 31) & 1; - - if (slotIDIndex >= nscSlotCount[moduleIndex]) { - return NULL; - } - - return sftk_SlotFromID(nscSlotList[moduleIndex][slotIDIndex], PR_FALSE); -} - -static CK_RV -sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex) -{ - PLHashEntry *entry; - int index; - - index = sftk_GetModuleIndex(slot->slotID); - - /* make sure the slotID for this module is valid */ - if (moduleIndex != index) { - return CKR_SLOT_ID_INVALID; - } - - if (nscSlotList[index] == NULL) { - nscSlotListSize[index] = NSC_SLOT_LIST_BLOCK_SIZE; - nscSlotList[index] = (CK_SLOT_ID *) - PORT_ZAlloc(nscSlotListSize[index]*sizeof(CK_SLOT_ID)); - if (nscSlotList[index] == NULL) { - return CKR_HOST_MEMORY; - } - } - if (nscSlotCount[index] >= nscSlotListSize[index]) { - CK_SLOT_ID* oldNscSlotList = nscSlotList[index]; - CK_ULONG oldNscSlotListSize = nscSlotListSize[index]; - nscSlotListSize[index] += NSC_SLOT_LIST_BLOCK_SIZE; - nscSlotList[index] = (CK_SLOT_ID *) PORT_Realloc(oldNscSlotList, - nscSlotListSize[index]*sizeof(CK_SLOT_ID)); - if (nscSlotList[index] == NULL) { - nscSlotList[index] = oldNscSlotList; - nscSlotListSize[index] = oldNscSlotListSize; - return CKR_HOST_MEMORY; - } - } - - if (nscSlotHashTable[index] == NULL) { - nscSlotHashTable[index] = PL_NewHashTable(64,sftk_HashNumber, - PL_CompareValues, PL_CompareValues, NULL, 0); - if (nscSlotHashTable[index] == NULL) { - return CKR_HOST_MEMORY; - } - } - - entry = PL_HashTableAdd(nscSlotHashTable[index],(void *)slot->slotID,slot); - if (entry == NULL) { - return CKR_HOST_MEMORY; - } - slot->index = (nscSlotCount[index] & 0x7f) | ((index << 7) & 0x80); - nscSlotList[index][nscSlotCount[index]++] = slot->slotID; - - return CKR_OK; -} - - -/* - * ths function has all the common initialization that happens whenever we - * create a new slot or repurpose an old slot (only valid for slotID's 4 - * and greater). - * - * things that are not reinitialized are: - * slotID (can't change) - * slotDescription (can't change once defined) - * the locks and hash tables (difficult to change in running code, and - * unnecessary. hash tables and list are cleared on shutdown, but they - * are cleared in a 'friendly' way). - * session and object ID counters -- so any old sessions and objects in the - * application will get properly notified that the world has changed. - * - * things that are reinitialized: - * database (otherwise what would the point be;). - * state variables related to databases. - * session count stat info. - * tokenDescription. - * - * NOTE: slotID's 4 and greater show up as removable devices. - * - */ -CK_RV -SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir, - char *updateID, sftk_token_parameters *params, int moduleIndex) -{ - PRBool needLogin = !params->noKeyDB; - CK_RV crv; - - slot->hasTokens = PR_FALSE; - slot->sessionIDConflict = 0; - slot->sessionCount = 0; - slot->rwSessionCount = 0; - slot->needLogin = PR_FALSE; - slot->isLoggedIn = PR_FALSE; - slot->ssoLoggedIn = PR_FALSE; - slot->DB_loaded = PR_FALSE; - slot->certDB = NULL; - slot->keyDB = NULL; - slot->minimumPinLen = 0; - slot->readOnly = params->readOnly; - sftk_setStringName(params->tokdes ? params->tokdes : - sftk_getDefTokName(slot->slotID), slot->tokDescription, - sizeof(slot->tokDescription),PR_TRUE); - sftk_setStringName(params->updtokdes ? params->updtokdes : " ", - slot->updateTokDescription, - sizeof(slot->updateTokDescription),PR_TRUE); - - if ((!params->noCertDB) || (!params->noKeyDB)) { - SFTKDBHandle * certHandle = NULL; - SFTKDBHandle *keyHandle = NULL; - crv = sftk_DBInit(params->configdir ? params->configdir : configdir, - params->certPrefix, params->keyPrefix, - params->updatedir ? params->updatedir : updatedir, - params->updCertPrefix, params->updKeyPrefix, - params->updateID ? params->updateID : updateID, - params->readOnly, params->noCertDB, params->noKeyDB, - params->forceOpen, &certHandle, &keyHandle); - if (crv != CKR_OK) { - goto loser; - } - - slot->certDB = certHandle; - slot->keyDB = keyHandle; - } - if (needLogin) { - /* if the data base is initialized with a null password,remember that */ - slot->needLogin = - (PRBool)!sftk_hasNullPassword(slot, slot->keyDB); - if ((params->minPW >= 0) && (params->minPW <= SFTK_MAX_PIN)) { - slot->minimumPinLen = params->minPW; - } - if ((slot->minimumPinLen == 0) && (params->pwRequired)) { - slot->minimumPinLen = 1; - } - if ((moduleIndex == NSC_FIPS_MODULE) && - (slot->minimumPinLen < FIPS_MIN_PIN)) { - slot->minimumPinLen = FIPS_MIN_PIN; - } - } - - slot->present = PR_TRUE; - return CKR_OK; - -loser: - SFTK_ShutdownSlot(slot); - return crv; -} - -/* - * initialize one of the slot structures. figure out which by the ID - */ -CK_RV -SFTK_SlotInit(char *configdir, char *updatedir, char *updateID, - sftk_token_parameters *params, int moduleIndex) -{ - unsigned int i; - CK_SLOT_ID slotID = params->slotID; - SFTKSlot *slot; - CK_RV crv = CKR_HOST_MEMORY; - - /* - * first we initialize everything that is 'permanent' with this slot. - * that is everything we aren't going to shutdown if we close this slot - * and open it up again with different databases */ - - slot = PORT_ZNew(SFTKSlot); - - if (slot == NULL) { - return CKR_HOST_MEMORY; - } - - slot->optimizeSpace = params->optimizeSpace; - if (slot->optimizeSpace) { - slot->sessObjHashSize = SPACE_SESSION_OBJECT_HASH_SIZE; - slot->sessHashSize = SPACE_SESSION_HASH_SIZE; - slot->numSessionLocks = 1; - } else { - slot->sessObjHashSize = TIME_SESSION_OBJECT_HASH_SIZE; - slot->sessHashSize = TIME_SESSION_HASH_SIZE; - slot->numSessionLocks = slot->sessHashSize/BUCKETS_PER_SESSION_LOCK; - } - slot->sessionLockMask = slot->numSessionLocks-1; - - slot->slotLock = PZ_NewLock(nssILockSession); - if (slot->slotLock == NULL) - goto mem_loser; - slot->sessionLock = PORT_ZNewArray(PZLock *, slot->numSessionLocks); - if (slot->sessionLock == NULL) - goto mem_loser; - for (i=0; i < slot->numSessionLocks; i++) { - slot->sessionLock[i] = PZ_NewLock(nssILockSession); - if (slot->sessionLock[i] == NULL) - goto mem_loser; - } - slot->objectLock = PZ_NewLock(nssILockObject); - if (slot->objectLock == NULL) - goto mem_loser; - slot->pwCheckLock = PR_NewLock(); - if (slot->pwCheckLock == NULL) - goto mem_loser; - slot->head = PORT_ZNewArray(SFTKSession *, slot->sessHashSize); - if (slot->head == NULL) - goto mem_loser; - slot->sessObjHashTable = PORT_ZNewArray(SFTKObject *, slot->sessObjHashSize); - if (slot->sessObjHashTable == NULL) - goto mem_loser; - slot->tokObjHashTable = PL_NewHashTable(64,sftk_HashNumber,PL_CompareValues, - SECITEM_HashCompare, NULL, 0); - if (slot->tokObjHashTable == NULL) - goto mem_loser; - - slot->sessionIDCount = 0; - slot->sessionObjectHandleCount = minSessionObjectHandle; - slot->slotID = slotID; - sftk_setStringName(params->slotdes ? params->slotdes : - sftk_getDefSlotName(slotID), slot->slotDescription, - sizeof(slot->slotDescription), PR_TRUE); - - /* call the reinit code to set everything that changes between token - * init calls */ - crv = SFTK_SlotReInit(slot, configdir, updatedir, updateID, - params, moduleIndex); - if (crv != CKR_OK) { - goto loser; - } - crv = sftk_RegisterSlot(slot, moduleIndex); - if (crv != CKR_OK) { - goto loser; - } - return CKR_OK; - -mem_loser: - crv = CKR_HOST_MEMORY; -loser: - SFTK_DestroySlotData(slot); - return crv; -} - - -CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout) -{ - SFTKSession *session; - unsigned int i; - SFTKDBHandle *handle; - - /* first log out the card */ - /* special case - if we are in a middle of upgrade, we want to close the - * sessions to fake a token removal to tell the upper level code we have - * switched from one database to another, but we don't want to - * explicity logout in case we can continue the upgrade with the - * existing password if possible. - */ - if (logout) { - handle = sftk_getKeyDB(slot); - SKIP_AFTER_FORK(PZ_Lock(slot->slotLock)); - slot->isLoggedIn = PR_FALSE; - if (handle) { - sftkdb_ClearPassword(handle); - } - SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock)); - if (handle) { - sftk_freeDB(handle); - } - } - - /* now close all the current sessions */ - /* NOTE: If you try to open new sessions before NSC_CloseAllSessions - * completes, some of those new sessions may or may not be closed by - * NSC_CloseAllSessions... but any session running when this code starts - * will guarrenteed be close, and no session will be partially closed */ - for (i=0; i < slot->sessHashSize; i++) { - PZLock *lock = SFTK_SESSION_LOCK(slot,i); - do { - SKIP_AFTER_FORK(PZ_Lock(lock)); - session = slot->head[i]; - /* hand deque */ - /* this duplicates function of NSC_close session functions, but - * because we know that we are freeing all the sessions, we can - * do more efficient processing */ - if (session) { - slot->head[i] = session->next; - if (session->next) session->next->prev = NULL; - session->next = session->prev = NULL; - SKIP_AFTER_FORK(PZ_Unlock(lock)); - SKIP_AFTER_FORK(PZ_Lock(slot->slotLock)); - --slot->sessionCount; - SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock)); - if (session->info.flags & CKF_RW_SESSION) { - PR_AtomicDecrement(&slot->rwSessionCount); - } - } else { - SKIP_AFTER_FORK(PZ_Unlock(lock)); - } - if (session) sftk_FreeSession(session); - } while (session != NULL); - } - return CKR_OK; -} - -/* - * shut down the databases. - * we get the slot lock (which also protects slot->certDB and slot->keyDB) - * and clear the values so the new users will not find the databases. - * once things are clear, we can release our references to the databases. - * The databases will close when the last reference is released. - * - * We use reference counts so that we don't crash if someone shuts down - * a token that another thread is actively using. - */ -static void -sftk_DBShutdown(SFTKSlot *slot) -{ - SFTKDBHandle *certHandle; - SFTKDBHandle *keyHandle; - SKIP_AFTER_FORK(PZ_Lock(slot->slotLock)); - certHandle = slot->certDB; - slot->certDB = NULL; - keyHandle = slot->keyDB; - slot->keyDB = NULL; - SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock)); - if (certHandle) { - sftk_freeDB(certHandle); - } - if (keyHandle) { - sftk_freeDB(keyHandle); - } -} - -CK_RV -SFTK_ShutdownSlot(SFTKSlot *slot) -{ - /* make sure no new PK11 calls work except C_GetSlotInfo */ - slot->present = PR_FALSE; - - /* close all outstanding sessions - * the sessHashSize variable guarentees we have all the session - * mechanism set up */ - if (slot->head) { - sftk_CloseAllSessions(slot, PR_TRUE); - } - - /* clear all objects.. session objects are cleared as a result of - * closing all the sessions. We just need to clear the token object - * cache. slot->tokObjHashTable guarentees we have the token - * infrastructure set up. */ - if (slot->tokObjHashTable) { - SFTK_ClearTokenKeyHashTable(slot); - } - - /* clear the slot description for the next guy */ - PORT_Memset(slot->tokDescription, 0, sizeof(slot->tokDescription)); - - /* now shut down the databases. */ - sftk_DBShutdown(slot); - return CKR_OK; -} - -/* - * initialize one of the slot structures. figure out which by the ID - */ -CK_RV -SFTK_DestroySlotData(SFTKSlot *slot) -{ - unsigned int i; - - SFTK_ShutdownSlot(slot); - - if (slot->tokObjHashTable) { - PL_HashTableDestroy(slot->tokObjHashTable); - slot->tokObjHashTable = NULL; - } - - if (slot->sessObjHashTable) { - PORT_Free(slot->sessObjHashTable); - slot->sessObjHashTable = NULL; - } - slot->sessObjHashSize = 0; - - if (slot->head) { - PORT_Free(slot->head); - slot->head = NULL; - } - slot->sessHashSize = 0; - - /* OK everything has been disassembled, now we can finally get rid - * of the locks */ - SKIP_AFTER_FORK(PZ_DestroyLock(slot->slotLock)); - slot->slotLock = NULL; - if (slot->sessionLock) { - for (i=0; i < slot->numSessionLocks; i++) { - if (slot->sessionLock[i]) { - SKIP_AFTER_FORK(PZ_DestroyLock(slot->sessionLock[i])); - slot->sessionLock[i] = NULL; - } - } - PORT_Free(slot->sessionLock); - slot->sessionLock = NULL; - } - if (slot->objectLock) { - SKIP_AFTER_FORK(PZ_DestroyLock(slot->objectLock)); - slot->objectLock = NULL; - } - if (slot->pwCheckLock) { - SKIP_AFTER_FORK(PR_DestroyLock(slot->pwCheckLock)); - slot->pwCheckLock = NULL; - } - PORT_Free(slot); - return CKR_OK; -} - -#ifndef NO_FORK_CHECK - -static CK_RV ForkCheck(void) -{ - CHECK_FORK(); - return CKR_OK; -} - -#endif - -/* - * handle the SECMOD.db - */ -char ** -NSC_ModuleDBFunc(unsigned long function,char *parameters, void *args) -{ - char *secmod = NULL; - char *appName = NULL; - char *filename = NULL; -#ifdef NSS_DISABLE_DBM - SDBType dbType = SDB_SQL; -#else - SDBType dbType = SDB_LEGACY; -#endif - PRBool rw; - static char *success="Success"; - char **rvstr = NULL; - -#ifndef NO_FORK_CHECK - if (CKR_OK != ForkCheck()) return NULL; -#endif - - secmod = sftk_getSecmodName(parameters, &dbType, &appName,&filename, &rw); - - switch (function) { - case SECMOD_MODULE_DB_FUNCTION_FIND: - rvstr = sftkdb_ReadSecmodDB(dbType,appName,filename,secmod,(char *)parameters,rw); - break; - case SECMOD_MODULE_DB_FUNCTION_ADD: - rvstr = (sftkdb_AddSecmodDB(dbType,appName,filename,secmod,(char *)args,rw) - == SECSuccess) ? &success: NULL; - break; - case SECMOD_MODULE_DB_FUNCTION_DEL: - rvstr = (sftkdb_DeleteSecmodDB(dbType,appName,filename,secmod,(char *)args,rw) - == SECSuccess) ? &success: NULL; - break; - case SECMOD_MODULE_DB_FUNCTION_RELEASE: - rvstr = (sftkdb_ReleaseSecmodDBData(dbType, appName,filename,secmod, - (char **)args,rw) == SECSuccess) ? &success: NULL; - break; - } - if (secmod) PR_smprintf_free(secmod); - if (appName) PORT_Free(appName); - if (filename) PORT_Free(filename); - return rvstr; -} - -static void nscFreeAllSlots(int moduleIndex) -{ - /* free all the slots */ - SFTKSlot *slot = NULL; - CK_SLOT_ID slotID; - int i; - - if (nscSlotList[moduleIndex]) { - CK_ULONG tmpSlotCount = nscSlotCount[moduleIndex]; - CK_SLOT_ID_PTR tmpSlotList = nscSlotList[moduleIndex]; - PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex]; - - /* first close all the session */ - for (i=0; i < (int) tmpSlotCount; i++) { - slotID = tmpSlotList[i]; - (void) NSC_CloseAllSessions(slotID); - } - - /* now clear out the statics */ - nscSlotList[moduleIndex] = NULL; - nscSlotCount[moduleIndex] = 0; - nscSlotHashTable[moduleIndex] = NULL; - nscSlotListSize[moduleIndex] = 0; - - for (i=0; i < (int) tmpSlotCount; i++) { - slotID = tmpSlotList[i]; - slot = (SFTKSlot *) - PL_HashTableLookup(tmpSlotHashTable, (void *)slotID); - PORT_Assert(slot); - if (!slot) continue; - SFTK_DestroySlotData(slot); - PL_HashTableRemove(tmpSlotHashTable, (void *)slotID); - } - PORT_Free(tmpSlotList); - PL_HashTableDestroy(tmpSlotHashTable); - } -} - -static void -sftk_closePeer(PRBool isFIPS) -{ - CK_SLOT_ID slotID = isFIPS ? PRIVATE_KEY_SLOT_ID: FIPS_SLOT_ID; - SFTKSlot *slot; - int moduleIndex = isFIPS? NSC_NON_FIPS_MODULE : NSC_FIPS_MODULE; - PLHashTable *tmpSlotHashTable = nscSlotHashTable[moduleIndex]; - - slot = (SFTKSlot *) PL_HashTableLookup(tmpSlotHashTable, (void *)slotID); - if (slot == NULL) { - return; - } - sftk_DBShutdown(slot); - return; -} - -/* NSC_Initialize initializes the Cryptoki library. */ -CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) -{ - CK_RV crv = CKR_OK; - SECStatus rv; - CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved; - int i; - int moduleIndex = isFIPS? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE; - - if (isFIPS) { - loginWaitTime = PR_SecondsToInterval(1); - } - - ENABLE_FORK_CHECK(); - - rv = SECOID_Init(); - if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - return crv; - } - - rv = RNG_RNGInit(); /* initialize random number generator */ - if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - return crv; - } - rv = BL_Init(); /* initialize freebl engine */ - if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - return crv; - } - RNG_SystemInfoForRNG(); - - - /* NOTE: - * we should be getting out mutexes from this list, not statically binding - * them from NSPR. This should happen before we allow the internal to split - * off from the rest on NSS. - */ - - /* initialize the key and cert db's */ - if (init_args && (!(init_args->flags & CKF_OS_LOCKING_OK))) { - if (init_args->CreateMutex && init_args->DestroyMutex && - init_args->LockMutex && init_args->UnlockMutex) { - /* softoken always uses NSPR (ie. OS locking), and doesn't know how - * to use the lock functions provided by the application. - */ - crv = CKR_CANT_LOCK; - return crv; - } - if (init_args->CreateMutex || init_args->DestroyMutex || - init_args->LockMutex || init_args->UnlockMutex) { - /* only some of the lock functions were provided by the - * application. This is invalid per PKCS#11 spec. - */ - crv = CKR_ARGUMENTS_BAD; - return crv; - } - } - crv = CKR_ARGUMENTS_BAD; - if ((init_args && init_args->LibraryParameters)) { - sftk_parameters paramStrings; - - crv = sftk_parseParameters - ((char *)init_args->LibraryParameters, ¶mStrings, isFIPS); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_configure(paramStrings.man, paramStrings.libdes); - if (crv != CKR_OK) { - goto loser; - } - - /* if we have a peer already open, have him close his DB's so we - * don't clobber each other. */ - if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) { - sftk_closePeer(isFIPS); - if (sftk_audit_enabled) { - if (isFIPS && nsc_init) { - sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE, - "enabled FIPS mode"); - } else { - sftk_LogAuditMessage(NSS_AUDIT_INFO, NSS_AUDIT_FIPS_STATE, - "disabled FIPS mode"); - } - } - } - - for (i=0; i < paramStrings.token_count; i++) { - crv = SFTK_SlotInit(paramStrings.configdir, - paramStrings.updatedir, paramStrings.updateID, - ¶mStrings.tokens[i], moduleIndex); - if (crv != CKR_OK) { - nscFreeAllSlots(moduleIndex); - break; - } - } -loser: - sftk_freeParams(¶mStrings); - } - if (CKR_OK == crv) { - sftk_InitFreeLists(); - } - -#ifndef NO_FORK_CHECK - if (CKR_OK == crv) { -#if defined(CHECK_FORK_MIXED) - /* Before Solaris 10, fork handlers are not unregistered at dlclose() - * time. So, we only use pthread_atfork on Solaris 10 and later. For - * earlier versions, we use PID checks. - */ - char buf[200]; - int major = 0, minor = 0; - - long rv = sysinfo(SI_RELEASE, buf, sizeof(buf)); - if (rv > 0 && rv < sizeof(buf)) { - if (2 == sscanf(buf, "%d.%d", &major, &minor)) { - /* Are we on Solaris 10 or greater ? */ - if (major >5 || (5 == major && minor >= 10)) { - /* we are safe to use pthread_atfork */ - usePthread_atfork = PR_TRUE; - } - } - } - if (usePthread_atfork) { - pthread_atfork(NULL, NULL, ForkedChild); - } else { - myPid = getpid(); - } - -#elif defined(CHECK_FORK_PTHREAD) - pthread_atfork(NULL, NULL, ForkedChild); -#elif defined(CHECK_FORK_GETPID) - myPid = getpid(); -#else -#error Incorrect fork check method. -#endif - } -#endif - return crv; -} - -CK_RV NSC_Initialize(CK_VOID_PTR pReserved) -{ - CK_RV crv; - - sftk_ForkReset(pReserved, &crv); - - if (nsc_init) { - return CKR_CRYPTOKI_ALREADY_INITIALIZED; - } - crv = nsc_CommonInitialize(pReserved,PR_FALSE); - nsc_init = (PRBool) (crv == CKR_OK); - return crv; -} - - -/* NSC_Finalize indicates that an application is done with the - * Cryptoki library.*/ -CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS) -{ - /* propagate the fork status to freebl and util */ - BL_SetForkState(parentForkedAfterC_Initialize); - UTIL_SetForkState(parentForkedAfterC_Initialize); - - nscFreeAllSlots(isFIPS ? NSC_FIPS_MODULE : NSC_NON_FIPS_MODULE); - - /* don't muck with the globals if our peer is still initialized */ - if (isFIPS && nsc_init) { - return CKR_OK; - } - if (!isFIPS && nsf_init) { - return CKR_OK; - } - - sftk_CleanupFreeLists(); - sftkdb_Shutdown(); - - /* This function does not discard all our previously aquired entropy. */ - RNG_RNGShutdown(); - - /* tell freeBL to clean up after itself */ - BL_Cleanup(); - - /* reset fork status in freebl. We must do this before BL_Unload so that - * this call doesn't force freebl to be reloaded. */ - BL_SetForkState(PR_FALSE); - - /* unload freeBL shared library from memory. This may only decrement the - * OS refcount if it's been loaded multiple times, eg. by libssl */ - BL_Unload(); - - /* clean up the default OID table */ - SECOID_Shutdown(); - - /* reset fork status in util */ - UTIL_SetForkState(PR_FALSE); - - nsc_init = PR_FALSE; - -#ifdef CHECK_FORK_MIXED - if (!usePthread_atfork) { - myPid = 0; /* allow CHECK_FORK in the next softoken initialization to - * succeed */ - } else { - forked = PR_FALSE; /* allow reinitialization */ - } -#elif defined(CHECK_FORK_GETPID) - myPid = 0; /* allow reinitialization */ -#elif defined (CHECK_FORK_PTHREAD) - forked = PR_FALSE; /* allow reinitialization */ -#endif - return CKR_OK; -} - -/* Hard-reset the entire softoken PKCS#11 module if the parent process forked - * while it was initialized. */ -PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV* crv) -{ -#ifndef NO_FORK_CHECK - if (PARENT_FORKED()) { - parentForkedAfterC_Initialize = PR_TRUE; - if (nsc_init) { - /* finalize non-FIPS token */ - *crv = nsc_CommonFinalize(pReserved, PR_FALSE); - PORT_Assert(CKR_OK == *crv); - nsc_init = (PRBool) !(*crv == CKR_OK); - } - if (nsf_init) { - /* finalize FIPS token */ - *crv = nsc_CommonFinalize(pReserved, PR_TRUE); - PORT_Assert(CKR_OK == *crv); - nsf_init = (PRBool) !(*crv == CKR_OK); - } - parentForkedAfterC_Initialize = PR_FALSE; - return PR_TRUE; - } -#endif - return PR_FALSE; -} - -/* NSC_Finalize indicates that an application is done with the - * Cryptoki library.*/ -CK_RV NSC_Finalize (CK_VOID_PTR pReserved) -{ - CK_RV crv; - - /* reset entire PKCS#11 module upon fork */ - if (sftk_ForkReset(pReserved, &crv)) { - return crv; - } - - if (!nsc_init) { - return CKR_OK; - } - - crv = nsc_CommonFinalize (pReserved, PR_FALSE); - - nsc_init = (PRBool) !(crv == CKR_OK); - - return crv; -} - -extern const char __nss_softokn_rcsid[]; -extern const char __nss_softokn_sccsid[]; - -/* NSC_GetInfo returns general information about Cryptoki. */ -CK_RV NSC_GetInfo(CK_INFO_PTR pInfo) -{ - volatile char c; /* force a reference that won't get optimized away */ - - CHECK_FORK(); - - c = __nss_softokn_rcsid[0] + __nss_softokn_sccsid[0]; - pInfo->cryptokiVersion.major = 2; - pInfo->cryptokiVersion.minor = 20; - PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32); - pInfo->libraryVersion.major = SOFTOKEN_VMAJOR; - pInfo->libraryVersion.minor = SOFTOKEN_VMINOR; - PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32); - pInfo->flags = 0; - return CKR_OK; -} - - -/* NSC_GetSlotList obtains a list of slots in the system. */ -CK_RV nsc_CommonGetSlotList(CK_BBOOL tokenPresent, - CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex) -{ - *pulCount = nscSlotCount[moduleIndex]; - if (pSlotList != NULL) { - PORT_Memcpy(pSlotList,nscSlotList[moduleIndex], - nscSlotCount[moduleIndex]*sizeof(CK_SLOT_ID)); - } - return CKR_OK; -} - -/* NSC_GetSlotList obtains a list of slots in the system. */ -CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent, - CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) -{ - CHECK_FORK(); - return nsc_CommonGetSlotList(tokenPresent, pSlotList, pulCount, - NSC_NON_FIPS_MODULE); -} - -/* NSC_GetSlotInfo obtains information about a particular slot in the system. */ -CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) -{ - SFTKSlot *slot = sftk_SlotFromID(slotID, PR_TRUE); - - CHECK_FORK(); - - if (slot == NULL) return CKR_SLOT_ID_INVALID; - - pInfo->firmwareVersion.major = 0; - pInfo->firmwareVersion.minor = 0; - - PORT_Memcpy(pInfo->manufacturerID,manufacturerID, - sizeof(pInfo->manufacturerID)); - PORT_Memcpy(pInfo->slotDescription,slot->slotDescription, - sizeof(pInfo->slotDescription)); - pInfo->flags = (slot->present) ? CKF_TOKEN_PRESENT : 0; - - /* all user defined slots are defined as removable */ - if (slotID >= SFTK_MIN_USER_SLOT_ID) { - pInfo->flags |= CKF_REMOVABLE_DEVICE; - } else { - /* In the case where we are doing a merge update, we need - * the DB slot to be removable so the token name can change - * appropriately. */ - SFTKDBHandle *handle = sftk_getKeyDB(slot); - if (handle) { - if (sftkdb_InUpdateMerge(handle)) { - pInfo->flags |= CKF_REMOVABLE_DEVICE; - } - sftk_freeDB(handle); - } - } - - /* ok we really should read it out of the keydb file. */ - /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */ - pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR; - pInfo->hardwareVersion.minor = SOFTOKEN_VMINOR; - return CKR_OK; -} - -/* - * check the current state of the 'needLogin' flag in case the database has - * been changed underneath us. - */ -static PRBool -sftk_checkNeedLogin(SFTKSlot *slot, SFTKDBHandle *keyHandle) -{ - if (sftkdb_PWCached(keyHandle) == SECSuccess) { - return slot->needLogin; - } - slot->needLogin = (PRBool)!sftk_hasNullPassword(slot, keyHandle); - return (slot->needLogin); -} - -static PRBool -sftk_isBlank(const char *s, int len) -{ - int i; - for (i=0; i < len; i++) { - if (s[i] != ' ') { - return PR_FALSE; - } - } - return PR_TRUE; -} - -/* NSC_GetTokenInfo obtains information about a particular token in - * the system. */ -CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) -{ - SFTKSlot *slot; - SFTKDBHandle *handle; - - CHECK_FORK(); - - if (!nsc_init && !nsf_init) return CKR_CRYPTOKI_NOT_INITIALIZED; - slot = sftk_SlotFromID(slotID, PR_FALSE); - if (slot == NULL) return CKR_SLOT_ID_INVALID; - - PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32); - PORT_Memcpy(pInfo->model,"NSS 3 ",16); - PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16); - PORT_Memcpy(pInfo->utcTime,"0000000000000000",16); - pInfo->ulMaxSessionCount = 0; /* arbitrarily large */ - pInfo->ulSessionCount = slot->sessionCount; - pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */ - pInfo->ulRwSessionCount = slot->rwSessionCount; - pInfo->firmwareVersion.major = 0; - pInfo->firmwareVersion.minor = 0; - PORT_Memcpy(pInfo->label,slot->tokDescription,sizeof(pInfo->label)); - handle = sftk_getKeyDB(slot); - pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS; - if (handle == NULL) { - pInfo->flags |= CKF_WRITE_PROTECTED; - pInfo->ulMaxPinLen = 0; - pInfo->ulMinPinLen = 0; - pInfo->ulTotalPublicMemory = 0; - pInfo->ulFreePublicMemory = 0; - pInfo->ulTotalPrivateMemory = 0; - pInfo->ulFreePrivateMemory = 0; - pInfo->hardwareVersion.major = 4; - pInfo->hardwareVersion.minor = 0; - } else { - /* - * we have three possible states which we may be in: - * (1) No DB password has been initialized. This also means we - * have no keys in the key db. - * (2) Password initialized to NULL. This means we have keys, but - * the user has chosen not use a password. - * (3) Finally we have an initialized password whicn is not NULL, and - * we will need to prompt for it. - */ - if (sftkdb_HasPasswordSet(handle) == SECFailure) { - pInfo->flags |= CKF_LOGIN_REQUIRED; - } else if (!sftk_checkNeedLogin(slot,handle)) { - pInfo->flags |= CKF_USER_PIN_INITIALIZED; - } else { - pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED; - /* - * if we are doing a merge style update, and we need to get the password - * of our source database (the database we are updating from), make sure we - * return a token name that will match the database we are prompting for. - */ - if (sftkdb_NeedUpdateDBPassword(handle)) { - /* if we have an update tok description, use it. otherwise - * use the updateID for this database */ - if (!sftk_isBlank(slot->updateTokDescription, - sizeof(pInfo->label))) { - PORT_Memcpy(pInfo->label,slot->updateTokDescription, - sizeof(pInfo->label)); - } else { - /* build from updateID */ - const char *updateID = sftkdb_GetUpdateID(handle); - if (updateID) { - sftk_setStringName(updateID, (char *)pInfo->label, - sizeof(pInfo->label), PR_FALSE); - } - } - } - } - pInfo->ulMaxPinLen = SFTK_MAX_PIN; - pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen; - pInfo->ulTotalPublicMemory = 1; - pInfo->ulFreePublicMemory = 1; - pInfo->ulTotalPrivateMemory = 1; - pInfo->ulFreePrivateMemory = 1; -#ifdef SHDB_FIXME - pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION; - pInfo->hardwareVersion.minor = handle->version; -#else - pInfo->hardwareVersion.major = 0; - pInfo->hardwareVersion.minor = 0; -#endif - sftk_freeDB(handle); - } - /* - * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED - * should be set - * 0 0 1 - * 1 0 0 - * 0 1 1 - * 1 1 1 - */ - if (!(pInfo->flags & CKF_LOGIN_REQUIRED) || - (pInfo->flags & CKF_USER_PIN_INITIALIZED)) { - pInfo->flags |= CKF_TOKEN_INITIALIZED; - } - return CKR_OK; -} - -/* NSC_GetMechanismList obtains a list of mechanism types - * supported by a token. */ -CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID, - CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) -{ - CK_ULONG i; - - CHECK_FORK(); - - switch (slotID) { - /* default: */ - case NETSCAPE_SLOT_ID: - *pulCount = mechanismCount; - if (pMechanismList != NULL) { - for (i=0; i < mechanismCount; i++) { - pMechanismList[i] = mechanisms[i].type; - } - } - break; - default: - *pulCount = 0; - for (i=0; i < mechanismCount; i++) { - if (mechanisms[i].privkey) { - (*pulCount)++; - if (pMechanismList != NULL) { - *pMechanismList++ = mechanisms[i].type; - } - } - } - break; - } - return CKR_OK; -} - - -/* NSC_GetMechanismInfo obtains information about a particular mechanism - * possibly supported by a token. */ -CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, - CK_MECHANISM_INFO_PTR pInfo) -{ - PRBool isPrivateKey; - CK_ULONG i; - - CHECK_FORK(); - - switch (slotID) { - case NETSCAPE_SLOT_ID: - isPrivateKey = PR_FALSE; - break; - default: - isPrivateKey = PR_TRUE; - break; - } - for (i=0; i < mechanismCount; i++) { - if (type == mechanisms[i].type) { - if (isPrivateKey && !mechanisms[i].privkey) { - return CKR_MECHANISM_INVALID; - } - PORT_Memcpy(pInfo,&mechanisms[i].info, sizeof(CK_MECHANISM_INFO)); - return CKR_OK; - } - } - return CKR_MECHANISM_INVALID; -} - -CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op) -{ - CK_ULONG i; - CK_FLAGS flags; - - switch (op) { - case CKA_ENCRYPT: flags = CKF_ENCRYPT; break; - case CKA_DECRYPT: flags = CKF_DECRYPT; break; - case CKA_WRAP: flags = CKF_WRAP; break; - case CKA_UNWRAP: flags = CKF_UNWRAP; break; - case CKA_SIGN: flags = CKF_SIGN; break; - case CKA_SIGN_RECOVER: flags = CKF_SIGN_RECOVER; break; - case CKA_VERIFY: flags = CKF_VERIFY; break; - case CKA_VERIFY_RECOVER: flags = CKF_VERIFY_RECOVER; break; - case CKA_DERIVE: flags = CKF_DERIVE; break; - default: - return CKR_ARGUMENTS_BAD; - } - for (i=0; i < mechanismCount; i++) { - if (type == mechanisms[i].type) { - return (flags & mechanisms[i].info.flags) ? CKR_OK - : CKR_MECHANISM_INVALID; - } - } - return CKR_MECHANISM_INVALID; -} - -/* NSC_InitToken initializes a token. */ -CK_RV NSC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin, - CK_ULONG ulPinLen,CK_CHAR_PTR pLabel) { - SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); - SFTKDBHandle *handle; - SFTKDBHandle *certHandle; - SECStatus rv; - unsigned int i; - SFTKObject *object; - - CHECK_FORK(); - - if (slot == NULL) return CKR_SLOT_ID_INVALID; - - /* don't initialize the database if we aren't talking to a token - * that uses the key database. - */ - if (slotID == NETSCAPE_SLOT_ID) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - /* first, delete all our loaded key and cert objects from our - * internal list. */ - PZ_Lock(slot->objectLock); - for (i=0; i < slot->sessObjHashSize; i++) { - do { - object = slot->sessObjHashTable[i]; - /* hand deque */ - /* this duplicates function of NSC_close session functions, but - * because we know that we are freeing all the sessions, we can - * do more efficient processing */ - if (object) { - slot->sessObjHashTable[i] = object->next; - - if (object->next) object->next->prev = NULL; - object->next = object->prev = NULL; - } - if (object) sftk_FreeObject(object); - } while (object != NULL); - } - slot->DB_loaded = PR_FALSE; - PZ_Unlock(slot->objectLock); - - /* then clear out the key database */ - handle = sftk_getKeyDB(slot); - if (handle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - rv = sftkdb_ResetKeyDB(handle); - sftk_freeDB(handle); - if (rv != SECSuccess) { - return CKR_DEVICE_ERROR; - } - - /* finally mark all the user certs as non-user certs */ - certHandle = sftk_getCertDB(slot); - if (certHandle == NULL) return CKR_OK; - - sftk_freeDB(certHandle); - - return CKR_OK; /*is this the right function for not implemented*/ -} - - -/* NSC_InitPIN initializes the normal user's PIN. */ -CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession, - CK_CHAR_PTR pPin, CK_ULONG ulPinLen) -{ - SFTKSession *sp = NULL; - SFTKSlot *slot; - SFTKDBHandle *handle = NULL; - char newPinStr[SFTK_MAX_PIN+1]; - SECStatus rv; - CK_RV crv = CKR_SESSION_HANDLE_INVALID; - PRBool tokenRemoved = PR_FALSE; - - CHECK_FORK(); - - sp = sftk_SessionFromHandle(hSession); - if (sp == NULL) { - goto loser; - } - - slot = sftk_SlotFromSession(sp); - if (slot == NULL) { - goto loser; - } - - handle = sftk_getKeyDB(slot); - if (handle == NULL) { - crv = CKR_PIN_LEN_RANGE; - goto loser; - } - - - if (sp->info.state != CKS_RW_SO_FUNCTIONS) { - crv = CKR_USER_NOT_LOGGED_IN; - goto loser; - } - - sftk_FreeSession(sp); - sp = NULL; - - /* make sure the pins aren't too long */ - if (ulPinLen > SFTK_MAX_PIN) { - crv = CKR_PIN_LEN_RANGE; - goto loser; - } - if (ulPinLen < (CK_ULONG)slot->minimumPinLen) { - crv = CKR_PIN_LEN_RANGE; - goto loser; - } - - if (sftkdb_HasPasswordSet(handle) != SECFailure) { - crv = CKR_DEVICE_ERROR; - goto loser; - } - - /* convert to null terminated string */ - PORT_Memcpy(newPinStr, pPin, ulPinLen); - newPinStr[ulPinLen] = 0; - - /* build the hashed pins which we pass around */ - - /* change the data base */ - rv = sftkdb_ChangePassword(handle, NULL, newPinStr, &tokenRemoved); - if (tokenRemoved) { - sftk_CloseAllSessions(slot, PR_FALSE); - } - sftk_freeDB(handle); - handle = NULL; - - /* Now update our local copy of the pin */ - if (rv == SECSuccess) { - if (ulPinLen == 0) slot->needLogin = PR_FALSE; - return CKR_OK; - } - crv = CKR_PIN_INCORRECT; - -loser: - if (sp) { - sftk_FreeSession(sp); - } - if (handle) { - sftk_freeDB(handle); - } - return crv; -} - - -/* NSC_SetPIN modifies the PIN of user that is currently logged in. */ -/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */ -CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, - CK_ULONG ulOldLen, CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen) -{ - SFTKSession *sp = NULL; - SFTKSlot *slot; - SFTKDBHandle *handle = NULL; - char newPinStr[SFTK_MAX_PIN+1],oldPinStr[SFTK_MAX_PIN+1]; - SECStatus rv; - CK_RV crv = CKR_SESSION_HANDLE_INVALID; - PRBool tokenRemoved = PR_FALSE; - - CHECK_FORK(); - - sp = sftk_SessionFromHandle(hSession); - if (sp == NULL) { - goto loser; - } - - slot = sftk_SlotFromSession(sp); - if (!slot) { - goto loser; - } - - handle = sftk_getKeyDB(slot); - if (handle == NULL) { - sftk_FreeSession(sp); - return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */ - } - - if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) { - crv = CKR_USER_NOT_LOGGED_IN; - goto loser; - } - - sftk_FreeSession(sp); - sp = NULL; - - /* make sure the pins aren't too long */ - if ((ulNewLen > SFTK_MAX_PIN) || (ulOldLen > SFTK_MAX_PIN)) { - crv = CKR_PIN_LEN_RANGE; - goto loser; - } - if (ulNewLen < (CK_ULONG)slot->minimumPinLen) { - crv = CKR_PIN_LEN_RANGE; - goto loser; - } - - - /* convert to null terminated string */ - PORT_Memcpy(newPinStr,pNewPin,ulNewLen); - newPinStr[ulNewLen] = 0; - PORT_Memcpy(oldPinStr,pOldPin,ulOldLen); - oldPinStr[ulOldLen] = 0; - - /* change the data base password */ - PR_Lock(slot->pwCheckLock); - rv = sftkdb_ChangePassword(handle, oldPinStr, newPinStr, &tokenRemoved); - if (tokenRemoved) { - sftk_CloseAllSessions(slot, PR_FALSE); - } - sftk_freeDB(handle); - handle = NULL; - if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) { - PR_Sleep(loginWaitTime); - } - PR_Unlock(slot->pwCheckLock); - - /* Now update our local copy of the pin */ - if (rv == SECSuccess) { - slot->needLogin = (PRBool)(ulNewLen != 0); - return CKR_OK; - } - crv = CKR_PIN_INCORRECT; -loser: - if (sp) { - sftk_FreeSession(sp); - } - if (handle) { - sftk_freeDB(handle); - } - return crv; -} - -/* NSC_OpenSession opens a session between an application and a token. */ -CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, - CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession) -{ - SFTKSlot *slot; - CK_SESSION_HANDLE sessionID; - SFTKSession *session; - SFTKSession *sameID; - - CHECK_FORK(); - - slot = sftk_SlotFromID(slotID, PR_FALSE); - if (slot == NULL) return CKR_SLOT_ID_INVALID; - - /* new session (we only have serial sessions) */ - session = sftk_NewSession(slotID, Notify, pApplication, - flags | CKF_SERIAL_SESSION); - if (session == NULL) return CKR_HOST_MEMORY; - - if (slot->readOnly && (flags & CKF_RW_SESSION)) { - /* NETSCAPE_SLOT_ID is Read ONLY */ - session->info.flags &= ~CKF_RW_SESSION; - } - PZ_Lock(slot->slotLock); - ++slot->sessionCount; - PZ_Unlock(slot->slotLock); - if (session->info.flags & CKF_RW_SESSION) { - PR_AtomicIncrement(&slot->rwSessionCount); - } - - do { - PZLock *lock; - do { - sessionID = (PR_AtomicIncrement(&slot->sessionIDCount) & 0xffffff) - | (slot->index << 24); - } while (sessionID == CK_INVALID_HANDLE); - lock = SFTK_SESSION_LOCK(slot,sessionID); - PZ_Lock(lock); - sftkqueue_find(sameID, sessionID, slot->head, slot->sessHashSize); - if (sameID == NULL) { - session->handle = sessionID; - sftk_update_state(slot, session); - sftkqueue_add(session, sessionID, slot->head,slot->sessHashSize); - } else { - slot->sessionIDConflict++; /* for debugging */ - } - PZ_Unlock(lock); - } while (sameID != NULL); - - *phSession = sessionID; - return CKR_OK; -} - - -/* NSC_CloseSession closes a session between an application and a token. */ -CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession) -{ - SFTKSlot *slot; - SFTKSession *session; - PRBool sessionFound; - PZLock *lock; - - CHECK_FORK(); - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - slot = sftk_SlotFromSession(session); - sessionFound = PR_FALSE; - - /* lock */ - lock = SFTK_SESSION_LOCK(slot,hSession); - PZ_Lock(lock); - if (sftkqueue_is_queued(session,hSession,slot->head,slot->sessHashSize)) { - sessionFound = PR_TRUE; - sftkqueue_delete(session,hSession,slot->head,slot->sessHashSize); - session->refCount--; /* can't go to zero while we hold the reference */ - PORT_Assert(session->refCount > 0); - } - PZ_Unlock(lock); - - if (sessionFound) { - SFTKDBHandle *handle; - handle = sftk_getKeyDB(slot); - PZ_Lock(slot->slotLock); - if (--slot->sessionCount == 0) { - slot->isLoggedIn = PR_FALSE; - if (handle) { - sftkdb_ClearPassword(handle); - } - } - PZ_Unlock(slot->slotLock); - if (handle) { - sftk_freeDB(handle); - } - if (session->info.flags & CKF_RW_SESSION) { - PR_AtomicDecrement(&slot->rwSessionCount); - } - } - - sftk_FreeSession(session); - return CKR_OK; -} - - -/* NSC_CloseAllSessions closes all sessions with a token. */ -CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID) -{ - SFTKSlot *slot; - -#ifndef NO_CHECK_FORK - /* skip fork check if we are being called from C_Initialize or C_Finalize */ - if (!parentForkedAfterC_Initialize) { - CHECK_FORK(); - } -#endif - - slot = sftk_SlotFromID(slotID, PR_FALSE); - if (slot == NULL) return CKR_SLOT_ID_INVALID; - - return sftk_CloseAllSessions(slot, PR_TRUE); -} - - - -/* NSC_GetSessionInfo obtains information about the session. */ -CK_RV NSC_GetSessionInfo(CK_SESSION_HANDLE hSession, - CK_SESSION_INFO_PTR pInfo) -{ - SFTKSession *session; - - CHECK_FORK(); - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - - PORT_Memcpy(pInfo,&session->info,sizeof(CK_SESSION_INFO)); - sftk_FreeSession(session); - return CKR_OK; -} - -/* NSC_Login logs a user into a token. */ -CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, - CK_CHAR_PTR pPin, CK_ULONG ulPinLen) -{ - SFTKSlot *slot; - SFTKSession *session; - SFTKDBHandle *handle; - CK_FLAGS sessionFlags; - SECStatus rv; - CK_RV crv; - char pinStr[SFTK_MAX_PIN+1]; - PRBool tokenRemoved = PR_FALSE; - - CHECK_FORK(); - - /* get the slot */ - slot = sftk_SlotFromSessionHandle(hSession); - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - - /* make sure the session is valid */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - sessionFlags = session->info.flags; - sftk_FreeSession(session); - session = NULL; - - /* can't log into the Netscape Slot */ - if (slot->slotID == NETSCAPE_SLOT_ID) { - return CKR_USER_TYPE_INVALID; - } - - if (slot->isLoggedIn) return CKR_USER_ALREADY_LOGGED_IN; - slot->ssoLoggedIn = PR_FALSE; - - if (ulPinLen > SFTK_MAX_PIN) return CKR_PIN_LEN_RANGE; - - /* convert to null terminated string */ - PORT_Memcpy(pinStr,pPin,ulPinLen); - pinStr[ulPinLen] = 0; - - handle = sftk_getKeyDB(slot); - if (handle == NULL) { - return CKR_USER_TYPE_INVALID; - } - - /* - * Deal with bootstrap. We allow the SSO to login in with a NULL - * password if and only if we haven't initialized the KEY DB yet. - * We only allow this on a RW session. - */ - rv = sftkdb_HasPasswordSet(handle); - if (rv == SECFailure) { - /* allow SSO's to log in only if there is not password on the - * key database */ - if (((userType == CKU_SO) && (sessionFlags & CKF_RW_SESSION)) - /* fips always needs to authenticate, even if there isn't a db */ - || (slot->slotID == FIPS_SLOT_ID)) { - /* should this be a fixed password? */ - if (ulPinLen == 0) { - sftkdb_ClearPassword(handle); - PZ_Lock(slot->slotLock); - slot->isLoggedIn = PR_TRUE; - slot->ssoLoggedIn = (PRBool)(userType == CKU_SO); - PZ_Unlock(slot->slotLock); - sftk_update_all_states(slot); - crv = CKR_OK; - goto done; - } - crv = CKR_PIN_INCORRECT; - goto done; - } - crv = CKR_USER_TYPE_INVALID; - goto done; - } - - /* don't allow the SSO to log in if the user is already initialized */ - if (userType != CKU_USER) { - crv = CKR_USER_TYPE_INVALID; - goto done; - } - - - /* build the hashed pins which we pass around */ - PR_Lock(slot->pwCheckLock); - rv = sftkdb_CheckPassword(handle,pinStr, &tokenRemoved); - if (tokenRemoved) { - sftk_CloseAllSessions(slot, PR_FALSE); - } - if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) { - PR_Sleep(loginWaitTime); - } - PR_Unlock(slot->pwCheckLock); - if (rv == SECSuccess) { - PZ_Lock(slot->slotLock); - /* make sure the login state matches the underlying - * database state */ - slot->isLoggedIn = sftkdb_PWCached(handle) == SECSuccess ? - PR_TRUE : PR_FALSE; - PZ_Unlock(slot->slotLock); - - sftk_freeDB(handle); - handle = NULL; - - /* update all sessions */ - sftk_update_all_states(slot); - return CKR_OK; - } - - crv = CKR_PIN_INCORRECT; -done: - if (handle) { - sftk_freeDB(handle); - } - return crv; -} - -/* NSC_Logout logs a user out from a token. */ -CK_RV NSC_Logout(CK_SESSION_HANDLE hSession) -{ - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - SFTKSession *session; - SFTKDBHandle *handle; - - CHECK_FORK(); - - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - sftk_FreeSession(session); - session = NULL; - - if (!slot->isLoggedIn) return CKR_USER_NOT_LOGGED_IN; - - handle = sftk_getKeyDB(slot); - PZ_Lock(slot->slotLock); - slot->isLoggedIn = PR_FALSE; - slot->ssoLoggedIn = PR_FALSE; - if (handle) { - sftkdb_ClearPassword(handle); - } - PZ_Unlock(slot->slotLock); - if (handle) { - sftk_freeDB(handle); - } - - sftk_update_all_states(slot); - return CKR_OK; -} - -/* - * Create a new slot on the fly. The slot that is passed in is the - * slot the request came from. Only the crypto or FIPS slots can - * be used. The resulting slot will live in the same module as - * the slot the request was passed to. object is the creation object - * that specifies the module spec for the new slot. - */ -static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class, - SFTKObject *object) -{ - CK_SLOT_ID idMin, idMax; - PRBool isFIPS = PR_FALSE; - unsigned long moduleIndex; - SFTKAttribute *attribute; - sftk_parameters paramStrings; - char *paramString; - CK_SLOT_ID slotID = 0; - SFTKSlot *newSlot = NULL; - CK_RV crv = CKR_OK; - - /* only the crypto or FIPS slots can create new slot objects */ - if (slot->slotID == NETSCAPE_SLOT_ID) { - idMin = SFTK_MIN_USER_SLOT_ID; - idMax = SFTK_MAX_USER_SLOT_ID; - moduleIndex = NSC_NON_FIPS_MODULE; - isFIPS = PR_FALSE; - } else if (slot->slotID == FIPS_SLOT_ID) { - idMin = SFTK_MIN_FIPS_USER_SLOT_ID; - idMax = SFTK_MAX_FIPS_USER_SLOT_ID; - moduleIndex = NSC_FIPS_MODULE; - isFIPS = PR_TRUE; - } else { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - attribute = sftk_FindAttribute(object,CKA_NETSCAPE_MODULE_SPEC); - if (attribute == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - paramString = (char *)attribute->attrib.pValue; - crv = sftk_parseParameters(paramString, ¶mStrings, isFIPS); - if (crv != CKR_OK) { - goto loser; - } - - /* enforce only one at a time */ - if (paramStrings.token_count != 1) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - goto loser; - } - - slotID = paramStrings.tokens[0].slotID; - - /* stay within the valid ID space */ - if ((slotID < idMin) || (slotID > idMax)) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - goto loser; - } - - /* unload any existing slot at this id */ - newSlot = sftk_SlotFromID(slotID, PR_TRUE); - if (newSlot && newSlot->present) { - crv = SFTK_ShutdownSlot(newSlot); - if (crv != CKR_OK) { - goto loser; - } - } - - /* if we were just planning on deleting the slot, then do so now */ - if (class == CKO_NETSCAPE_DELSLOT) { - /* sort of a unconventional use of this error code, be we are - * overusing CKR_ATTRIBUTE_VALUE_INVALID, and it does apply */ - crv = newSlot ? CKR_OK : CKR_SLOT_ID_INVALID; - goto loser; /* really exit */ - } - - if (newSlot) { - crv = SFTK_SlotReInit(newSlot, paramStrings.configdir, - paramStrings.updatedir, paramStrings.updateID, - ¶mStrings.tokens[0], moduleIndex); - } else { - crv = SFTK_SlotInit(paramStrings.configdir, - paramStrings.updatedir, paramStrings.updateID, - ¶mStrings.tokens[0], moduleIndex); - } - if (crv != CKR_OK) { - goto loser; - } -loser: - sftk_freeParams(¶mStrings); - sftk_FreeAttribute(attribute); - - return crv; -} - - -/* NSC_CreateObject creates a new object. */ -CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phObject) -{ - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - SFTKSession *session; - SFTKObject *object; - /* make sure class isn't randomly CKO_NETSCAPE_NEWSLOT or - * CKO_NETSCPE_DELSLOT. */ - CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED; - CK_RV crv; - int i; - - CHECK_FORK(); - - *phObject = CK_INVALID_HANDLE; - - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * now lets create an object to hang the attributes off of - */ - object = sftk_NewObject(slot); /* fill in the handle later */ - if (object == NULL) { - return CKR_HOST_MEMORY; - } - - /* - * load the template values into the object - */ - for (i=0; i < (int) ulCount; i++) { - crv = sftk_AddAttributeType(object,sftk_attr_expand(&pTemplate[i])); - if (crv != CKR_OK) { - sftk_FreeObject(object); - return crv; - } - if ((pTemplate[i].type == CKA_CLASS) && pTemplate[i].pValue) { - class = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; - } - } - - /* get the session */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - sftk_FreeObject(object); - return CKR_SESSION_HANDLE_INVALID; - } - - /* - * handle pseudo objects (CKO_NEWSLOT) - */ - if ((class == CKO_NETSCAPE_NEWSLOT) || (class == CKO_NETSCAPE_DELSLOT)) { - crv = sftk_CreateNewSlot(slot, class, object); - goto done; - } - - /* - * handle the base object stuff - */ - crv = sftk_handleObject(object,session); - *phObject = object->handle; -done: - sftk_FreeSession(session); - sftk_FreeObject(object); - - return crv; -} - - - -/* NSC_CopyObject copies an object, creating a new object for the copy. */ -CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phNewObject) -{ - SFTKObject *destObject,*srcObject; - SFTKSession *session; - CK_RV crv = CKR_OK; - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - int i; - - CHECK_FORK(); - - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - /* Get srcObject so we can find the class */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - srcObject = sftk_ObjectFromHandle(hObject,session); - if (srcObject == NULL) { - sftk_FreeSession(session); - return CKR_OBJECT_HANDLE_INVALID; - } - /* - * create an object to hang the attributes off of - */ - destObject = sftk_NewObject(slot); /* fill in the handle later */ - if (destObject == NULL) { - sftk_FreeSession(session); - sftk_FreeObject(srcObject); - return CKR_HOST_MEMORY; - } - - /* - * load the template values into the object - */ - for (i=0; i < (int) ulCount; i++) { - if (sftk_modifyType(pTemplate[i].type,srcObject->objclass) == SFTK_NEVER) { - crv = CKR_ATTRIBUTE_READ_ONLY; - break; - } - crv = sftk_AddAttributeType(destObject,sftk_attr_expand(&pTemplate[i])); - if (crv != CKR_OK) { break; } - } - if (crv != CKR_OK) { - sftk_FreeSession(session); - sftk_FreeObject(srcObject); - sftk_FreeObject(destObject); - return crv; - } - - /* sensitive can only be changed to CK_TRUE */ - if (sftk_hasAttribute(destObject,CKA_SENSITIVE)) { - if (!sftk_isTrue(destObject,CKA_SENSITIVE)) { - sftk_FreeSession(session); - sftk_FreeObject(srcObject); - sftk_FreeObject(destObject); - return CKR_ATTRIBUTE_READ_ONLY; - } - } - - /* - * now copy the old attributes from the new attributes - */ - /* don't create a token object if we aren't in a rw session */ - /* we need to hold the lock to copy a consistant version of - * the object. */ - crv = sftk_CopyObject(destObject,srcObject); - - destObject->objclass = srcObject->objclass; - sftk_FreeObject(srcObject); - if (crv != CKR_OK) { - sftk_FreeObject(destObject); - sftk_FreeSession(session); - return crv; - } - - crv = sftk_handleObject(destObject,session); - *phNewObject = destObject->handle; - sftk_FreeSession(session); - sftk_FreeObject(destObject); - - return crv; -} - - -/* NSC_GetObjectSize gets the size of an object in bytes. */ -CK_RV NSC_GetObjectSize(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) -{ - CHECK_FORK(); - - *pulSize = 0; - return CKR_OK; -} - - -/* NSC_GetAttributeValue obtains the value of one or more object attributes. */ -CK_RV NSC_GetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) -{ - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - SFTKSession *session; - SFTKObject *object; - SFTKAttribute *attribute; - PRBool sensitive; - CK_RV crv; - int i; - - CHECK_FORK(); - - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * make sure we're allowed - */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - - /* short circuit everything for token objects */ - if (sftk_isToken(hObject)) { - SFTKSlot *slot = sftk_SlotFromSession(session); - SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject); - SFTKDBHandle *keydb = NULL; - - if (dbHandle == NULL) { - sftk_FreeSession(session); - return CKR_OBJECT_HANDLE_INVALID; - } - - crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount); - - /* make sure we don't export any sensitive information */ - keydb = sftk_getKeyDB(slot); - if (dbHandle == keydb) { - for (i=0; i < (int) ulCount; i++) { - if (sftk_isSensitive(pTemplate[i].type,CKO_PRIVATE_KEY)) { - crv = CKR_ATTRIBUTE_SENSITIVE; - if (pTemplate[i].pValue && (pTemplate[i].ulValueLen!= -1)){ - PORT_Memset(pTemplate[i].pValue, 0, - pTemplate[i].ulValueLen); - } - pTemplate[i].ulValueLen = -1; - } - } - } - - sftk_FreeSession(session); - sftk_freeDB(dbHandle); - if (keydb) { - sftk_freeDB(keydb); - } - return crv; - } - - /* handle the session object */ - object = sftk_ObjectFromHandle(hObject,session); - sftk_FreeSession(session); - if (object == NULL) { - return CKR_OBJECT_HANDLE_INVALID; - } - - /* don't read a private object if we aren't logged in */ - if ((!slot->isLoggedIn) && (slot->needLogin) && - (sftk_isTrue(object,CKA_PRIVATE))) { - sftk_FreeObject(object); - return CKR_USER_NOT_LOGGED_IN; - } - - crv = CKR_OK; - sensitive = sftk_isTrue(object,CKA_SENSITIVE); - for (i=0; i < (int) ulCount; i++) { - /* Make sure that this attribute is retrievable */ - if (sensitive && sftk_isSensitive(pTemplate[i].type,object->objclass)) { - crv = CKR_ATTRIBUTE_SENSITIVE; - pTemplate[i].ulValueLen = -1; - continue; - } - attribute = sftk_FindAttribute(object,pTemplate[i].type); - if (attribute == NULL) { - crv = CKR_ATTRIBUTE_TYPE_INVALID; - pTemplate[i].ulValueLen = -1; - continue; - } - if (pTemplate[i].pValue != NULL) { - PORT_Memcpy(pTemplate[i].pValue,attribute->attrib.pValue, - attribute->attrib.ulValueLen); - } - pTemplate[i].ulValueLen = attribute->attrib.ulValueLen; - sftk_FreeAttribute(attribute); - } - - sftk_FreeObject(object); - return crv; -} - -/* NSC_SetAttributeValue modifies the value of one or more object attributes */ -CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) -{ - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - SFTKSession *session; - SFTKAttribute *attribute; - SFTKObject *object; - PRBool isToken; - CK_RV crv = CKR_OK; - CK_BBOOL legal; - int i; - - CHECK_FORK(); - - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * make sure we're allowed - */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - - object = sftk_ObjectFromHandle(hObject,session); - if (object == NULL) { - sftk_FreeSession(session); - return CKR_OBJECT_HANDLE_INVALID; - } - - /* don't modify a private object if we aren't logged in */ - if ((!slot->isLoggedIn) && (slot->needLogin) && - (sftk_isTrue(object,CKA_PRIVATE))) { - sftk_FreeSession(session); - sftk_FreeObject(object); - return CKR_USER_NOT_LOGGED_IN; - } - - /* don't modify a token object if we aren't in a rw session */ - isToken = sftk_isTrue(object,CKA_TOKEN); - if (((session->info.flags & CKF_RW_SESSION) == 0) && isToken) { - sftk_FreeSession(session); - sftk_FreeObject(object); - return CKR_SESSION_READ_ONLY; - } - sftk_FreeSession(session); - - /* only change modifiable objects */ - if (!sftk_isTrue(object,CKA_MODIFIABLE)) { - sftk_FreeObject(object); - return CKR_ATTRIBUTE_READ_ONLY; - } - - for (i=0; i < (int) ulCount; i++) { - /* Make sure that this attribute is changeable */ - switch (sftk_modifyType(pTemplate[i].type,object->objclass)) { - case SFTK_NEVER: - case SFTK_ONCOPY: - default: - crv = CKR_ATTRIBUTE_READ_ONLY; - break; - - case SFTK_SENSITIVE: - legal = (pTemplate[i].type == CKA_EXTRACTABLE) ? CK_FALSE : CK_TRUE; - if ((*(CK_BBOOL *)pTemplate[i].pValue) != legal) { - crv = CKR_ATTRIBUTE_READ_ONLY; - } - break; - case SFTK_ALWAYS: - break; - } - if (crv != CKR_OK) break; - - /* find the old attribute */ - attribute = sftk_FindAttribute(object,pTemplate[i].type); - if (attribute == NULL) { - crv =CKR_ATTRIBUTE_TYPE_INVALID; - break; - } - sftk_FreeAttribute(attribute); - crv = sftk_forceAttribute(object,sftk_attr_expand(&pTemplate[i])); - if (crv != CKR_OK) break; - - } - - sftk_FreeObject(object); - return crv; -} - -static CK_RV -sftk_expandSearchList(SFTKSearchResults *search, int count) -{ - search->array_size += count; - search->handles = (CK_OBJECT_HANDLE *)PORT_Realloc(search->handles, - sizeof(CK_OBJECT_HANDLE)*search->array_size); - return search->handles ? CKR_OK : CKR_HOST_MEMORY; -} - - - -static CK_RV -sftk_searchDatabase(SFTKDBHandle *handle, SFTKSearchResults *search, - const CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) -{ - CK_RV crv; - int objectListSize = search->array_size-search->size; - CK_OBJECT_HANDLE *array = &search->handles[search->size]; - SDBFind *find; - CK_ULONG count; - - crv = sftkdb_FindObjectsInit(handle, pTemplate, ulCount, &find); - if (crv != CKR_OK) - return crv; - do { - crv = sftkdb_FindObjects(handle, find, array, objectListSize, &count); - if ((crv != CKR_OK) || (count == 0)) - break; - search->size += count; - objectListSize -= count; - if (objectListSize > 0) - break; - crv = sftk_expandSearchList(search,NSC_SEARCH_BLOCK_SIZE); - objectListSize = NSC_SEARCH_BLOCK_SIZE; - array = &search->handles[search->size]; - } while (crv == CKR_OK); - sftkdb_FindObjectsFinal(handle, find); - - return crv; -} - -/* softoken used to search the SMimeEntries automatically instead of - * doing this in pk11wrap. This code should really be up in - * pk11wrap so that it will work with other tokens other than softoken. - */ -CK_RV -sftk_emailhack(SFTKSlot *slot, SFTKDBHandle *handle, - SFTKSearchResults *search, CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) -{ - PRBool isCert = PR_FALSE; - int emailIndex = -1; - int i; - SFTKSearchResults smime_search; - CK_ATTRIBUTE smime_template[2]; - CK_OBJECT_CLASS smime_class = CKO_NETSCAPE_SMIME; - SFTKAttribute *attribute = NULL; - SFTKObject *object = NULL; - CK_RV crv = CKR_OK; - - - smime_search.handles = NULL; /* paranoia, some one is bound to add a goto - * loser before this gets initialized */ - - /* see if we are looking for email certs */ - for (i=0; i < ulCount; i++) { - if (pTemplate[i].type == CKA_CLASS) { - if ((pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS) || - (*(CK_OBJECT_CLASS *)pTemplate[i].pValue) != CKO_CERTIFICATE)) { - /* not a cert, skip out */ - break; - } - isCert = PR_TRUE; - } else if (pTemplate[i].type == CKA_NETSCAPE_EMAIL) { - emailIndex = i; - - } - if (isCert && (emailIndex != -1)) break; - } - - if (!isCert || (emailIndex == -1)) { - return CKR_OK; - } - - /* we are doing a cert and email search, find the SMimeEntry */ - smime_template[0].type = CKA_CLASS; - smime_template[0].pValue = &smime_class; - smime_template[0].ulValueLen = sizeof(smime_class); - smime_template[1] = pTemplate[emailIndex]; - - smime_search.handles = (CK_OBJECT_HANDLE *) - PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE); - if (smime_search.handles == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - smime_search.index = 0; - smime_search.size = 0; - smime_search.array_size = NSC_SEARCH_BLOCK_SIZE; - - crv = sftk_searchDatabase(handle, &smime_search, smime_template, 2); - if (crv != CKR_OK || smime_search.size == 0) { - goto loser; - } - - /* get the SMime subject */ - object = sftk_NewTokenObject(slot, NULL, smime_search.handles[0]); - if (object == NULL) { - crv = CKR_HOST_MEMORY; /* is there any other reason for this failure? */ - goto loser; - } - attribute = sftk_FindAttribute(object,CKA_SUBJECT); - if (attribute == NULL) { - crv = CKR_ATTRIBUTE_TYPE_INVALID; - goto loser; - } - - /* now find the certs with that subject */ - pTemplate[emailIndex] = attribute->attrib; - /* now add the appropriate certs to the search list */ - crv = sftk_searchDatabase(handle, search, pTemplate, ulCount); - pTemplate[emailIndex] = smime_template[1]; /* restore the user's template*/ - -loser: - if (attribute) { - sftk_FreeAttribute(attribute); - } - if (object) { - sftk_FreeObject(object); - } - if (smime_search.handles) { - PORT_Free(smime_search.handles); - } - - return crv; -} - - -static CK_RV -sftk_searchTokenList(SFTKSlot *slot, SFTKSearchResults *search, - CK_ATTRIBUTE *pTemplate, CK_LONG ulCount, - PRBool *tokenOnly, PRBool isLoggedIn) -{ - CK_RV crv; - CK_RV crv2; - SFTKDBHandle *certHandle = sftk_getCertDB(slot); - - crv = sftk_searchDatabase(certHandle, search, pTemplate, ulCount); - crv2 = sftk_emailhack(slot, certHandle, search, pTemplate, ulCount); - if (crv == CKR_OK) crv2 = crv; - sftk_freeDB(certHandle); - - if (crv == CKR_OK && isLoggedIn) { - SFTKDBHandle *keyHandle = sftk_getKeyDB(slot); - crv = sftk_searchDatabase(keyHandle, search, pTemplate, ulCount); - sftk_freeDB(keyHandle); - } - return crv; -} - -/* NSC_FindObjectsInit initializes a search for token and session objects - * that match a template. */ -CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) -{ - SFTKSearchResults *search = NULL, *freeSearch = NULL; - SFTKSession *session = NULL; - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - PRBool tokenOnly = PR_FALSE; - CK_RV crv = CKR_OK; - PRBool isLoggedIn; - - CHECK_FORK(); - - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - crv = CKR_SESSION_HANDLE_INVALID; - goto loser; - } - - search = (SFTKSearchResults *)PORT_Alloc(sizeof(SFTKSearchResults)); - if (search == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - search->handles = (CK_OBJECT_HANDLE *) - PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE); - if (search->handles == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - search->index = 0; - search->size = 0; - search->array_size = NSC_SEARCH_BLOCK_SIZE; - isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn); - - crv = sftk_searchTokenList(slot, search, pTemplate, ulCount, &tokenOnly, - isLoggedIn); - if (crv != CKR_OK) { - goto loser; - } - - /* build list of found objects in the session */ - if (!tokenOnly) { - crv = sftk_searchObjectList(search, slot->sessObjHashTable, - slot->sessObjHashSize, slot->objectLock, - pTemplate, ulCount, isLoggedIn); - } - if (crv != CKR_OK) { - goto loser; - } - - if ((freeSearch = session->search) != NULL) { - session->search = NULL; - sftk_FreeSearch(freeSearch); - } - session->search = search; - sftk_FreeSession(session); - return CKR_OK; - -loser: - if (search) { - sftk_FreeSearch(search); - } - if (session) { - sftk_FreeSession(session); - } - return crv; -} - - -/* NSC_FindObjects continues a search for token and session objects - * that match a template, obtaining additional object handles. */ -CK_RV NSC_FindObjects(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount, - CK_ULONG_PTR pulObjectCount) -{ - SFTKSession *session; - SFTKSearchResults *search; - int transfer; - int left; - - CHECK_FORK(); - - *pulObjectCount = 0; - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - if (session->search == NULL) { - sftk_FreeSession(session); - return CKR_OK; - } - search = session->search; - left = session->search->size - session->search->index; - transfer = ((int)ulMaxObjectCount > left) ? left : ulMaxObjectCount; - if (transfer > 0) { - PORT_Memcpy(phObject,&search->handles[search->index], - transfer*sizeof(CK_OBJECT_HANDLE)); - } else { - *phObject = CK_INVALID_HANDLE; - } - - search->index += transfer; - if (search->index == search->size) { - session->search = NULL; - sftk_FreeSearch(search); - } - *pulObjectCount = transfer; - sftk_FreeSession(session); - return CKR_OK; -} - -/* NSC_FindObjectsFinal finishes a search for token and session objects. */ -CK_RV NSC_FindObjectsFinal(CK_SESSION_HANDLE hSession) -{ - SFTKSession *session; - SFTKSearchResults *search; - - CHECK_FORK(); - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - search = session->search; - session->search = NULL; - sftk_FreeSession(session); - if (search != NULL) { - sftk_FreeSearch(search); - } - return CKR_OK; -} - - - -CK_RV NSC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, - CK_VOID_PTR pReserved) -{ - CHECK_FORK(); - - return CKR_FUNCTION_NOT_SUPPORTED; -} - diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c deleted file mode 100644 index d45c6ff5f..000000000 --- a/security/nss/lib/softoken/pkcs11c.c +++ /dev/null @@ -1,6276 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Stephen Henson <stephen.henson@gemplus.com> - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * This file implements PKCS 11 on top of our existing security modules - * - * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. - * This implementation has two slots: - * slot 1 is our generic crypto support. It does not require login. - * It supports Public Key ops, and all they bulk ciphers and hashes. - * It can also support Private Key ops for imported Private keys. It does - * not have any token storage. - * slot 2 is our private key support. It requires a login before use. It - * can store Private Keys and Certs as token objects. Currently only private - * keys and their associated Certificates are saved on the token. - * - * In this implementation, session objects are only visible to the session - * that created or generated them. - */ -#include "seccomon.h" -#include "secitem.h" -#include "secport.h" -#include "blapi.h" -#include "pkcs11.h" -#include "pkcs11i.h" -#include "lowkeyi.h" -#include "sechash.h" -#include "secder.h" -#include "secdig.h" -#include "lowpbe.h" /* We do PBE below */ -#include "pkcs11t.h" -#include "secoid.h" -#include "alghmac.h" -#include "softoken.h" -#include "secasn1.h" -#include "secerr.h" - -#include "prprf.h" - -#define __PASTE(x,y) x##y - -/* - * we renamed all our internal functions, get the correct - * definitions for them... - */ -#undef CK_PKCS11_FUNCTION_INFO -#undef CK_NEED_ARG_LIST - -#define CK_EXTERN extern -#define CK_PKCS11_FUNCTION_INFO(func) \ - CK_RV __PASTE(NS,func) -#define CK_NEED_ARG_LIST 1 - -#include "pkcs11f.h" - -typedef struct { - uint8 client_version[2]; - uint8 random[46]; -} SSL3RSAPreMasterSecret; - -static void sftk_Null(void *data, PRBool freeit) -{ - return; -} - -#ifdef NSS_ENABLE_ECC -#ifdef EC_DEBUG -#define SEC_PRINT(str1, str2, num, sitem) \ - printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \ - str1, str2, num, sitem->len); \ - for (i = 0; i < sitem->len; i++) { \ - printf("%02x:", sitem->data[i]); \ - } \ - printf("\n") -#else -#define SEC_PRINT(a, b, c, d) -#endif -#endif /* NSS_ENABLE_ECC */ - -/* - * free routines.... Free local type allocated data, and convert - * other free routines to the destroy signature. - */ -static void -sftk_FreePrivKey(NSSLOWKEYPrivateKey *key, PRBool freeit) -{ - nsslowkey_DestroyPrivateKey(key); -} - -static void -sftk_Space(void *data, PRBool freeit) -{ - PORT_Free(data); -} - -/* - * map all the SEC_ERROR_xxx error codes that may be returned by freebl - * functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward - * compatibility. - */ -static CK_RV -sftk_MapCryptError(int error) -{ - switch (error) { - case SEC_ERROR_INVALID_ARGS: - case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */ - return CKR_ARGUMENTS_BAD; - case SEC_ERROR_INPUT_LEN: - return CKR_DATA_LEN_RANGE; - case SEC_ERROR_OUTPUT_LEN: - return CKR_BUFFER_TOO_SMALL; - case SEC_ERROR_LIBRARY_FAILURE: - return CKR_GENERAL_ERROR; - case SEC_ERROR_NO_MEMORY: - return CKR_HOST_MEMORY; - case SEC_ERROR_BAD_SIGNATURE: - return CKR_SIGNATURE_INVALID; - case SEC_ERROR_INVALID_KEY: - return CKR_KEY_SIZE_RANGE; - case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */ - return CKR_KEY_SIZE_RANGE; /* the closest error code */ - case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM: - return CKR_TEMPLATE_INCONSISTENT; - /* EC functions set this error if NSS_ENABLE_ECC is not defined */ - case SEC_ERROR_UNSUPPORTED_KEYALG: - return CKR_MECHANISM_INVALID; - case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE: - return CKR_DOMAIN_PARAMS_INVALID; - /* key pair generation failed after max number of attempts */ - case SEC_ERROR_NEED_RANDOM: - return CKR_FUNCTION_FAILED; - } - return CKR_DEVICE_ERROR; -} - -/* used by Decrypt and UnwrapKey (indirectly) */ -static CK_RV -sftk_MapDecryptError(int error) -{ - switch (error) { - case SEC_ERROR_BAD_DATA: - return CKR_ENCRYPTED_DATA_INVALID; - default: - return sftk_MapCryptError(error); - } -} - -/* - * return CKR_SIGNATURE_INVALID instead of CKR_DEVICE_ERROR by default for - * backward compatibilty. - */ -static CK_RV -sftk_MapVerifyError(int error) -{ - CK_RV crv = sftk_MapCryptError(error); - if (crv == CKR_DEVICE_ERROR) - crv = CKR_SIGNATURE_INVALID; - return crv; -} - - -/* - * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by - * Deprecating a full des key to 40 bit key strenth. - */ -static CK_RV -sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey) -{ - unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae }; - unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 }; - unsigned char enc_src[8]; - unsigned char enc_dest[8]; - unsigned int leng,i; - DESContext *descx; - SECStatus rv; - - - /* zero the parity bits */ - for (i=0; i < 8; i++) { - enc_src[i] = cdmfkey[i] & 0xfe; - } - - /* encrypt with key 1 */ - descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE); - if (descx == NULL) return CKR_HOST_MEMORY; - rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8); - DES_DestroyContext(descx,PR_TRUE); - if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError()); - - /* xor source with des, zero the parity bits and deprecate the key*/ - for (i=0; i < 8; i++) { - if (i & 1) { - enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe; - } else { - enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e; - } - } - - /* encrypt with key 2 */ - descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE); - if (descx == NULL) return CKR_HOST_MEMORY; - rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8); - DES_DestroyContext(descx,PR_TRUE); - if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError()); - - /* set the corret parity on our new des key */ - sftk_FormatDESKey(deskey, 8); - return CKR_OK; -} - - -/* NSC_DestroyObject destroys an object. */ -CK_RV -NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) -{ - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - SFTKSession *session; - SFTKObject *object; - SFTKFreeStatus status; - - CHECK_FORK(); - - if (slot == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * This whole block just makes sure we really can destroy the - * requested object. - */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - - object = sftk_ObjectFromHandle(hObject,session); - if (object == NULL) { - sftk_FreeSession(session); - return CKR_OBJECT_HANDLE_INVALID; - } - - /* don't destroy a private object if we aren't logged in */ - if ((!slot->isLoggedIn) && (slot->needLogin) && - (sftk_isTrue(object,CKA_PRIVATE))) { - sftk_FreeSession(session); - sftk_FreeObject(object); - return CKR_USER_NOT_LOGGED_IN; - } - - /* don't destroy a token object if we aren't in a rw session */ - - if (((session->info.flags & CKF_RW_SESSION) == 0) && - (sftk_isTrue(object,CKA_TOKEN))) { - sftk_FreeSession(session); - sftk_FreeObject(object); - return CKR_SESSION_READ_ONLY; - } - - sftk_DeleteObject(session,object); - - sftk_FreeSession(session); - - /* - * get some indication if the object is destroyed. Note: this is not - * 100%. Someone may have an object reference outstanding (though that - * should not be the case by here. Also note that the object is "half" - * destroyed. Our internal representation is destroyed, but it may still - * be in the data base. - */ - status = sftk_FreeObject(object); - - return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR; -} - - -/* - ************** Crypto Functions: Utilities ************************ - */ - - -/* - * return a context based on the SFTKContext type. - */ -SFTKSessionContext * -sftk_ReturnContextByType(SFTKSession *session, SFTKContextType type) -{ - switch (type) { - case SFTK_ENCRYPT: - case SFTK_DECRYPT: - return session->enc_context; - case SFTK_HASH: - return session->hash_context; - case SFTK_SIGN: - case SFTK_SIGN_RECOVER: - case SFTK_VERIFY: - case SFTK_VERIFY_RECOVER: - return session->hash_context; - } - return NULL; -} - -/* - * change a context based on the SFTKContext type. - */ -void -sftk_SetContextByType(SFTKSession *session, SFTKContextType type, - SFTKSessionContext *context) -{ - switch (type) { - case SFTK_ENCRYPT: - case SFTK_DECRYPT: - session->enc_context = context; - break; - case SFTK_HASH: - session->hash_context = context; - break; - case SFTK_SIGN: - case SFTK_SIGN_RECOVER: - case SFTK_VERIFY: - case SFTK_VERIFY_RECOVER: - session->hash_context = context; - break; - } - return; -} - -/* - * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal, - * and C_XXX function. The function takes a session handle, the context type, - * and wether or not the session needs to be multipart. It returns the context, - * and optionally returns the session pointer (if sessionPtr != NULL) if session - * pointer is returned, the caller is responsible for freeing it. - */ -static CK_RV -sftk_GetContext(CK_SESSION_HANDLE handle,SFTKSessionContext **contextPtr, - SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr) -{ - SFTKSession *session; - SFTKSessionContext *context; - - session = sftk_SessionFromHandle(handle); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - context = sftk_ReturnContextByType(session,type); - /* make sure the context is valid */ - if((context==NULL)||(context->type!=type)||(needMulti&&!(context->multi))){ - sftk_FreeSession(session); - return CKR_OPERATION_NOT_INITIALIZED; - } - *contextPtr = context; - if (sessionPtr != NULL) { - *sessionPtr = session; - } else { - sftk_FreeSession(session); - } - return CKR_OK; -} - -/* - ************** Crypto Functions: Encrypt ************************ - */ - -/* - * All the NSC_InitXXX functions have a set of common checks and processing they - * all need to do at the beginning. This is done here. - */ -static CK_RV -sftk_InitGeneric(SFTKSession *session,SFTKSessionContext **contextPtr, - SFTKContextType ctype,SFTKObject **keyPtr, - CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr, - CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation) -{ - SFTKObject *key = NULL; - SFTKAttribute *att; - SFTKSessionContext *context; - - /* We can only init if there is not current context active */ - if (sftk_ReturnContextByType(session,ctype) != NULL) { - return CKR_OPERATION_ACTIVE; - } - - /* find the key */ - if (keyPtr) { - key = sftk_ObjectFromHandle(hKey,session); - if (key == NULL) { - return CKR_KEY_HANDLE_INVALID; - } - - /* make sure it's a valid key for this operation */ - if (((key->objclass != CKO_SECRET_KEY) && (key->objclass != pubKeyType)) - || !sftk_isTrue(key,operation)) { - sftk_FreeObject(key); - return CKR_KEY_TYPE_INCONSISTENT; - } - /* get the key type */ - att = sftk_FindAttribute(key,CKA_KEY_TYPE); - if (att == NULL) { - sftk_FreeObject(key); - return CKR_KEY_TYPE_INCONSISTENT; - } - PORT_Assert(att->attrib.ulValueLen == sizeof(CK_KEY_TYPE)); - if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) { - sftk_FreeAttribute(att); - sftk_FreeObject(key); - return CKR_ATTRIBUTE_VALUE_INVALID; - } - PORT_Memcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE)); - sftk_FreeAttribute(att); - *keyPtr = key; - } - - /* allocate the context structure */ - context = (SFTKSessionContext *)PORT_Alloc(sizeof(SFTKSessionContext)); - if (context == NULL) { - if (key) sftk_FreeObject(key); - return CKR_HOST_MEMORY; - } - context->type = ctype; - context->multi = PR_TRUE; - context->cipherInfo = NULL; - context->hashInfo = NULL; - context->doPad = PR_FALSE; - context->padDataLength = 0; - context->key = key; - context->blockSize = 0; - - *contextPtr = context; - return CKR_OK; -} - -/* NSC_CryptInit initializes an encryption/Decryption operation. */ -/* This function is used by NSC_EncryptInit, NSC_DecryptInit, - * NSC_WrapKey, NSC_UnwrapKey, - * NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac), - * The only difference in their uses is the value of etype. - */ -static CK_RV -sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype, - SFTKContextType contextType, PRBool isEncrypt) -{ - SFTKSession *session; - SFTKObject *key; - SFTKSessionContext *context; - SFTKAttribute *att; - CK_RC2_CBC_PARAMS *rc2_param; -#if NSS_SOFTOKEN_DOES_RC5 - CK_RC5_CBC_PARAMS *rc5_param; - SECItem rc5Key; -#endif - CK_KEY_TYPE key_type; - CK_RV crv = CKR_OK; - unsigned effectiveKeyLength; - unsigned char newdeskey[24]; - PRBool useNewKey=PR_FALSE; - int t; - - crv = sftk_MechAllowsOperation(pMechanism->mechanism, etype); - if (crv != CKR_OK) - return crv; - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - - crv = sftk_InitGeneric(session,&context,contextType,&key,hKey,&key_type, - isEncrypt ?CKO_PUBLIC_KEY:CKO_PRIVATE_KEY, etype); - - if (crv != CKR_OK) { - sftk_FreeSession(session); - return crv; - } - - context->doPad = PR_FALSE; - switch(pMechanism->mechanism) { - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - if (key_type != CKK_RSA) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - context->multi = PR_FALSE; - if (isEncrypt) { - NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv); - if (pubKey == NULL) { - break; - } - context->maxLen = nsslowkey_PublicModulusLen(pubKey); - context->cipherInfo = (void *)pubKey; - context->update = (SFTKCipher) - (pMechanism->mechanism == CKM_RSA_X_509 - ? RSA_EncryptRaw : RSA_EncryptBlock); - } else { - NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv); - if (privKey == NULL) { - break; - } - context->maxLen = nsslowkey_PrivateModulusLen(privKey); - context->cipherInfo = (void *)privKey; - context->update = (SFTKCipher) - (pMechanism->mechanism == CKM_RSA_X_509 - ? RSA_DecryptRaw : RSA_DecryptBlock); - } - context->destroy = sftk_Null; - break; - case CKM_RC2_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_RC2_ECB: - case CKM_RC2_CBC: - context->blockSize = 8; - if (key_type != CKK_RC2) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter; - effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8; - context->cipherInfo = - RC2_CreateContext((unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen, rc2_param->iv, - pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 : - NSS_RC2_CBC,effectiveKeyLength); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->update = (SFTKCipher) (isEncrypt ? RC2_Encrypt : RC2_Decrypt); - context->destroy = (SFTKDestroy) RC2_DestroyContext; - break; -#if NSS_SOFTOKEN_DOES_RC5 - case CKM_RC5_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_RC5_ECB: - case CKM_RC5_CBC: - if (key_type != CKK_RC5) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter; - context->blockSize = rc5_param->ulWordsize*2; - rc5Key.data = (unsigned char*)att->attrib.pValue; - rc5Key.len = att->attrib.ulValueLen; - context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds, - rc5_param->ulWordsize,rc5_param->pIv, - pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->update = (SFTKCipher) (isEncrypt ? RC5_Encrypt : RC5_Decrypt); - context->destroy = (SFTKDestroy) RC5_DestroyContext; - break; -#endif - case CKM_RC4: - if (key_type != CKK_RC4) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - context->cipherInfo = - RC4_CreateContext((unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; /* WRONG !!! */ - break; - } - context->update = (SFTKCipher) (isEncrypt ? RC4_Encrypt : RC4_Decrypt); - context->destroy = (SFTKDestroy) RC4_DestroyContext; - break; - case CKM_CDMF_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_CDMF_ECB: - case CKM_CDMF_CBC: - if (key_type != CKK_CDMF) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC; - if (crv != CKR_OK) break; - goto finish_des; - case CKM_DES_ECB: - if (key_type != CKK_DES) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - t = NSS_DES; - goto finish_des; - case CKM_DES_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_DES_CBC: - if (key_type != CKK_DES) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - t = NSS_DES_CBC; - goto finish_des; - case CKM_DES3_ECB: - if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - t = NSS_DES_EDE3; - goto finish_des; - case CKM_DES3_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_DES3_CBC: - if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - t = NSS_DES_EDE3_CBC; -finish_des: - context->blockSize = 8; - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - if (key_type == CKK_DES2 && - (t == NSS_DES_EDE3_CBC || t == NSS_DES_EDE3)) { - /* extend DES2 key to DES3 key. */ - memcpy(newdeskey, att->attrib.pValue, 16); - memcpy(newdeskey + 16, newdeskey, 8); - useNewKey=PR_TRUE; - } else if (key_type == CKK_CDMF) { - crv = sftk_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey); - if (crv != CKR_OK) { - sftk_FreeAttribute(att); - break; - } - useNewKey=PR_TRUE; - } - context->cipherInfo = DES_CreateContext( - useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue, - (unsigned char*)pMechanism->pParameter,t, isEncrypt); - if (useNewKey) - memset(newdeskey, 0, sizeof newdeskey); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->update = (SFTKCipher) (isEncrypt ? DES_Encrypt : DES_Decrypt); - context->destroy = (SFTKDestroy) DES_DestroyContext; - break; - case CKM_SEED_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_SEED_CBC: - if (!pMechanism->pParameter || - pMechanism->ulParameterLen != 16) { - crv = CKR_MECHANISM_PARAM_INVALID; - break; - } - /* fall thru */ - case CKM_SEED_ECB: - context->blockSize = 16; - if (key_type != CKK_SEED) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - context->cipherInfo = SEED_CreateContext( - (unsigned char*)att->attrib.pValue, - (unsigned char*)pMechanism->pParameter, - pMechanism->mechanism == CKM_SEED_ECB ? NSS_SEED : NSS_SEED_CBC, - isEncrypt); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->update = (SFTKCipher)(isEncrypt ? SEED_Encrypt : SEED_Decrypt); - context->destroy = (SFTKDestroy) SEED_DestroyContext; - break; - - case CKM_CAMELLIA_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_CAMELLIA_CBC: - if (!pMechanism->pParameter || - pMechanism->ulParameterLen != 16) { - crv = CKR_MECHANISM_PARAM_INVALID; - break; - } - /* fall thru */ - case CKM_CAMELLIA_ECB: - context->blockSize = 16; - if (key_type != CKK_CAMELLIA) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - context->cipherInfo = Camellia_CreateContext( - (unsigned char*)att->attrib.pValue, - (unsigned char*)pMechanism->pParameter, - pMechanism->mechanism == - CKM_CAMELLIA_ECB ? NSS_CAMELLIA : NSS_CAMELLIA_CBC, - isEncrypt, att->attrib.ulValueLen); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->update = (SFTKCipher) (isEncrypt ? - Camellia_Encrypt : Camellia_Decrypt); - context->destroy = (SFTKDestroy) Camellia_DestroyContext; - break; - - case CKM_AES_CBC_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_AES_ECB: - case CKM_AES_CBC: - context->blockSize = 16; - if (key_type != CKK_AES) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - context->cipherInfo = AES_CreateContext( - (unsigned char*)att->attrib.pValue, - (unsigned char*)pMechanism->pParameter, - pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC, - isEncrypt, att->attrib.ulValueLen, 16); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->update = (SFTKCipher) (isEncrypt ? AES_Encrypt : AES_Decrypt); - context->destroy = (SFTKDestroy) AES_DestroyContext; - break; - - case CKM_NETSCAPE_AES_KEY_WRAP_PAD: - context->doPad = PR_TRUE; - /* fall thru */ - case CKM_NETSCAPE_AES_KEY_WRAP: - context->multi = PR_FALSE; - context->blockSize = 8; - if (key_type != CKK_AES) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att = sftk_FindAttribute(key,CKA_VALUE); - if (att == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - context->cipherInfo = AESKeyWrap_CreateContext( - (unsigned char*)att->attrib.pValue, - (unsigned char*)pMechanism->pParameter, - isEncrypt, att->attrib.ulValueLen); - sftk_FreeAttribute(att); - if (context->cipherInfo == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->update = (SFTKCipher) (isEncrypt ? AESKeyWrap_Encrypt - : AESKeyWrap_Decrypt); - context->destroy = (SFTKDestroy) AESKeyWrap_DestroyContext; - break; - - default: - crv = CKR_MECHANISM_INVALID; - break; - } - - if (crv != CKR_OK) { - sftk_FreeContext(context); - sftk_FreeSession(session); - return crv; - } - sftk_SetContextByType(session, contextType, context); - sftk_FreeSession(session); - return CKR_OK; -} - -/* NSC_EncryptInit initializes an encryption operation. */ -CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) -{ - CHECK_FORK(); - return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT, - SFTK_ENCRYPT, PR_TRUE); -} - -/* NSC_EncryptUpdate continues a multiple-part encryption operation. */ -CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) -{ - SFTKSessionContext *context; - unsigned int outlen,i; - unsigned int padoutlen = 0; - unsigned int maxout = *pulEncryptedPartLen; - CK_RV crv; - SECStatus rv; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL); - if (crv != CKR_OK) return crv; - - if (!pEncryptedPart) { - if (context->doPad) { - CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength; - CK_ULONG blocksToSend = totalDataAvailable/context->blockSize; - - *pulEncryptedPartLen = blocksToSend * context->blockSize; - return CKR_OK; - } - *pulEncryptedPartLen = ulPartLen; - return CKR_OK; - } - - /* do padding */ - if (context->doPad) { - /* deal with previous buffered data */ - if (context->padDataLength != 0) { - /* fill in the padded to a full block size */ - for (i=context->padDataLength; - (ulPartLen != 0) && i < context->blockSize; i++) { - context->padBuf[i] = *pPart++; - ulPartLen--; - context->padDataLength++; - } - - /* not enough data to encrypt yet? then return */ - if (context->padDataLength != context->blockSize) { - *pulEncryptedPartLen = 0; - return CKR_OK; - } - /* encrypt the current padded data */ - rv = (*context->update)(context->cipherInfo, pEncryptedPart, - &padoutlen, context->blockSize, context->padBuf, - context->blockSize); - if (rv != SECSuccess) { - return sftk_MapCryptError(PORT_GetError()); - } - pEncryptedPart += padoutlen; - maxout -= padoutlen; - } - /* save the residual */ - context->padDataLength = ulPartLen % context->blockSize; - if (context->padDataLength) { - PORT_Memcpy(context->padBuf, - &pPart[ulPartLen-context->padDataLength], - context->padDataLength); - ulPartLen -= context->padDataLength; - } - /* if we've exhausted our new buffer, we're done */ - if (ulPartLen == 0) { - *pulEncryptedPartLen = padoutlen; - return CKR_OK; - } - } - - - /* do it: NOTE: this assumes buf size in is >= buf size out! */ - rv = (*context->update)(context->cipherInfo,pEncryptedPart, - &outlen, maxout, pPart, ulPartLen); - *pulEncryptedPartLen = (CK_ULONG) (outlen + padoutlen); - return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); -} - - -/* NSC_EncryptFinal finishes a multiple-part encryption operation. */ -CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen,i; - unsigned int maxout = *pulLastEncryptedPartLen; - CK_RV crv; - SECStatus rv = SECSuccess; - PRBool contextFinished = PR_TRUE; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,&session); - if (crv != CKR_OK) return crv; - - *pulLastEncryptedPartLen = 0; - if (!pLastEncryptedPart) { - /* caller is checking the amount of remaining data */ - if (context->blockSize > 0 && context->doPad) { - *pulLastEncryptedPartLen = context->blockSize; - contextFinished = PR_FALSE; /* still have padding to go */ - } - goto finish; - } - - /* do padding */ - if (context->doPad) { - unsigned char padbyte = (unsigned char) - (context->blockSize - context->padDataLength); - /* fill out rest of pad buffer with pad magic*/ - for (i=context->padDataLength; i < context->blockSize; i++) { - context->padBuf[i] = padbyte; - } - rv = (*context->update)(context->cipherInfo,pLastEncryptedPart, - &outlen, maxout, context->padBuf, context->blockSize); - if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen; - } - -finish: - if (contextFinished) { - sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); - sftk_FreeContext(context); - } - sftk_FreeSession(session); - return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); -} - -/* NSC_Encrypt encrypts single-part data. */ -CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, - CK_ULONG_PTR pulEncryptedDataLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen; - unsigned int maxoutlen = *pulEncryptedDataLen; - CK_RV crv; - CK_RV crv2; - SECStatus rv = SECSuccess; - SECItem pText; - - pText.type = siBuffer; - pText.data = pData; - pText.len = ulDataLen; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,&session); - if (crv != CKR_OK) return crv; - - if (!pEncryptedData) { - *pulEncryptedDataLen = context->multi ? - ulDataLen + 2 * context->blockSize : context->maxLen; - goto finish; - } - - if (context->doPad) { - if (context->multi) { - CK_ULONG finalLen; - /* padding is fairly complicated, have the update and final - * code deal with it */ - sftk_FreeSession(session); - crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData, - pulEncryptedDataLen); - if (crv != CKR_OK) - *pulEncryptedDataLen = 0; - maxoutlen -= *pulEncryptedDataLen; - pEncryptedData += *pulEncryptedDataLen; - finalLen = maxoutlen; - crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen); - if (crv2 == CKR_OK) - *pulEncryptedDataLen += finalLen; - return crv == CKR_OK ? crv2 : crv; - } - /* doPad without multi means that padding must be done on the first - ** and only update. There will be no final. - */ - PORT_Assert(context->blockSize > 1); - if (context->blockSize > 1) { - CK_ULONG remainder = ulDataLen % context->blockSize; - CK_ULONG padding = context->blockSize - remainder; - pText.len += padding; - pText.data = PORT_ZAlloc(pText.len); - if (pText.data) { - memcpy(pText.data, pData, ulDataLen); - memset(pText.data + ulDataLen, padding, padding); - } else { - crv = CKR_HOST_MEMORY; - goto fail; - } - } - } - - /* do it: NOTE: this assumes buf size is big enough. */ - rv = (*context->update)(context->cipherInfo, pEncryptedData, - &outlen, maxoutlen, pText.data, pText.len); - crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); - *pulEncryptedDataLen = (CK_ULONG) outlen; - if (pText.data != pData) - PORT_ZFree(pText.data, pText.len); -fail: - sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); - sftk_FreeContext(context); -finish: - sftk_FreeSession(session); - - return crv; -} - - -/* - ************** Crypto Functions: Decrypt ************************ - */ - -/* NSC_DecryptInit initializes a decryption operation. */ -CK_RV NSC_DecryptInit( CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) -{ - CHECK_FORK(); - - return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT, - SFTK_DECRYPT, PR_FALSE); -} - -/* NSC_DecryptUpdate continues a multiple-part decryption operation. */ -CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, - CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) -{ - SFTKSessionContext *context; - unsigned int padoutlen = 0; - unsigned int outlen; - unsigned int maxout = *pulPartLen; - CK_RV crv; - SECStatus rv; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL); - if (crv != CKR_OK) return crv; - - /* this can only happen on an NSS programming error */ - PORT_Assert((context->padDataLength == 0) - || context->padDataLength == context->blockSize); - - - if (!pPart) { - if (context->doPad) { - /* we can check the data length here because if we are padding, - * then we must be using a block cipher. In the non-padding case - * the error will be returned by the underlying decryption - * function when do do the actual decrypt. We need to do the - * check here to avoid returning a negative length to the caller. - */ - if ((ulEncryptedPartLen == 0) || - (ulEncryptedPartLen % context->blockSize) != 0) { - return CKR_ENCRYPTED_DATA_LEN_RANGE; - } - *pulPartLen = - ulEncryptedPartLen + context->padDataLength - context->blockSize; - return CKR_OK; - } - /* for stream ciphers there is are no constraints on ulEncryptedPartLen. - * for block ciphers, it must be a multiple of blockSize. The error is - * detected when this function is called again do decrypt the output. - */ - *pulPartLen = ulEncryptedPartLen; - return CKR_OK; - } - - if (context->doPad) { - /* first decrypt our saved buffer */ - if (context->padDataLength != 0) { - rv = (*context->update)(context->cipherInfo, pPart, &padoutlen, - maxout, context->padBuf, context->blockSize); - if (rv != SECSuccess) return sftk_MapDecryptError(PORT_GetError()); - pPart += padoutlen; - maxout -= padoutlen; - } - /* now save the final block for the next decrypt or the final */ - PORT_Memcpy(context->padBuf,&pEncryptedPart[ulEncryptedPartLen - - context->blockSize], context->blockSize); - context->padDataLength = context->blockSize; - ulEncryptedPartLen -= context->padDataLength; - } - - /* do it: NOTE: this assumes buf size in is >= buf size out! */ - rv = (*context->update)(context->cipherInfo,pPart, &outlen, - maxout, pEncryptedPart, ulEncryptedPartLen); - *pulPartLen = (CK_ULONG) (outlen + padoutlen); - return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError()); -} - - -/* NSC_DecryptFinal finishes a multiple-part decryption operation. */ -CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen; - unsigned int maxout = *pulLastPartLen; - CK_RV crv; - SECStatus rv = SECSuccess; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session); - if (crv != CKR_OK) return crv; - - *pulLastPartLen = 0; - if (!pLastPart) { - /* caller is checking the amount of remaining data */ - if (context->padDataLength > 0) { - *pulLastPartLen = context->padDataLength; - } - rv = SECSuccess; - goto finish; - } - - if (context->doPad) { - /* decrypt our saved buffer */ - if (context->padDataLength != 0) { - /* this assumes that pLastPart is big enough to hold the *whole* - * buffer!!! */ - rv = (*context->update)(context->cipherInfo, pLastPart, &outlen, - maxout, context->padBuf, context->blockSize); - if (rv == SECSuccess) { - unsigned int padSize = - (unsigned int) pLastPart[context->blockSize-1]; - if ((padSize > context->blockSize) || (padSize == 0)) { - rv = SECFailure; - } else { - *pulLastPartLen = outlen - padSize; - } - } - } - } - - sftk_SetContextByType(session, SFTK_DECRYPT, NULL); - sftk_FreeContext(context); -finish: - sftk_FreeSession(session); - return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError()); -} - -/* NSC_Decrypt decrypts encrypted data in a single part. */ -CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData, - CK_ULONG_PTR pulDataLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen; - unsigned int maxoutlen = *pulDataLen; - CK_RV crv; - CK_RV crv2; - SECStatus rv = SECSuccess; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_FALSE,&session); - if (crv != CKR_OK) return crv; - - if (!pData) { - *pulDataLen = ulEncryptedDataLen + context->blockSize; - goto finish; - } - - if (context->doPad && context->multi) { - CK_ULONG finalLen; - /* padding is fairly complicated, have the update and final - * code deal with it */ - sftk_FreeSession(session); - crv = NSC_DecryptUpdate(hSession,pEncryptedData,ulEncryptedDataLen, - pData, pulDataLen); - if (crv != CKR_OK) - *pulDataLen = 0; - maxoutlen -= *pulDataLen; - pData += *pulDataLen; - finalLen = maxoutlen; - crv2 = NSC_DecryptFinal(hSession, pData, &finalLen); - if (crv2 == CKR_OK) - *pulDataLen += finalLen; - return crv == CKR_OK ? crv2 : crv; - } - - rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, - pEncryptedData, ulEncryptedDataLen); - /* XXX need to do MUCH better error mapping than this. */ - crv = (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError()); - if (rv == SECSuccess && context->doPad) { - CK_ULONG padding = pData[outlen - 1]; - if (padding > context->blockSize || !padding) { - crv = CKR_ENCRYPTED_DATA_INVALID; - } else - outlen -= padding; - } - *pulDataLen = (CK_ULONG) outlen; - sftk_SetContextByType(session, SFTK_DECRYPT, NULL); - sftk_FreeContext(context); -finish: - sftk_FreeSession(session); - return crv; -} - - - -/* - ************** Crypto Functions: Digest (HASH) ************************ - */ - -/* NSC_DigestInit initializes a message-digesting operation. */ -CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism) -{ - SFTKSession *session; - SFTKSessionContext *context; - CK_RV crv = CKR_OK; - - CHECK_FORK(); - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) - return CKR_SESSION_HANDLE_INVALID; - crv = sftk_InitGeneric(session,&context,SFTK_HASH,NULL,0,NULL, 0, 0); - if (crv != CKR_OK) { - sftk_FreeSession(session); - return crv; - } - - -#define INIT_MECH(mech,mmm) \ - case mech: { \ - mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \ - context->cipherInfo = (void *)mmm ## _ctx; \ - context->cipherInfoLen = mmm ## _FlattenSize(mmm ## _ctx); \ - context->currentMech = mech; \ - context->hashUpdate = (SFTKHash) mmm ## _Update; \ - context->end = (SFTKEnd) mmm ## _End; \ - context->destroy = (SFTKDestroy) mmm ## _DestroyContext; \ - context->maxLen = mmm ## _LENGTH; \ - if (mmm ## _ctx) \ - mmm ## _Begin(mmm ## _ctx); \ - else \ - crv = CKR_HOST_MEMORY; \ - break; \ - } - - switch(pMechanism->mechanism) { - INIT_MECH(CKM_MD2, MD2) - INIT_MECH(CKM_MD5, MD5) - INIT_MECH(CKM_SHA_1, SHA1) - INIT_MECH(CKM_SHA256, SHA256) - INIT_MECH(CKM_SHA384, SHA384) - INIT_MECH(CKM_SHA512, SHA512) - - default: - crv = CKR_MECHANISM_INVALID; - break; - } - - if (crv != CKR_OK) { - sftk_FreeContext(context); - sftk_FreeSession(session); - return crv; - } - sftk_SetContextByType(session, SFTK_HASH, context); - sftk_FreeSession(session); - return CKR_OK; -} - - -/* NSC_Digest digests data in a single part. */ -CK_RV NSC_Digest(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, - CK_ULONG_PTR pulDigestLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int digestLen; - unsigned int maxout = *pulDigestLen; - CK_RV crv; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_FALSE,&session); - if (crv != CKR_OK) return crv; - - if (pDigest == NULL) { - *pulDigestLen = context->maxLen; - goto finish; - } - - /* do it: */ - (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen); - /* NOTE: this assumes buf size is bigenough for the algorithm */ - (*context->end)(context->cipherInfo, pDigest, &digestLen,maxout); - *pulDigestLen = digestLen; - - sftk_SetContextByType(session, SFTK_HASH, NULL); - sftk_FreeContext(context); -finish: - sftk_FreeSession(session); - return CKR_OK; -} - - -/* NSC_DigestUpdate continues a multiple-part message-digesting operation. */ -CK_RV NSC_DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ - SFTKSessionContext *context; - CK_RV crv; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_HASH,PR_TRUE,NULL); - if (crv != CKR_OK) return crv; - /* do it: */ - (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen); - return CKR_OK; -} - - -/* NSC_DigestFinal finishes a multiple-part message-digesting operation. */ -CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest, - CK_ULONG_PTR pulDigestLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int maxout = *pulDigestLen; - unsigned int digestLen; - CK_RV crv; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session); - if (crv != CKR_OK) return crv; - - if (pDigest != NULL) { - (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout); - *pulDigestLen = digestLen; - sftk_SetContextByType(session, SFTK_HASH, NULL); - sftk_FreeContext(context); - } else { - *pulDigestLen = context->maxLen; - } - - sftk_FreeSession(session); - return CKR_OK; -} - -/* - * these helper functions are used by Generic Macing and Signing functions - * that use hashes as part of their operations. - */ -#define DOSUB(mmm) \ -static CK_RV \ -sftk_doSub ## mmm(SFTKSessionContext *context) { \ - mmm ## Context * mmm ## _ctx = mmm ## _NewContext(); \ - context->hashInfo = (void *) mmm ## _ctx; \ - context->hashUpdate = (SFTKHash) mmm ## _Update; \ - context->end = (SFTKEnd) mmm ## _End; \ - context->hashdestroy = (SFTKDestroy) mmm ## _DestroyContext; \ - if (!context->hashInfo) { \ - return CKR_HOST_MEMORY; \ - } \ - mmm ## _Begin( mmm ## _ctx ); \ - return CKR_OK; \ -} - -DOSUB(MD2) -DOSUB(MD5) -DOSUB(SHA1) -DOSUB(SHA256) -DOSUB(SHA384) -DOSUB(SHA512) - -/* - * HMAC General copies only a portion of the result. This update routine likes - * the final HMAC output with the signature. - */ -static SECStatus -sftk_HMACCopy(CK_ULONG *copyLen,unsigned char *sig,unsigned int *sigLen, - unsigned int maxLen,unsigned char *hash, unsigned int hashLen) -{ - if (maxLen < *copyLen) return SECFailure; - PORT_Memcpy(sig,hash,*copyLen); - *sigLen = *copyLen; - return SECSuccess; -} - -/* Verify is just a compare for HMAC */ -static SECStatus -sftk_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen, - unsigned char *hash, unsigned int hashLen) -{ - return (PORT_Memcmp(sig,hash,*copyLen) == 0) ? SECSuccess : SECFailure ; -} - -/* - * common HMAC initalization routine - */ -static CK_RV -sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash, - SFTKObject *key, CK_ULONG mac_size) -{ - SFTKAttribute *keyval; - HMACContext *HMACcontext; - CK_ULONG *intpointer; - const SECHashObject *hashObj = HASH_GetRawHashObject(hash); - PRBool isFIPS = (key->slot->slotID == FIPS_SLOT_ID); - - /* required by FIPS 198 Section 4 */ - if (isFIPS && (mac_size < 4 || mac_size < hashObj->length/2)) { - return CKR_BUFFER_TOO_SMALL; - } - - keyval = sftk_FindAttribute(key,CKA_VALUE); - if (keyval == NULL) return CKR_KEY_SIZE_RANGE; - - HMACcontext = HMAC_Create(hashObj, - (const unsigned char*)keyval->attrib.pValue, - keyval->attrib.ulValueLen, isFIPS); - context->hashInfo = HMACcontext; - context->multi = PR_TRUE; - sftk_FreeAttribute(keyval); - if (context->hashInfo == NULL) { - if (PORT_GetError() == SEC_ERROR_INVALID_ARGS) { - return CKR_KEY_SIZE_RANGE; - } - return CKR_HOST_MEMORY; - } - context->hashUpdate = (SFTKHash) HMAC_Update; - context->end = (SFTKEnd) HMAC_Finish; - - context->hashdestroy = (SFTKDestroy) HMAC_Destroy; - intpointer = (CK_ULONG *) PORT_Alloc(sizeof(CK_ULONG)); - if (intpointer == NULL) { - return CKR_HOST_MEMORY; - } - *intpointer = mac_size; - context->cipherInfo = (void *) intpointer; - context->destroy = (SFTKDestroy) sftk_Space; - context->update = (SFTKCipher) sftk_HMACCopy; - context->verify = (SFTKVerify) sftk_HMACCmp; - context->maxLen = hashObj->length; - HMAC_Begin(HMACcontext); - return CKR_OK; -} - -/* - * SSL Macing support. SSL Macs are inited, then update with the base - * hashing algorithm, then finalized in sign and verify - */ - -/* - * FROM SSL: - * 60 bytes is 3 times the maximum length MAC size that is supported. - * We probably should have one copy of this table. We still need this table - * in ssl to 'sign' the handshake hashes. - */ -static unsigned char ssl_pad_1 [60] = { - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36 -}; -static unsigned char ssl_pad_2 [60] = { - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c -}; - -static SECStatus -sftk_SSLMACSign(SFTKSSLMACInfo *info,unsigned char *sig,unsigned int *sigLen, - unsigned int maxLen,unsigned char *hash, unsigned int hashLen) -{ - unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH]; - unsigned int out; - - info->begin(info->hashContext); - info->update(info->hashContext,info->key,info->keySize); - info->update(info->hashContext,ssl_pad_2,info->padSize); - info->update(info->hashContext,hash,hashLen); - info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH); - PORT_Memcpy(sig,tmpBuf,info->macSize); - *sigLen = info->macSize; - return SECSuccess; -} - -static SECStatus -sftk_SSLMACVerify(SFTKSSLMACInfo *info,unsigned char *sig,unsigned int sigLen, - unsigned char *hash, unsigned int hashLen) -{ - unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH]; - unsigned int out; - - info->begin(info->hashContext); - info->update(info->hashContext,info->key,info->keySize); - info->update(info->hashContext,ssl_pad_2,info->padSize); - info->update(info->hashContext,hash,hashLen); - info->end(info->hashContext,tmpBuf,&out,SFTK_MAX_MAC_LENGTH); - return (PORT_Memcmp(sig,tmpBuf,info->macSize) == 0) ? - SECSuccess : SECFailure; -} - -/* - * common HMAC initalization routine - */ -static CK_RV -sftk_doSSLMACInit(SFTKSessionContext *context,SECOidTag oid, - SFTKObject *key, CK_ULONG mac_size) -{ - SFTKAttribute *keyval; - SFTKBegin begin; - int padSize; - SFTKSSLMACInfo *sslmacinfo; - CK_RV crv = CKR_MECHANISM_INVALID; - - if (oid == SEC_OID_SHA1) { - crv = sftk_doSubSHA1(context); - if (crv != CKR_OK) return crv; - begin = (SFTKBegin) SHA1_Begin; - padSize = 40; - } else { - crv = sftk_doSubMD5(context); - if (crv != CKR_OK) return crv; - begin = (SFTKBegin) MD5_Begin; - padSize = 48; - } - context->multi = PR_TRUE; - - keyval = sftk_FindAttribute(key,CKA_VALUE); - if (keyval == NULL) return CKR_KEY_SIZE_RANGE; - - context->hashUpdate(context->hashInfo,keyval->attrib.pValue, - keyval->attrib.ulValueLen); - context->hashUpdate(context->hashInfo,ssl_pad_1,padSize); - sslmacinfo = (SFTKSSLMACInfo *) PORT_Alloc(sizeof(SFTKSSLMACInfo)); - if (sslmacinfo == NULL) { - sftk_FreeAttribute(keyval); - return CKR_HOST_MEMORY; - } - sslmacinfo->macSize = mac_size; - sslmacinfo->hashContext = context->hashInfo; - PORT_Memcpy(sslmacinfo->key,keyval->attrib.pValue, - keyval->attrib.ulValueLen); - sslmacinfo->keySize = keyval->attrib.ulValueLen; - sslmacinfo->begin = begin; - sslmacinfo->end = context->end; - sslmacinfo->update = context->hashUpdate; - sslmacinfo->padSize = padSize; - sftk_FreeAttribute(keyval); - context->cipherInfo = (void *) sslmacinfo; - context->destroy = (SFTKDestroy) sftk_Space; - context->update = (SFTKCipher) sftk_SSLMACSign; - context->verify = (SFTKVerify) sftk_SSLMACVerify; - context->maxLen = mac_size; - return CKR_OK; -} - -/* - ************** Crypto Functions: Sign ************************ - */ - -/* - * Check if We're using CBCMacing and initialize the session context if we are. - */ -static CK_RV -sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage, - SFTKContextType contextType) - -{ - CK_MECHANISM cbc_mechanism; - CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE; - CK_RC2_CBC_PARAMS rc2_params; -#if NSS_SOFTOKEN_DOES_RC5 - CK_RC5_CBC_PARAMS rc5_params; - CK_RC5_MAC_GENERAL_PARAMS *rc5_mac; -#endif - unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE]; - SFTKSessionContext *context; - CK_RV crv; - int blockSize; - - switch (pMechanism->mechanism) { - case CKM_RC2_MAC_GENERAL: - mac_bytes = - ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength; - /* fall through */ - case CKM_RC2_MAC: - /* this works because ulEffectiveBits is in the same place in both the - * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */ - rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *) - pMechanism->pParameter)->ulEffectiveBits; - PORT_Memset(rc2_params.iv,0,sizeof(rc2_params.iv)); - cbc_mechanism.mechanism = CKM_RC2_CBC; - cbc_mechanism.pParameter = &rc2_params; - cbc_mechanism.ulParameterLen = sizeof(rc2_params); - blockSize = 8; - break; -#if NSS_SOFTOKEN_DOES_RC5 - case CKM_RC5_MAC_GENERAL: - mac_bytes = - ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength; - /* fall through */ - case CKM_RC5_MAC: - /* this works because ulEffectiveBits is in the same place in both the - * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */ - rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter; - rc5_params.ulWordsize = rc5_mac->ulWordsize; - rc5_params.ulRounds = rc5_mac->ulRounds; - rc5_params.pIv = ivBlock; - blockSize = rc5_mac->ulWordsize*2; - rc5_params.ulIvLen = blockSize; - PORT_Memset(ivBlock,0,blockSize); - cbc_mechanism.mechanism = CKM_RC5_CBC; - cbc_mechanism.pParameter = &rc5_params; - cbc_mechanism.ulParameterLen = sizeof(rc5_params); - break; -#endif - /* add cast and idea later */ - case CKM_DES_MAC_GENERAL: - mac_bytes = *(CK_ULONG *)pMechanism->pParameter; - /* fall through */ - case CKM_DES_MAC: - blockSize = 8; - PORT_Memset(ivBlock,0,blockSize); - cbc_mechanism.mechanism = CKM_DES_CBC; - cbc_mechanism.pParameter = &ivBlock; - cbc_mechanism.ulParameterLen = blockSize; - break; - case CKM_DES3_MAC_GENERAL: - mac_bytes = *(CK_ULONG *)pMechanism->pParameter; - /* fall through */ - case CKM_DES3_MAC: - blockSize = 8; - PORT_Memset(ivBlock,0,blockSize); - cbc_mechanism.mechanism = CKM_DES3_CBC; - cbc_mechanism.pParameter = &ivBlock; - cbc_mechanism.ulParameterLen = blockSize; - break; - case CKM_CDMF_MAC_GENERAL: - mac_bytes = *(CK_ULONG *)pMechanism->pParameter; - /* fall through */ - case CKM_CDMF_MAC: - blockSize = 8; - PORT_Memset(ivBlock,0,blockSize); - cbc_mechanism.mechanism = CKM_CDMF_CBC; - cbc_mechanism.pParameter = &ivBlock; - cbc_mechanism.ulParameterLen = blockSize; - break; - case CKM_SEED_MAC_GENERAL: - mac_bytes = *(CK_ULONG *)pMechanism->pParameter; - /* fall through */ - case CKM_SEED_MAC: - blockSize = 16; - PORT_Memset(ivBlock,0,blockSize); - cbc_mechanism.mechanism = CKM_SEED_CBC; - cbc_mechanism.pParameter = &ivBlock; - cbc_mechanism.ulParameterLen = blockSize; - break; - case CKM_CAMELLIA_MAC_GENERAL: - mac_bytes = *(CK_ULONG *)pMechanism->pParameter; - /* fall through */ - case CKM_CAMELLIA_MAC: - blockSize = 16; - PORT_Memset(ivBlock,0,blockSize); - cbc_mechanism.mechanism = CKM_CAMELLIA_CBC; - cbc_mechanism.pParameter = &ivBlock; - cbc_mechanism.ulParameterLen = blockSize; - break; - case CKM_AES_MAC_GENERAL: - mac_bytes = *(CK_ULONG *)pMechanism->pParameter; - /* fall through */ - case CKM_AES_MAC: - blockSize = 16; - PORT_Memset(ivBlock,0,blockSize); - cbc_mechanism.mechanism = CKM_AES_CBC; - cbc_mechanism.pParameter = &ivBlock; - cbc_mechanism.ulParameterLen = blockSize; - break; - default: - return CKR_FUNCTION_NOT_SUPPORTED; - } - - crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey, keyUsage, - contextType, PR_TRUE); - if (crv != CKR_OK) return crv; - crv = sftk_GetContext(hSession,&context,contextType,PR_TRUE,NULL); - - /* this shouldn't happen! */ - PORT_Assert(crv == CKR_OK); - if (crv != CKR_OK) return crv; - context->blockSize = blockSize; - if (mac_bytes == SFTK_INVALID_MAC_SIZE) mac_bytes = blockSize/2; - context->macSize = mac_bytes; - return CKR_OK; -} - -/* - * encode RSA PKCS #1 Signature data before signing... - */ -static SECStatus -sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, - unsigned int maxLen,unsigned char *hash, unsigned int hashLen) -{ - return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen, - hash,hashLen); -} - -/* XXX Old template; want to expunge it eventually. */ -static DERTemplate SECAlgorithmIDTemplate[] = { - { DER_SEQUENCE, - 0, NULL, sizeof(SECAlgorithmID) }, - { DER_OBJECT_ID, - offsetof(SECAlgorithmID,algorithm), }, - { DER_OPTIONAL | DER_ANY, - offsetof(SECAlgorithmID,parameters), }, - { 0, } -}; - -/* - * XXX OLD Template. Once all uses have been switched over to new one, - * remove this. - */ -static DERTemplate SGNDigestInfoTemplate[] = { - { DER_SEQUENCE, - 0, NULL, sizeof(SGNDigestInfo) }, - { DER_INLINE, - offsetof(SGNDigestInfo,digestAlgorithm), - SECAlgorithmIDTemplate, }, - { DER_OCTET_STRING, - offsetof(SGNDigestInfo,digest), }, - { 0, } -}; - -SECStatus -RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key, - unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, - unsigned char *hash, unsigned int hashLen) -{ - - SECStatus rv = SECFailure; - SECItem digder; - PLArenaPool *arena = NULL; - SGNDigestInfo *di = NULL; - - digder.data = NULL; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( !arena ) { goto loser; } - - /* Construct digest info */ - di = SGN_CreateDigestInfo(hashOid, hash, hashLen); - if (!di) { goto loser; } - - /* Der encode the digest as a DigestInfo */ - rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di); - if (rv != SECSuccess) { - goto loser; - } - - /* - ** Encrypt signature after constructing appropriate PKCS#1 signature - ** block - */ - rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len); - - loser: - SGN_DestroyDigestInfo(di); - if (arena != NULL) { - PORT_FreeArena(arena, PR_FALSE); - } - return rv; -} - -static SECStatus -nsc_DSA_Verify_Stub(void *ctx, void *sigBuf, unsigned int sigLen, - void *dataBuf, unsigned int dataLen) -{ - SECItem signature, digest; - NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx; - - signature.data = (unsigned char *)sigBuf; - signature.len = sigLen; - digest.data = (unsigned char *)dataBuf; - digest.len = dataLen; - return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest); -} - -static SECStatus -nsc_DSA_Sign_Stub(void *ctx, void *sigBuf, - unsigned int *sigLen, unsigned int maxSigLen, - void *dataBuf, unsigned int dataLen) -{ - SECItem signature, digest; - SECStatus rv; - NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx; - - signature.data = (unsigned char *)sigBuf; - signature.len = maxSigLen; - digest.data = (unsigned char *)dataBuf; - digest.len = dataLen; - rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest); - if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - *sigLen = signature.len; - return rv; -} - -#ifdef NSS_ENABLE_ECC -static SECStatus -nsc_ECDSAVerifyStub(void *ctx, void *sigBuf, unsigned int sigLen, - void *dataBuf, unsigned int dataLen) -{ - SECItem signature, digest; - NSSLOWKEYPublicKey *key = (NSSLOWKEYPublicKey *)ctx; - - signature.data = (unsigned char *)sigBuf; - signature.len = sigLen; - digest.data = (unsigned char *)dataBuf; - digest.len = dataLen; - return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest); -} - -static SECStatus -nsc_ECDSASignStub(void *ctx, void *sigBuf, - unsigned int *sigLen, unsigned int maxSigLen, - void *dataBuf, unsigned int dataLen) -{ - SECItem signature, digest; - SECStatus rv; - NSSLOWKEYPrivateKey *key = (NSSLOWKEYPrivateKey *)ctx; - - signature.data = (unsigned char *)sigBuf; - signature.len = maxSigLen; - digest.data = (unsigned char *)dataBuf; - digest.len = dataLen; - rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest); - if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - *sigLen = signature.len; - return rv; -} -#endif /* NSS_ENABLE_ECC */ - -/* NSC_SignInit setups up the signing operations. There are three basic - * types of signing: - * (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied - * to data in a single Sign operation (which often looks a lot like an - * encrypt, with data coming in and data going out). - * (2) Hash based signing, where we continually hash the data, then apply - * some sort of signature to the end. - * (3) Block Encryption CBC MAC's, where the Data is encrypted with a key, - * and only the final block is part of the mac. - * - * For case number 3, we initialize a context much like the Encryption Context - * (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and - * C_Final by the following method... if it's not multi-part, and it's doesn't - * have a hash context, it must be a block Encryption CBC MAC. - * - * For case number 2, we initialize a hash structure, as well as make it - * multi-part. Updates are simple calls to the hash update function. Final - * calls the hashend, then passes the result to the 'update' function (which - * operates as a final signature function). In some hash based MAC'ing (as - * opposed to hash base signatures), the update function is can be simply a - * copy (as is the case with HMAC). - */ -CK_RV NSC_SignInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) -{ - SFTKSession *session; - SFTKObject *key; - SFTKSessionContext *context; - CK_KEY_TYPE key_type; - CK_RV crv = CKR_OK; - NSSLOWKEYPrivateKey *privKey; - SFTKHashSignInfo *info = NULL; - - CHECK_FORK(); - - /* Block Cipher MACing Algorithms use a different Context init method..*/ - crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, SFTK_SIGN); - if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv; - - /* we're not using a block cipher mac */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - crv = sftk_InitGeneric(session,&context,SFTK_SIGN,&key,hKey,&key_type, - CKO_PRIVATE_KEY,CKA_SIGN); - if (crv != CKR_OK) { - sftk_FreeSession(session); - return crv; - } - - context->multi = PR_FALSE; - -#define INIT_RSA_SIGN_MECH(mmm) \ - case CKM_ ## mmm ## _RSA_PKCS: \ - context->multi = PR_TRUE; \ - crv = sftk_doSub ## mmm (context); \ - if (crv != CKR_OK) break; \ - context->update = (SFTKCipher) sftk_HashSign; \ - info = PORT_New(SFTKHashSignInfo); \ - if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \ - info->hashOid = SEC_OID_ ## mmm ; \ - goto finish_rsa; - - switch(pMechanism->mechanism) { - INIT_RSA_SIGN_MECH(MD5) - INIT_RSA_SIGN_MECH(MD2) - INIT_RSA_SIGN_MECH(SHA1) - INIT_RSA_SIGN_MECH(SHA256) - INIT_RSA_SIGN_MECH(SHA384) - INIT_RSA_SIGN_MECH(SHA512) - - case CKM_RSA_PKCS: - context->update = (SFTKCipher) RSA_Sign; - goto finish_rsa; - case CKM_RSA_X_509: - context->update = (SFTKCipher) RSA_SignRaw; -finish_rsa: - if (key_type != CKK_RSA) { - if (info) PORT_Free(info); - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - privKey = sftk_GetPrivKey(key,CKK_RSA,&crv); - if (privKey == NULL) { - if (info) PORT_Free(info); - break; - } - /* OK, info is allocated only if we're doing hash and sign mechanism. - * It's necessary to be able to set the correct OID in the final - * signature. - */ - if (info) { - info->key = privKey; - context->cipherInfo = info; - context->destroy = (SFTKDestroy)sftk_Space; - } else { - context->cipherInfo = privKey; - context->destroy = (SFTKDestroy)sftk_Null; - } - context->maxLen = nsslowkey_PrivateModulusLen(privKey); - break; - - case CKM_DSA_SHA1: - context->multi = PR_TRUE; - crv = sftk_doSubSHA1(context); - if (crv != CKR_OK) break; - /* fall through */ - case CKM_DSA: - if (key_type != CKK_DSA) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - privKey = sftk_GetPrivKey(key,CKK_DSA,&crv); - if (privKey == NULL) { - break; - } - context->cipherInfo = privKey; - context->update = (SFTKCipher) nsc_DSA_Sign_Stub; - context->destroy = (privKey == key->objectInfo) ? - (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey; - context->maxLen = DSA_SIGNATURE_LEN; - - break; - -#ifdef NSS_ENABLE_ECC - case CKM_ECDSA_SHA1: - context->multi = PR_TRUE; - crv = sftk_doSubSHA1(context); - if (crv != CKR_OK) break; - /* fall through */ - case CKM_ECDSA: - if (key_type != CKK_EC) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - privKey = sftk_GetPrivKey(key,CKK_EC,&crv); - if (privKey == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->cipherInfo = privKey; - context->update = (SFTKCipher) nsc_ECDSASignStub; - context->destroy = (privKey == key->objectInfo) ? - (SFTKDestroy) sftk_Null:(SFTKDestroy)sftk_FreePrivKey; - context->maxLen = MAX_ECKEY_LEN * 2; - - break; -#endif /* NSS_ENABLE_ECC */ - -#define INIT_HMAC_MECH(mmm) \ - case CKM_ ## mmm ## _HMAC_GENERAL: \ - crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, \ - *(CK_ULONG *)pMechanism->pParameter); \ - break; \ - case CKM_ ## mmm ## _HMAC: \ - crv = sftk_doHMACInit(context, HASH_Alg ## mmm ,key, mmm ## _LENGTH); \ - break; - - INIT_HMAC_MECH(MD2) - INIT_HMAC_MECH(MD5) - INIT_HMAC_MECH(SHA256) - INIT_HMAC_MECH(SHA384) - INIT_HMAC_MECH(SHA512) - - case CKM_SHA_1_HMAC_GENERAL: - crv = sftk_doHMACInit(context,HASH_AlgSHA1,key, - *(CK_ULONG *)pMechanism->pParameter); - break; - case CKM_SHA_1_HMAC: - crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH); - break; - - case CKM_SSL3_MD5_MAC: - crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key, - *(CK_ULONG *)pMechanism->pParameter); - break; - case CKM_SSL3_SHA1_MAC: - crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key, - *(CK_ULONG *)pMechanism->pParameter); - break; - case CKM_TLS_PRF_GENERAL: - crv = sftk_TLSPRFInit(context, key, key_type); - break; - default: - crv = CKR_MECHANISM_INVALID; - break; - } - - if (crv != CKR_OK) { - sftk_FreeContext(context); - sftk_FreeSession(session); - return crv; - } - sftk_SetContextByType(session, SFTK_SIGN, context); - sftk_FreeSession(session); - return CKR_OK; -} - - -/* MACUpdate is the common implementation for SignUpdate and VerifyUpdate. - * (sign and verify only very in their setup and final operations) */ -static CK_RV -sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, - CK_ULONG ulPartLen,SFTKContextType type) -{ - unsigned int outlen; - SFTKSessionContext *context; - CK_RV crv; - SECStatus rv; - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,type,PR_TRUE,NULL); - if (crv != CKR_OK) return crv; - - if (context->hashInfo) { - (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen); - return CKR_OK; - } - - /* must be block cipher macing */ - - /* deal with previous buffered data */ - if (context->padDataLength != 0) { - int i; - /* fill in the padded to a full block size */ - for (i=context->padDataLength; (ulPartLen != 0) && - i < (int)context->blockSize; i++) { - context->padBuf[i] = *pPart++; - ulPartLen--; - context->padDataLength++; - } - - /* not enough data to encrypt yet? then return */ - if (context->padDataLength != context->blockSize) return CKR_OK; - /* encrypt the current padded data */ - rv = (*context->update)(context->cipherInfo,context->macBuf,&outlen, - SFTK_MAX_BLOCK_SIZE,context->padBuf,context->blockSize); - if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError()); - } - - /* save the residual */ - context->padDataLength = ulPartLen % context->blockSize; - if (context->padDataLength) { - PORT_Memcpy(context->padBuf, - &pPart[ulPartLen-context->padDataLength], - context->padDataLength); - ulPartLen -= context->padDataLength; - } - - /* if we've exhausted our new buffer, we're done */ - if (ulPartLen == 0) { return CKR_OK; } - - /* run the data through out encrypter */ - while (ulPartLen) { - rv = (*context->update)(context->cipherInfo, context->padBuf, &outlen, - SFTK_MAX_BLOCK_SIZE, pPart, context->blockSize); - if (rv != SECSuccess) return sftk_MapCryptError(PORT_GetError()); - /* paranoia.. make sure we exit the loop */ - PORT_Assert(ulPartLen >= context->blockSize); - if (ulPartLen < context->blockSize) break; - ulPartLen -= context->blockSize; - } - - return CKR_OK; - -} - -/* NSC_SignUpdate continues a multiple-part signature operation, - * where the signature is (will be) an appendix to the data, - * and plaintext cannot be recovered from the signature */ -CK_RV NSC_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ - CHECK_FORK(); - - return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN); -} - - -/* NSC_SignFinal finishes a multiple-part signature operation, - * returning the signature. */ -CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen; - unsigned int digestLen; - unsigned int maxoutlen = *pulSignatureLen; - unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH]; - CK_RV crv; - SECStatus rv = SECSuccess; - - CHECK_FORK(); - - /* make sure we're legal */ - *pulSignatureLen = 0; - crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_TRUE,&session); - if (crv != CKR_OK) return crv; - - if (!pSignature) { - *pulSignatureLen = context->maxLen; - goto finish; - } else if (context->hashInfo) { - (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf)); - rv = (*context->update)(context->cipherInfo, pSignature, - &outlen, maxoutlen, tmpbuf, digestLen); - *pulSignatureLen = (CK_ULONG) outlen; - } else { - /* deal with the last block if any residual */ - if (context->padDataLength) { - /* fill out rest of pad buffer with pad magic*/ - int i; - for (i=context->padDataLength; i < (int)context->blockSize; i++) { - context->padBuf[i] = 0; - } - rv = (*context->update)(context->cipherInfo,context->macBuf, - &outlen,SFTK_MAX_BLOCK_SIZE,context->padBuf,context->blockSize); - } - if (rv == SECSuccess) { - PORT_Memcpy(pSignature,context->macBuf,context->macSize); - *pulSignatureLen = context->macSize; - } - } - - sftk_FreeContext(context); - sftk_SetContextByType(session, SFTK_SIGN, NULL); - -finish: - sftk_FreeSession(session); - - return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); -} - -/* NSC_Sign signs (encrypts with private key) data in a single part, - * where the signature is (will be) an appendix to the data, - * and plaintext cannot be recovered from the signature */ -CK_RV NSC_Sign(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature, - CK_ULONG_PTR pulSignatureLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen; - unsigned int maxoutlen = *pulSignatureLen; - CK_RV crv,crv2; - SECStatus rv = SECSuccess; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_SIGN,PR_FALSE,&session); - if (crv != CKR_OK) return crv; - - if (!pSignature) { - *pulSignatureLen = context->maxLen; - goto finish; - } - - /* multi part Signing are completely implemented by SignUpdate and - * sign Final */ - if (context->multi) { - sftk_FreeSession(session); - crv = NSC_SignUpdate(hSession,pData,ulDataLen); - if (crv != CKR_OK) *pulSignatureLen = 0; - crv2 = NSC_SignFinal(hSession, pSignature, pulSignatureLen); - return crv == CKR_OK ? crv2 :crv; - } - - rv = (*context->update)(context->cipherInfo, pSignature, - &outlen, maxoutlen, pData, ulDataLen); - *pulSignatureLen = (CK_ULONG) outlen; - sftk_FreeContext(context); - sftk_SetContextByType(session, SFTK_SIGN, NULL); - -finish: - sftk_FreeSession(session); - - return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); -} - - -/* - ************** Crypto Functions: Sign Recover ************************ - */ -/* NSC_SignRecoverInit initializes a signature operation, - * where the (digest) data can be recovered from the signature. - * E.g. encryption with the user's private key */ -CK_RV NSC_SignRecoverInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) -{ - CHECK_FORK(); - - switch (pMechanism->mechanism) { - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - return NSC_SignInit(hSession,pMechanism,hKey); - default: - break; - } - return CKR_MECHANISM_INVALID; -} - - -/* NSC_SignRecover signs data in a single operation - * where the (digest) data can be recovered from the signature. - * E.g. encryption with the user's private key */ -CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) -{ - CHECK_FORK(); - - return NSC_Sign(hSession,pData,ulDataLen,pSignature,pulSignatureLen); -} - -/* - ************** Crypto Functions: verify ************************ - */ - -/* Handle RSA Signature formatting */ -static SECStatus -sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, - unsigned int sigLen, unsigned char *digest, unsigned int digestLen) -{ - return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, - digest, digestLen); -} - -SECStatus -RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key, - unsigned char *sig, unsigned int sigLen, - unsigned char *digest, unsigned int digestLen) -{ - - SECItem it; - SGNDigestInfo *di = NULL; - SECStatus rv = SECSuccess; - - it.data = NULL; - - if (key == NULL) goto loser; - - it.len = nsslowkey_PublicModulusLen(key); - if (!it.len) goto loser; - - it.data = (unsigned char *) PORT_Alloc(it.len); - if (it.data == NULL) goto loser; - - /* decrypt the block */ - rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen); - if (rv != SECSuccess) goto loser; - - di = SGN_DecodeDigestInfo(&it); - if (di == NULL) goto loser; - if (di->digest.len != digestLen) goto loser; - - /* make sure the tag is OK */ - if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) { - goto loser; - } - /* make sure the "parameters" are not too bogus. */ - if (di->digestAlgorithm.parameters.len > 2) { - goto loser; - } - /* Now check the signature */ - if (PORT_Memcmp(digest, di->digest.data, di->digest.len) == 0) { - goto done; - } - - loser: - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - rv = SECFailure; - - done: - if (it.data != NULL) PORT_Free(it.data); - if (di != NULL) SGN_DestroyDigestInfo(di); - - return rv; -} - -/* NSC_VerifyInit initializes a verification operation, - * where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature (e.g. DSA) */ -CK_RV NSC_VerifyInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) -{ - SFTKSession *session; - SFTKObject *key; - SFTKSessionContext *context; - CK_KEY_TYPE key_type; - CK_RV crv = CKR_OK; - NSSLOWKEYPublicKey *pubKey; - SFTKHashVerifyInfo *info = NULL; - - CHECK_FORK(); - - /* Block Cipher MACing Algorithms use a different Context init method..*/ - crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY, SFTK_VERIFY); - if (crv != CKR_FUNCTION_NOT_SUPPORTED) return crv; - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - crv = sftk_InitGeneric(session,&context,SFTK_VERIFY,&key,hKey,&key_type, - CKO_PUBLIC_KEY,CKA_VERIFY); - if (crv != CKR_OK) { - sftk_FreeSession(session); - return crv; - } - - context->multi = PR_FALSE; - -#define INIT_RSA_VFY_MECH(mmm) \ - case CKM_ ## mmm ## _RSA_PKCS: \ - context->multi = PR_TRUE; \ - crv = sftk_doSub ## mmm (context); \ - if (crv != CKR_OK) break; \ - context->verify = (SFTKVerify) sftk_hashCheckSign; \ - info = PORT_New(SFTKHashVerifyInfo); \ - if (info == NULL) { crv = CKR_HOST_MEMORY; break; } \ - info->hashOid = SEC_OID_ ## mmm ; \ - goto finish_rsa; - - switch(pMechanism->mechanism) { - INIT_RSA_VFY_MECH(MD5) - INIT_RSA_VFY_MECH(MD2) - INIT_RSA_VFY_MECH(SHA1) - INIT_RSA_VFY_MECH(SHA256) - INIT_RSA_VFY_MECH(SHA384) - INIT_RSA_VFY_MECH(SHA512) - - case CKM_RSA_PKCS: - context->verify = (SFTKVerify) RSA_CheckSign; - goto finish_rsa; - case CKM_RSA_X_509: - context->verify = (SFTKVerify) RSA_CheckSignRaw; -finish_rsa: - if (key_type != CKK_RSA) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - pubKey = sftk_GetPubKey(key,CKK_RSA,&crv); - if (pubKey == NULL) { - break; - } - if (info) { - info->key = pubKey; - context->cipherInfo = info; - context->destroy = sftk_Space; - } else { - context->cipherInfo = pubKey; - context->destroy = sftk_Null; - } - break; - case CKM_DSA_SHA1: - context->multi = PR_TRUE; - crv = sftk_doSubSHA1(context); - if (crv != CKR_OK) break; - /* fall through */ - case CKM_DSA: - if (key_type != CKK_DSA) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - pubKey = sftk_GetPubKey(key,CKK_DSA,&crv); - if (pubKey == NULL) { - break; - } - context->cipherInfo = pubKey; - context->verify = (SFTKVerify) nsc_DSA_Verify_Stub; - context->destroy = sftk_Null; - break; -#ifdef NSS_ENABLE_ECC - case CKM_ECDSA_SHA1: - context->multi = PR_TRUE; - crv = sftk_doSubSHA1(context); - if (crv != CKR_OK) break; - /* fall through */ - case CKM_ECDSA: - if (key_type != CKK_EC) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - pubKey = sftk_GetPubKey(key,CKK_EC,&crv); - if (pubKey == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - context->cipherInfo = pubKey; - context->verify = (SFTKVerify) nsc_ECDSAVerifyStub; - context->destroy = sftk_Null; - break; -#endif /* NSS_ENABLE_ECC */ - - INIT_HMAC_MECH(MD2) - INIT_HMAC_MECH(MD5) - INIT_HMAC_MECH(SHA256) - INIT_HMAC_MECH(SHA384) - INIT_HMAC_MECH(SHA512) - - case CKM_SHA_1_HMAC_GENERAL: - crv = sftk_doHMACInit(context,HASH_AlgSHA1,key, - *(CK_ULONG *)pMechanism->pParameter); - break; - case CKM_SHA_1_HMAC: - crv = sftk_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH); - break; - - case CKM_SSL3_MD5_MAC: - crv = sftk_doSSLMACInit(context,SEC_OID_MD5,key, - *(CK_ULONG *)pMechanism->pParameter); - break; - case CKM_SSL3_SHA1_MAC: - crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key, - *(CK_ULONG *)pMechanism->pParameter); - break; - case CKM_TLS_PRF_GENERAL: - crv = sftk_TLSPRFInit(context, key, key_type); - break; - - default: - crv = CKR_MECHANISM_INVALID; - break; - } - - if (crv != CKR_OK) { - if (info) PORT_Free(info); - PORT_Free(context); - sftk_FreeSession(session); - return crv; - } - sftk_SetContextByType(session, SFTK_VERIFY, context); - sftk_FreeSession(session); - return CKR_OK; -} - -/* NSC_Verify verifies a signature in a single-part operation, - * where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature */ -CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, - CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - CK_RV crv, crv2; - SECStatus rv; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session); - if (crv != CKR_OK) return crv; - - /* multi part Verifying are completely implemented by VerifyUpdate and - * VerifyFinal */ - if (context->multi) { - sftk_FreeSession(session); - crv = NSC_VerifyUpdate(hSession, pData, ulDataLen); - crv2 = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen); - return crv == CKR_OK ? crv2 :crv; - } - - rv = (*context->verify)(context->cipherInfo,pSignature, ulSignatureLen, - pData, ulDataLen); - sftk_FreeContext(context); - sftk_SetContextByType(session, SFTK_VERIFY, NULL); - sftk_FreeSession(session); - - return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError()); - -} - - -/* NSC_VerifyUpdate continues a multiple-part verification operation, - * where the signature is an appendix to the data, - * and plaintext cannot be recovered from the signature */ -CK_RV NSC_VerifyUpdate( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen) -{ - CHECK_FORK(); - - return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY); -} - - -/* NSC_VerifyFinal finishes a multiple-part verification operation, - * checking the signature. */ -CK_RV NSC_VerifyFinal(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen; - unsigned int digestLen; - unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH]; - CK_RV crv; - SECStatus rv = SECSuccess; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_TRUE,&session); - if (crv != CKR_OK) return crv; - - if (context->hashInfo) { - (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf)); - rv = (*context->verify)(context->cipherInfo, pSignature, - ulSignatureLen, tmpbuf, digestLen); - } else { - if (context->padDataLength) { - /* fill out rest of pad buffer with pad magic*/ - int i; - for (i=context->padDataLength; i < (int)context->blockSize; i++) { - context->padBuf[i] = 0; - } - rv = (*context->update)(context->cipherInfo,context->macBuf, - &outlen,SFTK_MAX_BLOCK_SIZE,context->padBuf,context->blockSize); - } - if (rv == SECSuccess) { - rv =(PORT_Memcmp(pSignature,context->macBuf,context->macSize) == 0) - ? SECSuccess : SECFailure; - } - } - - sftk_FreeContext(context); - sftk_SetContextByType(session, SFTK_VERIFY, NULL); - sftk_FreeSession(session); - return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError()); - -} - -/* - ************** Crypto Functions: Verify Recover ************************ - */ - -/* NSC_VerifyRecoverInit initializes a signature verification operation, - * where the data is recovered from the signature. - * E.g. Decryption with the user's public key */ -CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) -{ - SFTKSession *session; - SFTKObject *key; - SFTKSessionContext *context; - CK_KEY_TYPE key_type; - CK_RV crv = CKR_OK; - NSSLOWKEYPublicKey *pubKey; - - CHECK_FORK(); - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - crv = sftk_InitGeneric(session,&context,SFTK_VERIFY_RECOVER, - &key,hKey,&key_type,CKO_PUBLIC_KEY,CKA_VERIFY_RECOVER); - if (crv != CKR_OK) { - sftk_FreeSession(session); - return crv; - } - - context->multi = PR_TRUE; - - switch(pMechanism->mechanism) { - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - if (key_type != CKK_RSA) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - context->multi = PR_FALSE; - pubKey = sftk_GetPubKey(key,CKK_RSA,&crv); - if (pubKey == NULL) { - break; - } - context->cipherInfo = pubKey; - context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509 - ? RSA_CheckSignRecoverRaw : RSA_CheckSignRecover); - context->destroy = sftk_Null; - break; - default: - crv = CKR_MECHANISM_INVALID; - break; - } - - if (crv != CKR_OK) { - PORT_Free(context); - sftk_FreeSession(session); - return crv; - } - sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, context); - sftk_FreeSession(session); - return CKR_OK; -} - - -/* NSC_VerifyRecover verifies a signature in a single-part operation, - * where the data is recovered from the signature. - * E.g. Decryption with the user's public key */ -CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen, - CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen) -{ - SFTKSession *session; - SFTKSessionContext *context; - unsigned int outlen; - unsigned int maxoutlen = *pulDataLen; - CK_RV crv; - SECStatus rv; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER, - PR_FALSE,&session); - if (crv != CKR_OK) return crv; - if (pData == NULL) { - /* to return the actual size, we need to do the decrypt, just return - * the max size, which is the size of the input signature. */ - *pulDataLen = ulSignatureLen; - rv = SECSuccess; - goto finish; - } - - rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, - pSignature, ulSignatureLen); - *pulDataLen = (CK_ULONG) outlen; - - sftk_FreeContext(context); - sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, NULL); -finish: - sftk_FreeSession(session); - return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError()); -} - -/* - **************************** Random Functions: ************************ - */ - -/* NSC_SeedRandom mixes additional seed material into the token's random number - * generator. */ -CK_RV NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, - CK_ULONG ulSeedLen) -{ - SECStatus rv; - - CHECK_FORK(); - - rv = RNG_RandomUpdate(pSeed, ulSeedLen); - return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); -} - -/* NSC_GenerateRandom generates random data. */ -CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) -{ - SECStatus rv; - - CHECK_FORK(); - - rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen); - /* - * This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't - * seeded with enough entropy. - */ - return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); -} - -/* - **************************** Key Functions: ************************ - */ - - -/* - * generate a password based encryption key. This code uses - * PKCS5 to do the work. - */ -static CK_RV -nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism, - void *buf, CK_ULONG *key_length, PRBool faulty3DES) -{ - SECItem *pbe_key = NULL, iv, pwitem; - CK_PBE_PARAMS *pbe_params = NULL; - CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL; - - *key_length = 0; - iv.data = NULL; iv.len = 0; - - if (pMechanism->mechanism == CKM_PKCS5_PBKD2) { - pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter; - pwitem.data = (unsigned char *)pbkd2_params->pPassword; - /* was this a typo in the PKCS #11 spec? */ - pwitem.len = *pbkd2_params->ulPasswordLen; - } else { - pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; - pwitem.data = (unsigned char *)pbe_params->pPassword; - pwitem.len = pbe_params->ulPasswordLen; - } - pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES); - if (pbe_key == NULL) { - return CKR_HOST_MEMORY; - } - - PORT_Memcpy(buf, pbe_key->data, pbe_key->len); - *key_length = pbe_key->len; - SECITEM_ZfreeItem(pbe_key, PR_TRUE); - pbe_key = NULL; - - if (iv.data) { - if (pbe_params && pbe_params->pInitVector != NULL) { - PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); - } - PORT_Free(iv.data); - } - - return CKR_OK; -} -static CK_RV -nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key) -{ - SFTKAttribute *attribute; - CK_ULONG counter; - unsigned int seedBits = 0; - unsigned int primeBits; - unsigned int j; - CK_RV crv = CKR_OK; - PQGParams *params = NULL; - PQGVerify *vfy = NULL; - SECStatus rv; - - attribute = sftk_FindAttribute(key, CKA_PRIME_BITS); - if (attribute == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - j = PQG_PBITS_TO_INDEX(primeBits); - if (j == (unsigned int)-1) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - attribute = sftk_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS); - if (attribute != NULL) { - seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - } - - sftk_DeleteAttributeType(key,CKA_PRIME_BITS); - sftk_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS); - - if (seedBits == 0) { - rv = PQG_ParamGen(j, ¶ms, &vfy); - } else { - rv = PQG_ParamGenSeedLen(j,seedBits/8, ¶ms, &vfy); - } - - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - return sftk_MapCryptError(PORT_GetError()); - } - crv = sftk_AddAttributeType(key,CKA_PRIME, - params->prime.data, params->prime.len); - if (crv != CKR_OK) goto loser; - crv = sftk_AddAttributeType(key,CKA_SUBPRIME, - params->subPrime.data, params->subPrime.len); - if (crv != CKR_OK) goto loser; - crv = sftk_AddAttributeType(key,CKA_BASE, - params->base.data, params->base.len); - if (crv != CKR_OK) goto loser; - counter = vfy->counter; - crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_COUNTER, - &counter, sizeof(counter)); - crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_SEED, - vfy->seed.data, vfy->seed.len); - if (crv != CKR_OK) goto loser; - crv = sftk_AddAttributeType(key,CKA_NETSCAPE_PQG_H, - vfy->h.data, vfy->h.len); - if (crv != CKR_OK) goto loser; - -loser: - if (params) { - PQG_DestroyParams(params); - } - if (vfy) { - PQG_DestroyVerify(vfy); - } - return crv; -} - - -static CK_RV -nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type, - CK_ULONG *key_length) -{ - CK_RV crv = CKR_OK; - - switch (mechanism) { - case CKM_RC2_KEY_GEN: - *key_type = CKK_RC2; - if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE; - break; -#if NSS_SOFTOKEN_DOES_RC5 - case CKM_RC5_KEY_GEN: - *key_type = CKK_RC5; - if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE; - break; -#endif - case CKM_RC4_KEY_GEN: - *key_type = CKK_RC4; - if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE; - break; - case CKM_GENERIC_SECRET_KEY_GEN: - *key_type = CKK_GENERIC_SECRET; - if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE; - break; - case CKM_CDMF_KEY_GEN: - *key_type = CKK_CDMF; - *key_length = 8; - break; - case CKM_DES_KEY_GEN: - *key_type = CKK_DES; - *key_length = 8; - break; - case CKM_DES2_KEY_GEN: - *key_type = CKK_DES2; - *key_length = 16; - break; - case CKM_DES3_KEY_GEN: - *key_type = CKK_DES3; - *key_length = 24; - break; - case CKM_SEED_KEY_GEN: - *key_type = CKK_SEED; - *key_length = 16; - break; - case CKM_CAMELLIA_KEY_GEN: - *key_type = CKK_CAMELLIA; - if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE; - break; - case CKM_AES_KEY_GEN: - *key_type = CKK_AES; - if (*key_length == 0) crv = CKR_TEMPLATE_INCOMPLETE; - break; - default: - PORT_Assert(0); - crv = CKR_MECHANISM_INVALID; - break; - } - - return crv; -} - -CK_RV -nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe) -{ - SECItem salt; - CK_PBE_PARAMS *pbe_params = NULL; - NSSPKCS5PBEParameter *params; - PRArenaPool *arena = NULL; - SECStatus rv; - - *pbe = NULL; - - arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if (arena == NULL) { - return CKR_HOST_MEMORY; - } - - params = (NSSPKCS5PBEParameter *) PORT_ArenaZAlloc(arena, - sizeof(NSSPKCS5PBEParameter)); - if (params == NULL) { - PORT_FreeArena(arena,PR_TRUE); - return CKR_HOST_MEMORY; - } - - params->poolp = arena; - params->ivLen = 0; - params->pbeType = NSSPKCS5_PKCS12_V2; - params->hashType = HASH_AlgSHA1; - params->encAlg = SEC_OID_SHA1; /* any invalid value */ - params->is2KeyDES = PR_FALSE; - params->keyID = pbeBitGenIntegrityKey; - pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; - params->iter = pbe_params->ulIteration; - - salt.data = (unsigned char *)pbe_params->pSalt; - salt.len = (unsigned int)pbe_params->ulSaltLen; - rv = SECITEM_CopyItem(arena,¶ms->salt,&salt); - if (rv != SECSuccess) { - PORT_FreeArena(arena,PR_TRUE); - return CKR_HOST_MEMORY; - } - switch (pMechanism->mechanism) { - case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN: - case CKM_PBA_SHA1_WITH_SHA1_HMAC: - params->hashType = HASH_AlgSHA1; - params->keyLen = 20; - break; - case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN: - params->hashType = HASH_AlgMD5; - params->keyLen = 16; - break; - case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN: - params->hashType = HASH_AlgMD2; - params->keyLen = 16; - break; - default: - PORT_FreeArena(arena,PR_TRUE); - return CKR_MECHANISM_INVALID; - } - *pbe = params; - return CKR_OK; -} - -/* maybe this should be table driven? */ -static CK_RV -nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe, - CK_KEY_TYPE *key_type, CK_ULONG *key_length) -{ - CK_RV crv = CKR_OK; - SECOidData *oid; - CK_PBE_PARAMS *pbe_params = NULL; - NSSPKCS5PBEParameter *params = NULL; - CK_PKCS5_PBKD2_PARAMS *pbkd2_params = NULL; - SECItem salt; - CK_ULONG iteration = 0; - - *pbe = NULL; - - oid = SECOID_FindOIDByMechanism(pMechanism->mechanism); - if (oid == NULL) { - return CKR_MECHANISM_INVALID; - } - - if (pMechanism->mechanism == CKM_PKCS5_PBKD2) { - pbkd2_params = (CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter; - if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED) { - return CKR_MECHANISM_PARAM_INVALID; - } - salt.data = (unsigned char *)pbkd2_params->pSaltSourceData; - salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen; - iteration = pbkd2_params->iterations; - } else { - pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; - salt.data = (unsigned char *)pbe_params->pSalt; - salt.len = (unsigned int)pbe_params->ulSaltLen; - iteration = pbe_params->ulIteration; - } - params=nsspkcs5_NewParam(oid->offset, &salt, iteration); - if (params == NULL) { - return CKR_MECHANISM_INVALID; - } - - switch (params->encAlg) { - case SEC_OID_DES_CBC: - *key_type = CKK_DES; - *key_length = params->keyLen; - break; - case SEC_OID_DES_EDE3_CBC: - *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3; - *key_length = params->keyLen; - break; - case SEC_OID_RC2_CBC: - *key_type = CKK_RC2; - *key_length = params->keyLen; - break; - case SEC_OID_RC4: - *key_type = CKK_RC4; - *key_length = params->keyLen; - break; - case SEC_OID_PKCS5_PBKDF2: - /* sigh, PKCS #11 currently only defines SHA1 for the KDF hash type. - * we do the check here because this where we would handle multiple - * hash types in the future */ - if (pbkd2_params == NULL || - pbkd2_params->prf != CKP_PKCS5_PBKD2_HMAC_SHA1) { - crv = CKR_MECHANISM_PARAM_INVALID; - break; - } - /* key type must already be set */ - if (*key_type == CKK_INVALID_KEY_TYPE) { - crv = CKR_TEMPLATE_INCOMPLETE; - break; - } - /* PBKDF2 needs to calculate the key length from the other parameters - */ - if (*key_length == 0) { - *key_length = sftk_MapKeySize(*key_type); - } - if (*key_length == 0) { - crv = CKR_TEMPLATE_INCOMPLETE; - break; - } - params->keyLen = *key_length; - break; - default: - crv = CKR_MECHANISM_INVALID; - nsspkcs5_DestroyPBEParameter(params); - break; - } - if (crv == CKR_OK) { - *pbe = params; - } - return crv; -} - -/* NSC_GenerateKey generates a secret key, creating a new key object. */ -CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phKey) -{ - SFTKObject *key; - SFTKSession *session; - PRBool checkWeak = PR_FALSE; - CK_ULONG key_length = 0; - CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE; - CK_OBJECT_CLASS objclass = CKO_SECRET_KEY; - CK_RV crv = CKR_OK; - CK_BBOOL cktrue = CK_TRUE; - int i; - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - unsigned char buf[MAX_KEY_LEN]; - enum {nsc_pbe, nsc_ssl, nsc_bulk, nsc_param} key_gen_type; - NSSPKCS5PBEParameter *pbe_param; - SSL3RSAPreMasterSecret *rsa_pms; - CK_VERSION *version; - /* in very old versions of NSS, there were implementation errors with key - * generation methods. We want to beable to read these, but not - * produce them any more. The affected algorithm was 3DES. - */ - PRBool faultyPBE3DES = PR_FALSE; - - CHECK_FORK(); - - if (!slot) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * now lets create an object to hang the attributes off of - */ - key = sftk_NewObject(slot); /* fill in the handle later */ - if (key == NULL) { - return CKR_HOST_MEMORY; - } - - /* - * load the template values into the object - */ - for (i=0; i < (int) ulCount; i++) { - if (pTemplate[i].type == CKA_VALUE_LEN) { - key_length = *(CK_ULONG *)pTemplate[i].pValue; - continue; - } - /* some algorithms need keytype specified */ - if (pTemplate[i].type == CKA_KEY_TYPE) { - key_type = *(CK_ULONG *)pTemplate[i].pValue; - continue; - } - - crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i])); - if (crv != CKR_OK) break; - } - if (crv != CKR_OK) { - sftk_FreeObject(key); - return crv; - } - - /* make sure we don't have any class, key_type, or value fields */ - sftk_DeleteAttributeType(key,CKA_CLASS); - sftk_DeleteAttributeType(key,CKA_KEY_TYPE); - sftk_DeleteAttributeType(key,CKA_VALUE); - - /* Now Set up the parameters to generate the key (based on mechanism) */ - key_gen_type = nsc_bulk; /* bulk key by default */ - switch (pMechanism->mechanism) { - case CKM_CDMF_KEY_GEN: - case CKM_DES_KEY_GEN: - case CKM_DES2_KEY_GEN: - case CKM_DES3_KEY_GEN: - checkWeak = PR_TRUE; - case CKM_RC2_KEY_GEN: - case CKM_RC4_KEY_GEN: - case CKM_GENERIC_SECRET_KEY_GEN: - case CKM_SEED_KEY_GEN: - case CKM_CAMELLIA_KEY_GEN: - case CKM_AES_KEY_GEN: -#if NSS_SOFTOKEN_DOES_RC5 - case CKM_RC5_KEY_GEN: -#endif - crv = nsc_SetupBulkKeyGen(pMechanism->mechanism,&key_type,&key_length); - break; - case CKM_SSL3_PRE_MASTER_KEY_GEN: - key_type = CKK_GENERIC_SECRET; - key_length = 48; - key_gen_type = nsc_ssl; - break; - 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: - key_gen_type = nsc_pbe; - key_type = CKK_GENERIC_SECRET; - crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param); - break; - case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC: - faultyPBE3DES = PR_TRUE; - case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC: - case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC: - case CKM_NETSCAPE_PBE_SHA1_DES_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_128_CBC: - case CKM_PBE_SHA1_RC2_40_CBC: - case CKM_PBE_SHA1_RC4_128: - case CKM_PBE_SHA1_RC4_40: - case CKM_PBE_MD5_DES_CBC: - case CKM_PBE_MD2_DES_CBC: - case CKM_PKCS5_PBKD2: - key_gen_type = nsc_pbe; - crv = nsc_SetupPBEKeyGen(pMechanism,&pbe_param, &key_type, &key_length); - break; - case CKM_DSA_PARAMETER_GEN: - key_gen_type = nsc_param; - key_type = CKK_DSA; - objclass = CKO_KG_PARAMETERS; - crv = CKR_OK; - break; - default: - crv = CKR_MECHANISM_INVALID; - break; - } - - /* make sure we aren't going to overflow the buffer */ - if (sizeof(buf) < key_length) { - /* someone is getting pretty optimistic about how big their key can - * be... */ - crv = CKR_TEMPLATE_INCONSISTENT; - } - - if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } - - /* if there was no error, - * key_type *MUST* be set in the switch statement above */ - PORT_Assert( key_type != CKK_INVALID_KEY_TYPE ); - - /* - * now to the actual key gen. - */ - switch (key_gen_type) { - case nsc_pbe: - crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length, - faultyPBE3DES); - nsspkcs5_DestroyPBEParameter(pbe_param); - break; - case nsc_ssl: - rsa_pms = (SSL3RSAPreMasterSecret *)buf; - version = (CK_VERSION *)pMechanism->pParameter; - rsa_pms->client_version[0] = version->major; - rsa_pms->client_version[1] = version->minor; - crv = - NSC_GenerateRandom(0,&rsa_pms->random[0], sizeof(rsa_pms->random)); - break; - case nsc_bulk: - /* get the key, check for weak keys and repeat if found */ - do { - crv = NSC_GenerateRandom(0, buf, key_length); - } while (crv == CKR_OK && checkWeak && sftk_IsWeakKey(buf,key_type)); - break; - case nsc_param: - /* generate parameters */ - *buf = 0; - crv = nsc_parameter_gen(key_type,key); - break; - } - - if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } - - /* Add the class, key_type, and value */ - crv = sftk_AddAttributeType(key,CKA_CLASS,&objclass,sizeof(CK_OBJECT_CLASS)); - if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } - crv = sftk_AddAttributeType(key,CKA_KEY_TYPE,&key_type,sizeof(CK_KEY_TYPE)); - if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } - if (key_length != 0) { - crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length); - if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } - } - - /* get the session */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - sftk_FreeObject(key); - return CKR_SESSION_HANDLE_INVALID; - } - - /* - * handle the base object stuff - */ - crv = sftk_handleObject(key,session); - sftk_FreeSession(session); - if (sftk_isTrue(key,CKA_SENSITIVE)) { - sftk_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL)); - } - if (!sftk_isTrue(key,CKA_EXTRACTABLE)) { - sftk_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,sizeof(CK_BBOOL)); - } - - *phKey = key->handle; - sftk_FreeObject(key); - return crv; -} - -#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */ -#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */ - -/* - * FIPS 140-2 pairwise consistency check utilized to validate key pair. - * - * This function returns - * CKR_OK if pairwise consistency check passed - * CKR_GENERAL_ERROR if pairwise consistency check failed - * other error codes if paiswise consistency check could not be - * performed, for example, CKR_HOST_MEMORY. - */ -static CK_RV -sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, - SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType) -{ - /* - * Key type Mechanism type - * -------------------------------- - * For encrypt/decrypt: CKK_RSA => CKM_RSA_PKCS - * others => CKM_INVALID_MECHANISM - * - * For sign/verify: CKK_RSA => CKM_RSA_PKCS - * CKK_DSA => CKM_DSA - * CKK_EC => CKM_ECDSA - * others => CKM_INVALID_MECHANISM - * - * None of these mechanisms has a parameter. - */ - CK_MECHANISM mech = {0, NULL, 0}; - - CK_ULONG modulusLen; - PRBool isEncryptable = PR_FALSE; - PRBool canSignVerify = PR_FALSE; - PRBool isDerivable = PR_FALSE; - CK_RV crv; - - /* Variables used for Encrypt/Decrypt functions. */ - unsigned char *known_message = (unsigned char *)"Known Crypto Message"; - unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH]; - CK_ULONG bytes_decrypted; - unsigned char *ciphertext; - unsigned char *text_compared; - CK_ULONG bytes_encrypted; - CK_ULONG bytes_compared; - - /* Variables used for Signature/Verification functions. */ - /* always uses SHA-1 digest */ - unsigned char *known_digest = (unsigned char *)"Mozilla Rules World!"; - unsigned char *signature; - CK_ULONG signature_length; - - if (keyType == CKK_RSA) { - SFTKAttribute *attribute; - - /* Get modulus length of private key. */ - attribute = sftk_FindAttribute(privateKey, CKA_MODULUS); - if (attribute == NULL) { - return CKR_DEVICE_ERROR; - } - modulusLen = attribute->attrib.ulValueLen; - if (*(unsigned char *)attribute->attrib.pValue == 0) { - modulusLen--; - } - sftk_FreeAttribute(attribute); - } - - /**************************************************/ - /* Pairwise Consistency Check of Encrypt/Decrypt. */ - /**************************************************/ - - isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT); - - /* - * If the decryption attribute is set, attempt to encrypt - * with the public key and decrypt with the private key. - */ - if (isEncryptable) { - if (keyType != CKK_RSA) { - return CKR_DEVICE_ERROR; - } - bytes_encrypted = modulusLen; - mech.mechanism = CKM_RSA_PKCS; - - /* Allocate space for ciphertext. */ - ciphertext = (unsigned char *) PORT_ZAlloc(bytes_encrypted); - if (ciphertext == NULL) { - return CKR_HOST_MEMORY; - } - - /* Prepare for encryption using the public key. */ - crv = NSC_EncryptInit(hSession, &mech, publicKey->handle); - if (crv != CKR_OK) { - PORT_Free(ciphertext); - return crv; - } - - /* Encrypt using the public key. */ - crv = NSC_Encrypt(hSession, - known_message, - PAIRWISE_MESSAGE_LENGTH, - ciphertext, - &bytes_encrypted); - if (crv != CKR_OK) { - PORT_Free(ciphertext); - return crv; - } - - /* Always use the smaller of these two values . . . */ - bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH); - - /* - * If there was a failure, the plaintext - * goes at the end, therefore . . . - */ - text_compared = ciphertext + bytes_encrypted - bytes_compared; - - /* - * Check to ensure that ciphertext does - * NOT EQUAL known input message text - * per FIPS PUB 140-2 directive. - */ - if (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 CKR_GENERAL_ERROR; - } - - /* Prepare for decryption using the private key. */ - crv = NSC_DecryptInit(hSession, &mech, privateKey->handle); - if (crv != CKR_OK) { - PORT_Free(ciphertext); - return crv; - } - - memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH); - - /* - * 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 = NSC_Decrypt(hSession, - ciphertext, - bytes_encrypted, - plaintext, - &bytes_decrypted); - - /* Finished with ciphertext; free it. */ - PORT_Free(ciphertext); - - if (crv != CKR_OK) { - return crv; - } - - /* - * 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 CKR_GENERAL_ERROR; - } - } - - /**********************************************/ - /* Pairwise Consistency Check of Sign/Verify. */ - /**********************************************/ - - canSignVerify = sftk_isTrue(privateKey, CKA_SIGN); - - if (canSignVerify) { - /* Determine length of signature. */ - switch (keyType) { - case CKK_RSA: - signature_length = modulusLen; - mech.mechanism = CKM_RSA_PKCS; - break; - case CKK_DSA: - signature_length = DSA_SIGNATURE_LEN; - mech.mechanism = CKM_DSA; - break; -#ifdef NSS_ENABLE_ECC - case CKK_EC: - signature_length = MAX_ECKEY_LEN * 2; - mech.mechanism = CKM_ECDSA; - break; -#endif - default: - return CKR_DEVICE_ERROR; - } - - /* Allocate space for signature data. */ - signature = (unsigned char *) PORT_ZAlloc(signature_length); - if (signature == NULL) { - return CKR_HOST_MEMORY; - } - - /* Sign the known hash using the private key. */ - crv = NSC_SignInit(hSession, &mech, privateKey->handle); - if (crv != CKR_OK) { - PORT_Free(signature); - return crv; - } - - crv = NSC_Sign(hSession, - known_digest, - PAIRWISE_DIGEST_LENGTH, - signature, - &signature_length); - if (crv != CKR_OK) { - PORT_Free(signature); - return crv; - } - - /* Verify the known hash using the public key. */ - crv = NSC_VerifyInit(hSession, &mech, publicKey->handle); - if (crv != CKR_OK) { - PORT_Free(signature); - return crv; - } - - crv = NSC_Verify(hSession, - known_digest, - PAIRWISE_DIGEST_LENGTH, - signature, - signature_length); - - /* Free signature data. */ - PORT_Free(signature); - - if ((crv == CKR_SIGNATURE_LEN_RANGE) || - (crv == CKR_SIGNATURE_INVALID)) { - return CKR_GENERAL_ERROR; - } - if (crv != CKR_OK) { - return crv; - } - } - - /**********************************************/ - /* Pairwise Consistency Check for Derivation */ - /**********************************************/ - - isDerivable = sftk_isTrue(privateKey, CKA_DERIVE); - - if (isDerivable) { - /* - * We are not doing consistency check for Diffie-Hellman Key - - * otherwise it would be here - * This is also true for Elliptic Curve Diffie-Hellman keys - * NOTE: EC keys are currently subjected to pairwise - * consistency check for signing/verification. - */ - /* - * FIPS 140-2 had the following pairwise consistency test for - * public and private keys used for key agreement: - * If the keys are used to perform key agreement, then the - * cryptographic module shall create a second, compatible - * key pair. The cryptographic module shall perform both - * sides of the key agreement algorithm and shall compare - * the resulting shared values. If the shared values are - * not equal, the test shall fail. - * This test was removed in Change Notice 3. - */ - - } - - return CKR_OK; -} - -/* NSC_GenerateKeyPair generates a public-key/private-key pair, - * creating new key objects. */ -CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, - CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, - CK_OBJECT_HANDLE_PTR phPrivateKey) -{ - SFTKObject * publicKey,*privateKey; - SFTKSession * session; - CK_KEY_TYPE key_type; - CK_RV crv = CKR_OK; - CK_BBOOL cktrue = CK_TRUE; - SECStatus rv; - CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; - CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; - int i; - SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession); - unsigned int bitSize; - - /* RSA */ - int public_modulus_bits = 0; - SECItem pubExp; - RSAPrivateKey * rsaPriv; - - /* DSA */ - PQGParams pqgParam; - DHParams dhParam; - DSAPrivateKey * dsaPriv; - - /* Diffie Hellman */ - int private_value_bits = 0; - DHPrivateKey * dhPriv; - -#ifdef NSS_ENABLE_ECC - /* Elliptic Curve Cryptography */ - SECItem ecEncodedParams; /* DER Encoded parameters */ - ECPrivateKey * ecPriv; - ECParams * ecParams; -#endif /* NSS_ENABLE_ECC */ - - CHECK_FORK(); - - if (!slot) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * now lets create an object to hang the attributes off of - */ - publicKey = sftk_NewObject(slot); /* fill in the handle later */ - if (publicKey == NULL) { - return CKR_HOST_MEMORY; - } - - /* - * load the template values into the publicKey - */ - for (i=0; i < (int) ulPublicKeyAttributeCount; i++) { - if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS) { - public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue; - continue; - } - - crv = sftk_AddAttributeType(publicKey, - sftk_attr_expand(&pPublicKeyTemplate[i])); - if (crv != CKR_OK) break; - } - - if (crv != CKR_OK) { - sftk_FreeObject(publicKey); - return CKR_HOST_MEMORY; - } - - privateKey = sftk_NewObject(slot); /* fill in the handle later */ - if (privateKey == NULL) { - sftk_FreeObject(publicKey); - return CKR_HOST_MEMORY; - } - /* - * now load the private key template - */ - for (i=0; i < (int) ulPrivateKeyAttributeCount; i++) { - if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) { - private_value_bits = *(CK_ULONG *)pPrivateKeyTemplate[i].pValue; - continue; - } - - crv = sftk_AddAttributeType(privateKey, - sftk_attr_expand(&pPrivateKeyTemplate[i])); - if (crv != CKR_OK) break; - } - - if (crv != CKR_OK) { - sftk_FreeObject(publicKey); - sftk_FreeObject(privateKey); - return CKR_HOST_MEMORY; - } - sftk_DeleteAttributeType(privateKey,CKA_CLASS); - sftk_DeleteAttributeType(privateKey,CKA_KEY_TYPE); - sftk_DeleteAttributeType(privateKey,CKA_VALUE); - sftk_DeleteAttributeType(publicKey,CKA_CLASS); - sftk_DeleteAttributeType(publicKey,CKA_KEY_TYPE); - sftk_DeleteAttributeType(publicKey,CKA_VALUE); - - /* Now Set up the parameters to generate the key (based on mechanism) */ - switch (pMechanism->mechanism) { - case CKM_RSA_PKCS_KEY_PAIR_GEN: - /* format the keys */ - sftk_DeleteAttributeType(publicKey,CKA_MODULUS); - sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB); - sftk_DeleteAttributeType(privateKey,CKA_MODULUS); - sftk_DeleteAttributeType(privateKey,CKA_PRIVATE_EXPONENT); - sftk_DeleteAttributeType(privateKey,CKA_PUBLIC_EXPONENT); - sftk_DeleteAttributeType(privateKey,CKA_PRIME_1); - sftk_DeleteAttributeType(privateKey,CKA_PRIME_2); - sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_1); - sftk_DeleteAttributeType(privateKey,CKA_EXPONENT_2); - sftk_DeleteAttributeType(privateKey,CKA_COEFFICIENT); - key_type = CKK_RSA; - if (public_modulus_bits == 0) { - crv = CKR_TEMPLATE_INCOMPLETE; - break; - } - if (public_modulus_bits < RSA_MIN_MODULUS_BITS) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - if (public_modulus_bits % 2 != 0) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - - /* extract the exponent */ - crv=sftk_Attribute2SSecItem(NULL,&pubExp,publicKey,CKA_PUBLIC_EXPONENT); - if (crv != CKR_OK) break; - bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len); - if (bitSize < 2) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - crv = sftk_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT, - sftk_item_expand(&pubExp)); - if (crv != CKR_OK) { - PORT_Free(pubExp.data); - break; - } - - rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp); - PORT_Free(pubExp.data); - if (rsaPriv == NULL) { - if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - crv = sftk_MapCryptError(PORT_GetError()); - break; - } - /* now fill in the RSA dependent paramenters in the public key */ - crv = sftk_AddAttributeType(publicKey,CKA_MODULUS, - sftk_item_expand(&rsaPriv->modulus)); - if (crv != CKR_OK) goto kpg_done; - /* now fill in the RSA dependent paramenters in the private key */ - crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB, - sftk_item_expand(&rsaPriv->modulus)); - if (crv != CKR_OK) goto kpg_done; - crv = sftk_AddAttributeType(privateKey,CKA_MODULUS, - sftk_item_expand(&rsaPriv->modulus)); - if (crv != CKR_OK) goto kpg_done; - crv = sftk_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT, - sftk_item_expand(&rsaPriv->privateExponent)); - if (crv != CKR_OK) goto kpg_done; - crv = sftk_AddAttributeType(privateKey,CKA_PRIME_1, - sftk_item_expand(&rsaPriv->prime1)); - if (crv != CKR_OK) goto kpg_done; - crv = sftk_AddAttributeType(privateKey,CKA_PRIME_2, - sftk_item_expand(&rsaPriv->prime2)); - if (crv != CKR_OK) goto kpg_done; - crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_1, - sftk_item_expand(&rsaPriv->exponent1)); - if (crv != CKR_OK) goto kpg_done; - crv = sftk_AddAttributeType(privateKey,CKA_EXPONENT_2, - sftk_item_expand(&rsaPriv->exponent2)); - if (crv != CKR_OK) goto kpg_done; - crv = sftk_AddAttributeType(privateKey,CKA_COEFFICIENT, - sftk_item_expand(&rsaPriv->coefficient)); -kpg_done: - /* Should zeroize the contents first, since this func doesn't. */ - PORT_FreeArena(rsaPriv->arena, PR_TRUE); - break; - case CKM_DSA_KEY_PAIR_GEN: - sftk_DeleteAttributeType(publicKey,CKA_VALUE); - sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB); - sftk_DeleteAttributeType(privateKey,CKA_PRIME); - sftk_DeleteAttributeType(privateKey,CKA_SUBPRIME); - sftk_DeleteAttributeType(privateKey,CKA_BASE); - key_type = CKK_DSA; - - /* extract the necessary paramters and copy them to the private key */ - crv=sftk_Attribute2SSecItem(NULL,&pqgParam.prime,publicKey,CKA_PRIME); - if (crv != CKR_OK) break; - crv=sftk_Attribute2SSecItem(NULL,&pqgParam.subPrime,publicKey, - CKA_SUBPRIME); - if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - break; - } - crv=sftk_Attribute2SSecItem(NULL,&pqgParam.base,publicKey,CKA_BASE); - if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - break; - } - crv = sftk_AddAttributeType(privateKey,CKA_PRIME, - sftk_item_expand(&pqgParam.prime)); - if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); - break; - } - crv = sftk_AddAttributeType(privateKey,CKA_SUBPRIME, - sftk_item_expand(&pqgParam.subPrime)); - if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); - break; - } - crv = sftk_AddAttributeType(privateKey,CKA_BASE, - sftk_item_expand(&pqgParam.base)); - if (crv != CKR_OK) { - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); - break; - } - - bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data, - pqgParam.subPrime.len); - if (bitSize != DSA_Q_BITS) { - crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); - break; - } - bitSize = sftk_GetLengthInBits(pqgParam.prime.data,pqgParam.prime.len); - if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) { - crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); - break; - } - bitSize = sftk_GetLengthInBits(pqgParam.base.data,pqgParam.base.len); - if ((bitSize < 1) || (bitSize > DSA_MAX_P_BITS)) { - crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); - break; - } - - /* Generate the key */ - rv = DSA_NewKey(&pqgParam, &dsaPriv); - - PORT_Free(pqgParam.prime.data); - PORT_Free(pqgParam.subPrime.data); - PORT_Free(pqgParam.base.data); - - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - crv = sftk_MapCryptError(PORT_GetError()); - break; - } - - /* store the generated key into the attributes */ - crv = sftk_AddAttributeType(publicKey,CKA_VALUE, - sftk_item_expand(&dsaPriv->publicValue)); - if (crv != CKR_OK) goto dsagn_done; - - /* now fill in the RSA dependent paramenters in the private key */ - crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB, - sftk_item_expand(&dsaPriv->publicValue)); - if (crv != CKR_OK) goto dsagn_done; - crv = sftk_AddAttributeType(privateKey,CKA_VALUE, - sftk_item_expand(&dsaPriv->privateValue)); - -dsagn_done: - /* should zeroize, since this function doesn't. */ - PORT_FreeArena(dsaPriv->params.arena, PR_TRUE); - break; - - case CKM_DH_PKCS_KEY_PAIR_GEN: - sftk_DeleteAttributeType(privateKey,CKA_PRIME); - sftk_DeleteAttributeType(privateKey,CKA_BASE); - sftk_DeleteAttributeType(privateKey,CKA_VALUE); - sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB); - key_type = CKK_DH; - - /* extract the necessary parameters and copy them to private keys */ - crv = sftk_Attribute2SSecItem(NULL, &dhParam.prime, publicKey, - CKA_PRIME); - if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE); - if (crv != CKR_OK) { - PORT_Free(dhParam.prime.data); - break; - } - crv = sftk_AddAttributeType(privateKey, CKA_PRIME, - sftk_item_expand(&dhParam.prime)); - if (crv != CKR_OK) { - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); - break; - } - crv = sftk_AddAttributeType(privateKey, CKA_BASE, - sftk_item_expand(&dhParam.base)); - if (crv != CKR_OK) { - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); - break; - } - bitSize = sftk_GetLengthInBits(dhParam.prime.data,dhParam.prime.len); - if ((bitSize < DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) { - crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); - break; - } - bitSize = sftk_GetLengthInBits(dhParam.base.data,dhParam.base.len); - if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS)) { - crv = CKR_TEMPLATE_INCOMPLETE; - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); - break; - } - - rv = DH_NewKey(&dhParam, &dhPriv); - PORT_Free(dhParam.prime.data); - PORT_Free(dhParam.base.data); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - crv = sftk_MapCryptError(PORT_GetError()); - break; - } - - crv=sftk_AddAttributeType(publicKey, CKA_VALUE, - sftk_item_expand(&dhPriv->publicValue)); - if (crv != CKR_OK) goto dhgn_done; - - crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB, - sftk_item_expand(&dhPriv->publicValue)); - if (crv != CKR_OK) goto dhgn_done; - - crv=sftk_AddAttributeType(privateKey, CKA_VALUE, - sftk_item_expand(&dhPriv->privateValue)); - -dhgn_done: - /* should zeroize, since this function doesn't. */ - PORT_FreeArena(dhPriv->arena, PR_TRUE); - break; - -#ifdef NSS_ENABLE_ECC - case CKM_EC_KEY_PAIR_GEN: - sftk_DeleteAttributeType(privateKey,CKA_EC_PARAMS); - sftk_DeleteAttributeType(privateKey,CKA_VALUE); - sftk_DeleteAttributeType(privateKey,CKA_NETSCAPE_DB); - key_type = CKK_EC; - - /* extract the necessary parameters and copy them to private keys */ - crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey, - CKA_EC_PARAMS); - if (crv != CKR_OK) break; - - crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS, - sftk_item_expand(&ecEncodedParams)); - if (crv != CKR_OK) { - PORT_Free(ecEncodedParams.data); - break; - } - - /* Decode ec params before calling EC_NewKey */ - rv = EC_DecodeParams(&ecEncodedParams, &ecParams); - PORT_Free(ecEncodedParams.data); - if (rv != SECSuccess) { - crv = sftk_MapCryptError(PORT_GetError()); - break; - } - rv = EC_NewKey(ecParams, &ecPriv); - PORT_FreeArena(ecParams->arena, PR_TRUE); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - crv = sftk_MapCryptError(PORT_GetError()); - break; - } - - if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) { - crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, - sftk_item_expand(&ecPriv->publicValue)); - } else { - SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, - &ecPriv->publicValue, - SEC_ASN1_GET(SEC_OctetStringTemplate)); - if (!pubValue) { - crv = CKR_ARGUMENTS_BAD; - goto ecgn_done; - } - crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, - sftk_item_expand(pubValue)); - SECITEM_FreeItem(pubValue, PR_TRUE); - } - if (crv != CKR_OK) goto ecgn_done; - - crv = sftk_AddAttributeType(privateKey, CKA_VALUE, - sftk_item_expand(&ecPriv->privateValue)); - if (crv != CKR_OK) goto ecgn_done; - - crv = sftk_AddAttributeType(privateKey,CKA_NETSCAPE_DB, - sftk_item_expand(&ecPriv->publicValue)); -ecgn_done: - /* should zeroize, since this function doesn't. */ - PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE); - break; -#endif /* NSS_ENABLE_ECC */ - - default: - crv = CKR_MECHANISM_INVALID; - } - - if (crv != CKR_OK) { - sftk_FreeObject(privateKey); - sftk_FreeObject(publicKey); - return crv; - } - - - /* Add the class, key_type The loop lets us check errors blow out - * on errors and clean up at the bottom */ - session = NULL; /* make pedtantic happy... session cannot leave the*/ - /* loop below NULL unless an error is set... */ - do { - crv = sftk_AddAttributeType(privateKey,CKA_CLASS,&privClass, - sizeof(CK_OBJECT_CLASS)); - if (crv != CKR_OK) break; - crv = sftk_AddAttributeType(publicKey,CKA_CLASS,&pubClass, - sizeof(CK_OBJECT_CLASS)); - if (crv != CKR_OK) break; - crv = sftk_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type, - sizeof(CK_KEY_TYPE)); - if (crv != CKR_OK) break; - crv = sftk_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type, - sizeof(CK_KEY_TYPE)); - if (crv != CKR_OK) break; - session = sftk_SessionFromHandle(hSession); - if (session == NULL) crv = CKR_SESSION_HANDLE_INVALID; - } while (0); - - if (crv != CKR_OK) { - sftk_FreeObject(privateKey); - sftk_FreeObject(publicKey); - return crv; - } - - /* - * handle the base object cleanup for the public Key - */ - crv = sftk_handleObject(privateKey,session); - if (crv != CKR_OK) { - sftk_FreeSession(session); - sftk_FreeObject(privateKey); - sftk_FreeObject(publicKey); - return crv; - } - - /* - * handle the base object cleanup for the private Key - * If we have any problems, we destroy the public Key we've - * created and linked. - */ - crv = sftk_handleObject(publicKey,session); - sftk_FreeSession(session); - if (crv != CKR_OK) { - sftk_FreeObject(publicKey); - NSC_DestroyObject(hSession,privateKey->handle); - sftk_FreeObject(privateKey); - return crv; - } - if (sftk_isTrue(privateKey,CKA_SENSITIVE)) { - sftk_forceAttribute(privateKey,CKA_ALWAYS_SENSITIVE, - &cktrue,sizeof(CK_BBOOL)); - } - if (sftk_isTrue(publicKey,CKA_SENSITIVE)) { - sftk_forceAttribute(publicKey,CKA_ALWAYS_SENSITIVE, - &cktrue,sizeof(CK_BBOOL)); - } - if (!sftk_isTrue(privateKey,CKA_EXTRACTABLE)) { - sftk_forceAttribute(privateKey,CKA_NEVER_EXTRACTABLE, - &cktrue,sizeof(CK_BBOOL)); - } - if (!sftk_isTrue(publicKey,CKA_EXTRACTABLE)) { - sftk_forceAttribute(publicKey,CKA_NEVER_EXTRACTABLE, - &cktrue,sizeof(CK_BBOOL)); - } - - /* Perform FIPS 140-2 pairwise consistency check. */ - crv = sftk_PairwiseConsistencyCheck(hSession, - publicKey, privateKey, key_type); - if (crv != CKR_OK) { - NSC_DestroyObject(hSession,publicKey->handle); - sftk_FreeObject(publicKey); - NSC_DestroyObject(hSession,privateKey->handle); - sftk_FreeObject(privateKey); - if (sftk_audit_enabled) { - char msg[128]; - PR_snprintf(msg,sizeof msg, - "C_GenerateKeyPair(hSession=0x%08lX, " - "pMechanism->mechanism=0x%08lX)=0x%08lX " - "self-test: pair-wise consistency test failed", - (PRUint32)hSession,(PRUint32)pMechanism->mechanism, - (PRUint32)crv); - sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); - } - return crv; - } - - *phPrivateKey = privateKey->handle; - *phPublicKey = publicKey->handle; - sftk_FreeObject(publicKey); - sftk_FreeObject(privateKey); - - return CKR_OK; -} - -static SECItem *sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) -{ - NSSLOWKEYPrivateKey *lk = NULL; - NSSLOWKEYPrivateKeyInfo *pki = NULL; - SFTKAttribute *attribute = NULL; - PLArenaPool *arena = NULL; - SECOidTag algorithm = SEC_OID_UNKNOWN; - void *dummy, *param = NULL; - SECStatus rv = SECSuccess; - SECItem *encodedKey = NULL; -#ifdef NSS_ENABLE_ECC - SECItem *fordebug; - int savelen; -#endif - - if(!key) { - *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */ - return NULL; - } - - attribute = sftk_FindAttribute(key, CKA_KEY_TYPE); - if(!attribute) { - *crvp = CKR_KEY_TYPE_INCONSISTENT; - return NULL; - } - - lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp); - sftk_FreeAttribute(attribute); - if(!lk) { - return NULL; - } - - arena = PORT_NewArena(2048); /* XXX different size? */ - if(!arena) { - *crvp = CKR_HOST_MEMORY; - rv = SECFailure; - goto loser; - } - - pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPrivateKeyInfo)); - if(!pki) { - *crvp = CKR_HOST_MEMORY; - rv = SECFailure; - goto loser; - } - pki->arena = arena; - - param = NULL; - switch(lk->keyType) { - case NSSLOWKEYRSAKey: - prepare_low_rsa_priv_key_for_asn1(lk); - dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, - nsslowkey_RSAPrivateKeyTemplate); - algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; - break; - case NSSLOWKEYDSAKey: - prepare_low_dsa_priv_key_export_for_asn1(lk); - dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, - nsslowkey_DSAPrivateKeyExportTemplate); - prepare_low_pqg_params_for_asn1(&lk->u.dsa.params); - param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params), - nsslowkey_PQGParamsTemplate); - algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE; - break; -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - prepare_low_ec_priv_key_for_asn1(lk); - /* Public value is encoded as a bit string so adjust length - * to be in bits before ASN encoding and readjust - * immediately after. - * - * Since the SECG specification recommends not including the - * parameters as part of ECPrivateKey, we zero out the curveOID - * length before encoding and restore it later. - */ - lk->u.ec.publicValue.len <<= 3; - savelen = lk->u.ec.ecParams.curveOID.len; - lk->u.ec.ecParams.curveOID.len = 0; - dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, - nsslowkey_ECPrivateKeyTemplate); - lk->u.ec.ecParams.curveOID.len = savelen; - lk->u.ec.publicValue.len >>= 3; - - fordebug = &pki->privateKey; - SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType, - fordebug); - - param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding); - - algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY; - break; -#endif /* NSS_ENABLE_ECC */ - case NSSLOWKEYDHKey: - default: - dummy = NULL; - break; - } - - if(!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) { - *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */ - rv = SECFailure; - goto loser; - } - - rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm, - (SECItem*)param); - if(rv != SECSuccess) { - *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */ - rv = SECFailure; - goto loser; - } - - dummy = SEC_ASN1EncodeInteger(arena, &pki->version, - NSSLOWKEY_PRIVATE_KEY_INFO_VERSION); - if(!dummy) { - *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */ - rv = SECFailure; - goto loser; - } - - encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki, - nsslowkey_PrivateKeyInfoTemplate); - *crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR; - -#ifdef NSS_ENABLE_ECC - fordebug = encodedKey; - SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType, - fordebug); -#endif -loser: - if(arena) { - PORT_FreeArena(arena, PR_TRUE); - } - - if(lk && (lk != key->objectInfo)) { - nsslowkey_DestroyPrivateKey(lk); - } - - if(param) { - SECITEM_ZfreeItem((SECItem*)param, PR_TRUE); - } - - if(rv != SECSuccess) { - return NULL; - } - - return encodedKey; -} - -/* it doesn't matter yet, since we colapse error conditions in the - * level above, but we really should map those few key error differences */ -static CK_RV -sftk_mapWrap(CK_RV crv) -{ - switch (crv) { - case CKR_ENCRYPTED_DATA_INVALID: crv = CKR_WRAPPED_KEY_INVALID; break; - } - return crv; -} - -/* NSC_WrapKey wraps (i.e., encrypts) a key. */ -CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, - CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, - CK_ULONG_PTR pulWrappedKeyLen) -{ - SFTKSession *session; - SFTKAttribute *attribute; - SFTKObject *key; - CK_RV crv; - - CHECK_FORK(); - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - return CKR_SESSION_HANDLE_INVALID; - } - - key = sftk_ObjectFromHandle(hKey,session); - sftk_FreeSession(session); - if (key == NULL) { - return CKR_KEY_HANDLE_INVALID; - } - - switch(key->objclass) { - case CKO_SECRET_KEY: - { - SFTKSessionContext *context = NULL; - SECItem pText; - - attribute = sftk_FindAttribute(key,CKA_VALUE); - - if (attribute == NULL) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey, - CKA_WRAP, SFTK_ENCRYPT, PR_TRUE); - if (crv != CKR_OK) { - sftk_FreeAttribute(attribute); - break; - } - - pText.type = siBuffer; - pText.data = (unsigned char *)attribute->attrib.pValue; - pText.len = attribute->attrib.ulValueLen; - - /* Find out if this is a block cipher. */ - crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_FALSE,NULL); - if (crv != CKR_OK || !context) - break; - if (context->blockSize > 1) { - unsigned int remainder = pText.len % context->blockSize; - if (!context->doPad && remainder) { - /* When wrapping secret keys with unpadded block ciphers, - ** the keys are zero padded, if necessary, to fill out - ** a full block. - */ - pText.len += context->blockSize - remainder; - pText.data = PORT_ZAlloc(pText.len); - if (pText.data) - memcpy(pText.data, attribute->attrib.pValue, - attribute->attrib.ulValueLen); - else { - crv = CKR_HOST_MEMORY; - break; - } - } - } - - crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data, - pText.len, pWrappedKey, pulWrappedKeyLen); - /* always force a finalize, both on errors and when - * we are just getting the size */ - if (crv != CKR_OK || pWrappedKey == NULL) { - CK_RV lcrv ; - lcrv = sftk_GetContext(hSession,&context, - SFTK_ENCRYPT,PR_FALSE,NULL); - sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); - if (lcrv == CKR_OK && context) { - sftk_FreeContext(context); - } - } - - if (pText.data != (unsigned char *)attribute->attrib.pValue) - PORT_ZFree(pText.data, pText.len); - sftk_FreeAttribute(attribute); - break; - } - - case CKO_PRIVATE_KEY: - { - SECItem *bpki = sftk_PackagePrivateKey(key, &crv); - SFTKSessionContext *context = NULL; - - if(!bpki) { - break; - } - - crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey, - CKA_WRAP, SFTK_ENCRYPT, PR_TRUE); - if(crv != CKR_OK) { - SECITEM_ZfreeItem(bpki, PR_TRUE); - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - - crv = NSC_Encrypt(hSession, bpki->data, bpki->len, - pWrappedKey, pulWrappedKeyLen); - /* always force a finalize */ - if (crv != CKR_OK || pWrappedKey == NULL) { - CK_RV lcrv ; - lcrv = sftk_GetContext(hSession,&context, - SFTK_ENCRYPT,PR_FALSE,NULL); - sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); - if (lcrv == CKR_OK && context) { - sftk_FreeContext(context); - } - } - SECITEM_ZfreeItem(bpki, PR_TRUE); - break; - } - - default: - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - sftk_FreeObject(key); - - return sftk_mapWrap(crv); -} - -/* - * import a pprivate key info into the desired slot - */ -static SECStatus -sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) -{ - CK_BBOOL cktrue = CK_TRUE; - CK_KEY_TYPE keyType = CKK_RSA; - SECStatus rv = SECFailure; - const SEC_ASN1Template *keyTemplate, *paramTemplate; - void *paramDest = NULL; - PLArenaPool *arena; - NSSLOWKEYPrivateKey *lpk = NULL; - NSSLOWKEYPrivateKeyInfo *pki = NULL; - CK_RV crv = CKR_KEY_TYPE_INCONSISTENT; - - arena = PORT_NewArena(2048); - if(!arena) { - return SECFailure; - } - - pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPrivateKeyInfo)); - if(!pki) { - PORT_FreeArena(arena, PR_FALSE); - return SECFailure; - } - - if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) - != SECSuccess) { - PORT_FreeArena(arena, PR_TRUE); - return SECFailure; - } - - lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena, - sizeof(NSSLOWKEYPrivateKey)); - if(lpk == NULL) { - goto loser; - } - lpk->arena = arena; - - switch(SECOID_GetAlgorithmTag(&pki->algorithm)) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - keyTemplate = nsslowkey_RSAPrivateKeyTemplate; - paramTemplate = NULL; - paramDest = NULL; - lpk->keyType = NSSLOWKEYRSAKey; - prepare_low_rsa_priv_key_for_asn1(lpk); - break; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate; - paramTemplate = nsslowkey_PQGParamsTemplate; - paramDest = &(lpk->u.dsa.params); - lpk->keyType = NSSLOWKEYDSAKey; - prepare_low_dsa_priv_key_export_for_asn1(lpk); - prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params); - break; - /* case NSSLOWKEYDHKey: */ -#ifdef NSS_ENABLE_ECC - case SEC_OID_ANSIX962_EC_PUBLIC_KEY: - keyTemplate = nsslowkey_ECPrivateKeyTemplate; - paramTemplate = NULL; - paramDest = &(lpk->u.ec.ecParams.DEREncoding); - lpk->keyType = NSSLOWKEYECKey; - prepare_low_ec_priv_key_for_asn1(lpk); - prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams); - break; -#endif /* NSS_ENABLE_ECC */ - default: - keyTemplate = NULL; - paramTemplate = NULL; - paramDest = NULL; - break; - } - - if(!keyTemplate) { - goto loser; - } - - /* decode the private key and any algorithm parameters */ - rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey); - -#ifdef NSS_ENABLE_ECC - if (lpk->keyType == NSSLOWKEYECKey) { - /* convert length in bits to length in bytes */ - lpk->u.ec.publicValue.len >>= 3; - rv = SECITEM_CopyItem(arena, - &(lpk->u.ec.ecParams.DEREncoding), - &(pki->algorithm.parameters)); - if(rv != SECSuccess) { - goto loser; - } - } -#endif /* NSS_ENABLE_ECC */ - - if(rv != SECSuccess) { - goto loser; - } - if(paramDest && paramTemplate) { - rv = SEC_QuickDERDecodeItem(arena, paramDest, paramTemplate, - &(pki->algorithm.parameters)); - if(rv != SECSuccess) { - goto loser; - } - } - - rv = SECFailure; - - switch (lpk->keyType) { - case NSSLOWKEYRSAKey: - keyType = CKK_RSA; - if(sftk_hasAttribute(key, CKA_NETSCAPE_DB)) { - sftk_DeleteAttributeType(key, CKA_NETSCAPE_DB); - } - crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType, - sizeof(keyType)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_UNWRAP, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_DECRYPT, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_MODULUS, - sftk_item_expand(&lpk->u.rsa.modulus)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT, - sftk_item_expand(&lpk->u.rsa.publicExponent)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT, - sftk_item_expand(&lpk->u.rsa.privateExponent)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_PRIME_1, - sftk_item_expand(&lpk->u.rsa.prime1)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_PRIME_2, - sftk_item_expand(&lpk->u.rsa.prime2)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_EXPONENT_1, - sftk_item_expand(&lpk->u.rsa.exponent1)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_EXPONENT_2, - sftk_item_expand(&lpk->u.rsa.exponent2)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_COEFFICIENT, - sftk_item_expand(&lpk->u.rsa.coefficient)); - break; - case NSSLOWKEYDSAKey: - keyType = CKK_DSA; - crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK : - CKR_KEY_TYPE_INCONSISTENT; - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType, - sizeof(keyType)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_PRIME, - sftk_item_expand(&lpk->u.dsa.params.prime)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_SUBPRIME, - sftk_item_expand(&lpk->u.dsa.params.subPrime)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_BASE, - sftk_item_expand(&lpk->u.dsa.params.base)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_VALUE, - sftk_item_expand(&lpk->u.dsa.privateValue)); - if(crv != CKR_OK) break; - break; -#ifdef notdef - case NSSLOWKEYDHKey: - template = dhTemplate; - templateCount = sizeof(dhTemplate)/sizeof(CK_ATTRIBUTE); - keyType = CKK_DH; - break; -#endif - /* what about fortezza??? */ -#ifdef NSS_ENABLE_ECC - case NSSLOWKEYECKey: - keyType = CKK_EC; - crv = (sftk_hasAttribute(key, CKA_NETSCAPE_DB)) ? CKR_OK : - CKR_KEY_TYPE_INCONSISTENT; - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType, - sizeof(keyType)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_DERIVE, &cktrue, - sizeof(CK_BBOOL)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_EC_PARAMS, - sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding)); - if(crv != CKR_OK) break; - crv = sftk_AddAttributeType(key, CKA_VALUE, - sftk_item_expand(&lpk->u.ec.privateValue)); - if(crv != CKR_OK) break; - /* XXX Do we need to decode the EC Params here ?? */ - break; -#endif /* NSS_ENABLE_ECC */ - default: - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - -loser: - if(lpk) { - nsslowkey_DestroyPrivateKey(lpk); - } - - if(crv != CKR_OK) { - return SECFailure; - } - - return SECSuccess; -} - - -/* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ -CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, - CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey) -{ - SFTKObject *key = NULL; - SFTKSession *session; - CK_ULONG key_length = 0; - unsigned char * buf = NULL; - CK_RV crv = CKR_OK; - int i; - CK_ULONG bsize = ulWrappedKeyLen; - SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); - SECItem bpki; - CK_OBJECT_CLASS target_type = CKO_SECRET_KEY; - - CHECK_FORK(); - - if (!slot) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * now lets create an object to hang the attributes off of - */ - key = sftk_NewObject(slot); /* fill in the handle later */ - if (key == NULL) { - return CKR_HOST_MEMORY; - } - - /* - * load the template values into the object - */ - for (i=0; i < (int) ulAttributeCount; i++) { - if (pTemplate[i].type == CKA_VALUE_LEN) { - key_length = *(CK_ULONG *)pTemplate[i].pValue; - continue; - } - if (pTemplate[i].type == CKA_CLASS) { - target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; - } - crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i])); - if (crv != CKR_OK) break; - } - if (crv != CKR_OK) { - sftk_FreeObject(key); - return crv; - } - - crv = sftk_CryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP, - SFTK_DECRYPT, PR_FALSE); - if (crv != CKR_OK) { - sftk_FreeObject(key); - return sftk_mapWrap(crv); - } - - /* allocate the buffer to decrypt into - * this assumes the unwrapped key is never larger than the - * wrapped key. For all the mechanisms we support this is true */ - buf = (unsigned char *)PORT_Alloc( ulWrappedKeyLen); - bsize = ulWrappedKeyLen; - - crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize); - if (crv != CKR_OK) { - sftk_FreeObject(key); - PORT_Free(buf); - return sftk_mapWrap(crv); - } - - switch(target_type) { - case CKO_SECRET_KEY: - if (!sftk_hasAttribute(key,CKA_KEY_TYPE)) { - crv = CKR_TEMPLATE_INCOMPLETE; - break; - } - - if (key_length == 0 || key_length > bsize) { - key_length = bsize; - } - if (key_length > MAX_KEY_LEN) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - - /* add the value */ - crv = sftk_AddAttributeType(key,CKA_VALUE,buf,key_length); - break; - case CKO_PRIVATE_KEY: - bpki.data = (unsigned char *)buf; - bpki.len = bsize; - crv = CKR_OK; - if(sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) { - crv = CKR_TEMPLATE_INCOMPLETE; - } - break; - default: - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - - PORT_ZFree(buf, bsize); - if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } - - /* get the session */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - sftk_FreeObject(key); - return CKR_SESSION_HANDLE_INVALID; - } - - /* - * handle the base object stuff - */ - crv = sftk_handleObject(key,session); - *phKey = key->handle; - sftk_FreeSession(session); - sftk_FreeObject(key); - - return crv; - -} - -/* - * The SSL key gen mechanism create's lots of keys. This function handles the - * details of each of these key creation. - */ -static CK_RV -sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey, - PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize, - CK_OBJECT_HANDLE *keyHandle) -{ - SFTKObject *key; - SFTKSession *session; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_BBOOL cktrue = CK_TRUE; - CK_BBOOL ckfalse = CK_FALSE; - CK_RV crv = CKR_HOST_MEMORY; - - /* - * now lets create an object to hang the attributes off of - */ - *keyHandle = CK_INVALID_HANDLE; - key = sftk_NewObject(baseKey->slot); - if (key == NULL) return CKR_HOST_MEMORY; - sftk_narrowToSessionObject(key)->wasDerived = PR_TRUE; - - crv = sftk_CopyObject(key,baseKey); - if (crv != CKR_OK) goto loser; - if (isMacKey) { - crv = sftk_forceAttribute(key,CKA_KEY_TYPE,&keyType,sizeof(keyType)); - if (crv != CKR_OK) goto loser; - crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) goto loser; - crv = sftk_forceAttribute(key,CKA_ENCRYPT,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) goto loser; - crv = sftk_forceAttribute(key,CKA_DECRYPT,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) goto loser; - crv = sftk_forceAttribute(key,CKA_SIGN,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) goto loser; - crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) goto loser; - crv = sftk_forceAttribute(key,CKA_WRAP,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) goto loser; - crv = sftk_forceAttribute(key,CKA_UNWRAP,&ckfalse,sizeof(CK_BBOOL)); - if (crv != CKR_OK) goto loser; - } - crv = sftk_forceAttribute(key,CKA_VALUE,keyBlock,keySize); - if (crv != CKR_OK) goto loser; - - /* get the session */ - crv = CKR_HOST_MEMORY; - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { goto loser; } - - crv = sftk_handleObject(key,session); - sftk_FreeSession(session); - *keyHandle = key->handle; -loser: - if (key) sftk_FreeObject(key); - return crv; -} - -/* - * if there is an error, we need to free the keys we already created in SSL - * This is the routine that will do it.. - */ -static void -sftk_freeSSLKeys(CK_SESSION_HANDLE session, - CK_SSL3_KEY_MAT_OUT *returnedMaterial ) -{ - if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) { - NSC_DestroyObject(session,returnedMaterial->hClientMacSecret); - } - if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) { - NSC_DestroyObject(session, returnedMaterial->hServerMacSecret); - } - if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) { - NSC_DestroyObject(session, returnedMaterial->hClientKey); - } - if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) { - NSC_DestroyObject(session, returnedMaterial->hServerKey); - } -} - -/* - * when deriving from sensitive and extractable keys, we need to preserve some - * of the semantics in the derived key. This helper routine maintains these - * semantics. - */ -static CK_RV -sftk_DeriveSensitiveCheck(SFTKObject *baseKey,SFTKObject *destKey) -{ - PRBool hasSensitive; - PRBool sensitive = PR_FALSE; - PRBool hasExtractable; - PRBool extractable = PR_TRUE; - CK_RV crv = CKR_OK; - SFTKAttribute *att; - - hasSensitive = PR_FALSE; - att = sftk_FindAttribute(destKey,CKA_SENSITIVE); - if (att) { - hasSensitive = PR_TRUE; - sensitive = (PRBool) *(CK_BBOOL *)att->attrib.pValue; - sftk_FreeAttribute(att); - } - - hasExtractable = PR_FALSE; - att = sftk_FindAttribute(destKey,CKA_EXTRACTABLE); - if (att) { - hasExtractable = PR_TRUE; - extractable = (PRBool) *(CK_BBOOL *)att->attrib.pValue; - sftk_FreeAttribute(att); - } - - - /* don't make a key more accessible */ - if (sftk_isTrue(baseKey,CKA_SENSITIVE) && hasSensitive && - (sensitive == PR_FALSE)) { - return CKR_KEY_FUNCTION_NOT_PERMITTED; - } - if (!sftk_isTrue(baseKey,CKA_EXTRACTABLE) && hasExtractable && - (extractable == PR_TRUE)) { - return CKR_KEY_FUNCTION_NOT_PERMITTED; - } - - /* inherit parent's sensitivity */ - if (!hasSensitive) { - att = sftk_FindAttribute(baseKey,CKA_SENSITIVE); - if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT; - crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib)); - sftk_FreeAttribute(att); - if (crv != CKR_OK) return crv; - } - if (!hasExtractable) { - att = sftk_FindAttribute(baseKey,CKA_EXTRACTABLE); - if (att == NULL) return CKR_KEY_TYPE_INCONSISTENT; - crv = sftk_defaultAttribute(destKey,sftk_attr_expand(&att->attrib)); - sftk_FreeAttribute(att); - if (crv != CKR_OK) return crv; - } - - /* we should inherit the parent's always extractable/ never sensitive info, - * but handleObject always forces this attributes, so we would need to do - * something special. */ - return CKR_OK; -} - -/* - * make known fixed PKCS #11 key types to their sizes in bytes - */ -unsigned long -sftk_MapKeySize(CK_KEY_TYPE keyType) -{ - switch (keyType) { - case CKK_CDMF: - return 8; - case CKK_DES: - return 8; - case CKK_DES2: - return 16; - case CKK_DES3: - return 24; - /* IDEA and CAST need to be added */ - default: - break; - } - return 0; -} - -/* - * SSL Key generation given pre master secret - */ -#define NUM_MIXERS 9 -static const char * const mixers[NUM_MIXERS] = { - "A", - "BB", - "CCC", - "DDDD", - "EEEEE", - "FFFFFF", - "GGGGGGG", - "HHHHHHHH", - "IIIIIIIII" }; -#define SSL3_PMS_LENGTH 48 -#define SSL3_MASTER_SECRET_LENGTH 48 -#define SSL3_RANDOM_LENGTH 32 - - -/* NSC_DeriveKey derives a key from a base key, creating a new key object. */ -CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey) -{ - SFTKSession * session; - SFTKSlot * slot = sftk_SlotFromSessionHandle(hSession); - SFTKObject * key; - SFTKObject * sourceKey; - SFTKAttribute * att; - SFTKAttribute * att2; - unsigned char * buf; - SHA1Context * sha; - MD5Context * md5; - MD2Context * md2; - CK_ULONG macSize; - CK_ULONG tmpKeySize; - CK_ULONG IVSize; - CK_ULONG keySize = 0; - CK_RV crv = CKR_OK; - CK_BBOOL cktrue = CK_TRUE; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_OBJECT_CLASS classType = CKO_SECRET_KEY; - CK_KEY_DERIVATION_STRING_DATA *stringPtr; - PRBool isTLS = PR_FALSE; - PRBool isDH = PR_FALSE; - SECStatus rv; - int i; - unsigned int outLen; - unsigned char sha_out[SHA1_LENGTH]; - unsigned char key_block[NUM_MIXERS * MD5_LENGTH]; - unsigned char key_block2[MD5_LENGTH]; - PRBool isFIPS; - - CHECK_FORK(); - - if (!slot) { - return CKR_SESSION_HANDLE_INVALID; - } - /* - * now lets create an object to hang the attributes off of - */ - if (phKey) *phKey = CK_INVALID_HANDLE; - - key = sftk_NewObject(slot); /* fill in the handle later */ - if (key == NULL) { - return CKR_HOST_MEMORY; - } - isFIPS = (slot->slotID == FIPS_SLOT_ID); - - /* - * load the template values into the object - */ - for (i=0; i < (int) ulAttributeCount; i++) { - crv = sftk_AddAttributeType(key,sftk_attr_expand(&pTemplate[i])); - if (crv != CKR_OK) break; - - if (pTemplate[i].type == CKA_KEY_TYPE) { - keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue; - } - if (pTemplate[i].type == CKA_VALUE_LEN) { - keySize = *(CK_ULONG *)pTemplate[i].pValue; - } - } - if (crv != CKR_OK) { sftk_FreeObject(key); return crv; } - - if (keySize == 0) { - keySize = sftk_MapKeySize(keyType); - } - - /* Derive can only create SECRET KEY's currently... */ - classType = CKO_SECRET_KEY; - crv = sftk_forceAttribute (key,CKA_CLASS,&classType,sizeof(classType)); - if (crv != CKR_OK) { - sftk_FreeObject(key); - return crv; - } - - /* look up the base key we're deriving with */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - sftk_FreeObject(key); - return CKR_SESSION_HANDLE_INVALID; - } - - sourceKey = sftk_ObjectFromHandle(hBaseKey,session); - sftk_FreeSession(session); - if (sourceKey == NULL) { - sftk_FreeObject(key); - return CKR_KEY_HANDLE_INVALID; - } - - /* get the value of the base key */ - att = sftk_FindAttribute(sourceKey,CKA_VALUE); - if (att == NULL) { - sftk_FreeObject(key); - sftk_FreeObject(sourceKey); - return CKR_KEY_HANDLE_INVALID; - } - - switch (pMechanism->mechanism) { - /* - * generate the master secret - */ - case CKM_TLS_MASTER_KEY_DERIVE: - case CKM_TLS_MASTER_KEY_DERIVE_DH: - isTLS = PR_TRUE; - /* fall thru */ - case CKM_SSL3_MASTER_KEY_DERIVE: - case CKM_SSL3_MASTER_KEY_DERIVE_DH: - { - CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master; - SSL3RSAPreMasterSecret * rsa_pms; - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - - if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) || - (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH)) - isDH = PR_TRUE; - - /* first do the consistancy checks */ - if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) { - crv = CKR_KEY_TYPE_INCONSISTENT; - break; - } - att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE); - if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue != - CKK_GENERIC_SECRET)) { - if (att2) sftk_FreeAttribute(att2); - crv = CKR_KEY_FUNCTION_NOT_PERMITTED; - break; - } - sftk_FreeAttribute(att2); - if (keyType != CKK_GENERIC_SECRET) { - crv = CKR_KEY_FUNCTION_NOT_PERMITTED; - break; - } - if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) { - crv = CKR_KEY_FUNCTION_NOT_PERMITTED; - break; - } - - /* finally do the key gen */ - ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) - pMechanism->pParameter; - - PORT_Memcpy(crsrdata, - ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); - - if (ssl3_master->pVersion) { - SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); - rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue; - /* don't leak more key material then necessary for SSL to work */ - if ((sessKey == NULL) || sessKey->wasDerived) { - ssl3_master->pVersion->major = 0xff; - ssl3_master->pVersion->minor = 0xff; - } else { - ssl3_master->pVersion->major = rsa_pms->client_version[0]; - ssl3_master->pVersion->minor = rsa_pms->client_version[1]; - } - } - if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH) { - crv = CKR_MECHANISM_PARAM_INVALID; - break; - } - if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) { - crv = CKR_MECHANISM_PARAM_INVALID; - break; - } - - if (isTLS) { - SECStatus status; - SECItem crsr = { siBuffer, NULL, 0 }; - SECItem master = { siBuffer, NULL, 0 }; - SECItem pms = { siBuffer, NULL, 0 }; - - crsr.data = crsrdata; - crsr.len = sizeof crsrdata; - master.data = key_block; - master.len = SSL3_MASTER_SECRET_LENGTH; - pms.data = (unsigned char*)att->attrib.pValue; - pms.len = att->attrib.ulValueLen; - - status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); - if (status != SECSuccess) { - crv = CKR_FUNCTION_FAILED; - break; - } - } else { - /* now allocate the hash contexts */ - md5 = MD5_NewContext(); - if (md5 == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - sha = SHA1_NewContext(); - if (sha == NULL) { - PORT_Free(md5); - crv = CKR_HOST_MEMORY; - break; - } - for (i = 0; i < 3; i++) { - SHA1_Begin(sha); - SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); - SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - SHA1_Update(sha, crsrdata, sizeof crsrdata); - SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); - PORT_Assert(outLen == SHA1_LENGTH); - - MD5_Begin(md5); - MD5_Update(md5, (const unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - MD5_Update(md5, sha_out, outLen); - MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH); - PORT_Assert(outLen == MD5_LENGTH); - } - PORT_Free(md5); - PORT_Free(sha); - } - - /* store the results */ - crv = sftk_forceAttribute - (key,CKA_VALUE,key_block,SSL3_MASTER_SECRET_LENGTH); - if (crv != CKR_OK) break; - keyType = CKK_GENERIC_SECRET; - crv = sftk_forceAttribute (key,CKA_KEY_TYPE,&keyType,sizeof(keyType)); - if (isTLS) { - /* TLS's master secret is used to "sign" finished msgs with PRF. */ - /* XXX This seems like a hack. But SFTK_Derive only accepts - * one "operation" argument. */ - crv = sftk_forceAttribute(key,CKA_SIGN, &cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) break; - crv = sftk_forceAttribute(key,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) break; - /* While we're here, we might as well force this, too. */ - crv = sftk_forceAttribute(key,CKA_DERIVE,&cktrue,sizeof(CK_BBOOL)); - if (crv != CKR_OK) break; - } - break; - } - - case CKM_TLS_KEY_AND_MAC_DERIVE: - isTLS = PR_TRUE; - /* fall thru */ - case CKM_SSL3_KEY_AND_MAC_DERIVE: - { - CK_SSL3_KEY_MAT_PARAMS *ssl3_keys; - CK_SSL3_KEY_MAT_OUT * ssl3_keys_out; - CK_ULONG effKeySize; - unsigned int block_needed; - unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) break; - - if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH) { - crv = CKR_KEY_FUNCTION_NOT_PERMITTED; - break; - } - att2 = sftk_FindAttribute(sourceKey,CKA_KEY_TYPE); - if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue != - CKK_GENERIC_SECRET)) { - if (att2) sftk_FreeAttribute(att2); - crv = CKR_KEY_FUNCTION_NOT_PERMITTED; - break; - } - sftk_FreeAttribute(att2); - md5 = MD5_NewContext(); - if (md5 == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - sha = SHA1_NewContext(); - if (sha == NULL) { - PORT_Free(md5); - crv = CKR_HOST_MEMORY; - break; - } - ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter; - - PORT_Memcpy(srcrdata, - ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); - PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); - - PORT_Memcpy(crsrdata, - ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); - - /* - * clear out our returned keys so we can recover on failure - */ - ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial; - ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE; - ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE; - ssl3_keys_out->hClientKey = CK_INVALID_HANDLE; - ssl3_keys_out->hServerKey = CK_INVALID_HANDLE; - - /* - * How much key material do we need? - */ - macSize = ssl3_keys->ulMacSizeInBits/8; - effKeySize = ssl3_keys->ulKeySizeInBits/8; - IVSize = ssl3_keys->ulIVSizeInBits/8; - if (keySize == 0) { - effKeySize = keySize; - } - block_needed = 2 * (macSize + effKeySize + - ((!ssl3_keys->bIsExport) * IVSize)); - PORT_Assert(block_needed <= sizeof key_block); - if (block_needed > sizeof key_block) - block_needed = sizeof key_block; - - /* - * generate the key material: This looks amazingly similar to the - * PMS code, and is clearly crying out for a function to provide it. - */ - if (isTLS) { - SECStatus status; - SECItem srcr = { siBuffer, NULL, 0 }; - SECItem keyblk = { siBuffer, NULL, 0 }; - SECItem master = { siBuffer, NULL, 0 }; - - srcr.data = srcrdata; - srcr.len = sizeof srcrdata; - keyblk.data = key_block; - keyblk.len = block_needed; - master.data = (unsigned char*)att->attrib.pValue; - master.len = att->attrib.ulValueLen; - - status = TLS_PRF(&master, "key expansion", &srcr, &keyblk, - isFIPS); - if (status != SECSuccess) { - goto key_and_mac_derive_fail; - } - } else { - unsigned int block_bytes = 0; - /* key_block = - * MD5(master_secret + SHA('A' + master_secret + - * ServerHello.random + ClientHello.random)) + - * MD5(master_secret + SHA('BB' + master_secret + - * ServerHello.random + ClientHello.random)) + - * MD5(master_secret + SHA('CCC' + master_secret + - * ServerHello.random + ClientHello.random)) + - * [...]; - */ - for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) { - SHA1_Begin(sha); - SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); - SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - SHA1_Update(sha, srcrdata, sizeof srcrdata); - SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); - PORT_Assert(outLen == SHA1_LENGTH); - MD5_Begin(md5); - MD5_Update(md5, (const unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - MD5_Update(md5, sha_out, outLen); - MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH); - PORT_Assert(outLen == MD5_LENGTH); - block_bytes += outLen; - } - } - - /* - * Put the key material where it goes. - */ - i = 0; /* now shows how much consumed */ - - /* - * The key_block is partitioned as follows: - * client_write_MAC_secret[CipherSpec.hash_size] - */ - crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize, - &ssl3_keys_out->hClientMacSecret); - if (crv != CKR_OK) - goto key_and_mac_derive_fail; - - i += macSize; - - /* - * server_write_MAC_secret[CipherSpec.hash_size] - */ - crv = sftk_buildSSLKey(hSession,key,PR_TRUE,&key_block[i],macSize, - &ssl3_keys_out->hServerMacSecret); - if (crv != CKR_OK) { - goto key_and_mac_derive_fail; - } - i += macSize; - - if (keySize) { - if (!ssl3_keys->bIsExport) { - /* - ** Generate Domestic write keys and IVs. - ** client_write_key[CipherSpec.key_material] - */ - crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i], - keySize, &ssl3_keys_out->hClientKey); - if (crv != CKR_OK) { - goto key_and_mac_derive_fail; - } - i += keySize; - - /* - ** server_write_key[CipherSpec.key_material] - */ - crv = sftk_buildSSLKey(hSession,key,PR_FALSE,&key_block[i], - keySize, &ssl3_keys_out->hServerKey); - if (crv != CKR_OK) { - goto key_and_mac_derive_fail; - } - i += keySize; - - /* - ** client_write_IV[CipherSpec.IV_size] - */ - if (IVSize > 0) { - PORT_Memcpy(ssl3_keys_out->pIVClient, - &key_block[i], IVSize); - i += IVSize; - } - - /* - ** server_write_IV[CipherSpec.IV_size] - */ - if (IVSize > 0) { - PORT_Memcpy(ssl3_keys_out->pIVServer, - &key_block[i], IVSize); - i += IVSize; - } - PORT_Assert(i <= sizeof key_block); - - } else if (!isTLS) { - - /* - ** Generate SSL3 Export write keys and IVs. - ** client_write_key[CipherSpec.key_material] - ** final_client_write_key = MD5(client_write_key + - ** ClientHello.random + ServerHello.random); - */ - MD5_Begin(md5); - MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, crsrdata, sizeof crsrdata); - MD5_End(md5, key_block2, &outLen, MD5_LENGTH); - i += effKeySize; - crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, - keySize,&ssl3_keys_out->hClientKey); - if (crv != CKR_OK) { - goto key_and_mac_derive_fail; - } - - /* - ** server_write_key[CipherSpec.key_material] - ** final_server_write_key = MD5(server_write_key + - ** ServerHello.random + ClientHello.random); - */ - MD5_Begin(md5); - MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, srcrdata, sizeof srcrdata); - MD5_End(md5, key_block2, &outLen, MD5_LENGTH); - i += effKeySize; - crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, - keySize,&ssl3_keys_out->hServerKey); - if (crv != CKR_OK) { - goto key_and_mac_derive_fail; - } - - /* - ** client_write_IV = - ** MD5(ClientHello.random + ServerHello.random); - */ - MD5_Begin(md5); - MD5_Update(md5, crsrdata, sizeof crsrdata); - MD5_End(md5, key_block2, &outLen, MD5_LENGTH); - PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize); - - /* - ** server_write_IV = - ** MD5(ServerHello.random + ClientHello.random); - */ - MD5_Begin(md5); - MD5_Update(md5, srcrdata, sizeof srcrdata); - MD5_End(md5, key_block2, &outLen, MD5_LENGTH); - PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize); - - } else { - - /* - ** Generate TLS Export write keys and IVs. - */ - SECStatus status; - SECItem secret = { siBuffer, NULL, 0 }; - SECItem crsr = { siBuffer, NULL, 0 }; - SECItem keyblk = { siBuffer, NULL, 0 }; - - /* - ** client_write_key[CipherSpec.key_material] - ** final_client_write_key = PRF(client_write_key, - ** "client write key", - ** client_random + server_random); - */ - secret.data = &key_block[i]; - secret.len = effKeySize; - i += effKeySize; - crsr.data = crsrdata; - crsr.len = sizeof crsrdata; - keyblk.data = key_block2; - keyblk.len = sizeof key_block2; - status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, - isFIPS); - if (status != SECSuccess) { - goto key_and_mac_derive_fail; - } - crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2, - keySize, &ssl3_keys_out->hClientKey); - if (crv != CKR_OK) { - goto key_and_mac_derive_fail; - } - - /* - ** server_write_key[CipherSpec.key_material] - ** final_server_write_key = PRF(server_write_key, - ** "server write key", - ** client_random + server_random); - */ - secret.data = &key_block[i]; - secret.len = effKeySize; - i += effKeySize; - keyblk.data = key_block2; - keyblk.len = sizeof key_block2; - status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, - isFIPS); - if (status != SECSuccess) { - goto key_and_mac_derive_fail; - } - crv = sftk_buildSSLKey(hSession, key, PR_FALSE, key_block2, - keySize, &ssl3_keys_out->hServerKey); - if (crv != CKR_OK) { - goto key_and_mac_derive_fail; - } - - /* - ** iv_block = PRF("", "IV block", - ** client_random + server_random); - ** client_write_IV[SecurityParameters.IV_size] - ** server_write_IV[SecurityParameters.IV_size] - */ - if (IVSize) { - secret.data = NULL; - secret.len = 0; - keyblk.data = &key_block[i]; - keyblk.len = 2 * IVSize; - status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, - isFIPS); - if (status != SECSuccess) { - goto key_and_mac_derive_fail; - } - PORT_Memcpy(ssl3_keys_out->pIVClient, keyblk.data, IVSize); - PORT_Memcpy(ssl3_keys_out->pIVServer, keyblk.data + IVSize, - IVSize); - } - } - } - - crv = CKR_OK; - - if (0) { -key_and_mac_derive_fail: - if (crv == CKR_OK) - crv = CKR_FUNCTION_FAILED; - sftk_freeSSLKeys(hSession, ssl3_keys_out); - } - MD5_DestroyContext(md5, PR_TRUE); - SHA1_DestroyContext(sha, PR_TRUE); - sftk_FreeObject(key); - key = NULL; - break; - } - - case CKM_CONCATENATE_BASE_AND_KEY: - { - SFTKObject *newKey; - - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) break; - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - crv = CKR_SESSION_HANDLE_INVALID; - break; - } - - newKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *) - pMechanism->pParameter,session); - sftk_FreeSession(session); - if ( newKey == NULL) { - crv = CKR_KEY_HANDLE_INVALID; - break; - } - - if (sftk_isTrue(newKey,CKA_SENSITIVE)) { - crv = sftk_forceAttribute(newKey,CKA_SENSITIVE,&cktrue, - sizeof(CK_BBOOL)); - if (crv != CKR_OK) { - sftk_FreeObject(newKey); - break; - } - } - - att2 = sftk_FindAttribute(newKey,CKA_VALUE); - if (att2 == NULL) { - sftk_FreeObject(newKey); - crv = CKR_KEY_HANDLE_INVALID; - break; - } - tmpKeySize = att->attrib.ulValueLen+att2->attrib.ulValueLen; - if (keySize == 0) keySize = tmpKeySize; - if (keySize > tmpKeySize) { - sftk_FreeObject(newKey); - sftk_FreeAttribute(att2); - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - buf = (unsigned char*)PORT_Alloc(tmpKeySize); - if (buf == NULL) { - sftk_FreeAttribute(att2); - sftk_FreeObject(newKey); - crv = CKR_HOST_MEMORY; - break; - } - - PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen); - PORT_Memcpy(buf+att->attrib.ulValueLen, - att2->attrib.pValue,att2->attrib.ulValueLen); - - crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize); - PORT_ZFree(buf,tmpKeySize); - sftk_FreeAttribute(att2); - sftk_FreeObject(newKey); - break; - } - - case CKM_CONCATENATE_BASE_AND_DATA: - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) break; - - stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; - tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen; - if (keySize == 0) keySize = tmpKeySize; - if (keySize > tmpKeySize) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - buf = (unsigned char*)PORT_Alloc(tmpKeySize); - if (buf == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - - PORT_Memcpy(buf,att->attrib.pValue,att->attrib.ulValueLen); - PORT_Memcpy(buf+att->attrib.ulValueLen,stringPtr->pData, - stringPtr->ulLen); - - crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize); - PORT_ZFree(buf,tmpKeySize); - break; - case CKM_CONCATENATE_DATA_AND_BASE: - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) break; - - stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; - tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen; - if (keySize == 0) keySize = tmpKeySize; - if (keySize > tmpKeySize) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - buf = (unsigned char*)PORT_Alloc(tmpKeySize); - if (buf == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - - PORT_Memcpy(buf,stringPtr->pData,stringPtr->ulLen); - PORT_Memcpy(buf+stringPtr->ulLen,att->attrib.pValue, - att->attrib.ulValueLen); - - crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize); - PORT_ZFree(buf,tmpKeySize); - break; - case CKM_XOR_BASE_AND_DATA: - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) break; - - stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; - tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen); - if (keySize == 0) keySize = tmpKeySize; - if (keySize > tmpKeySize) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - buf = (unsigned char*)PORT_Alloc(keySize); - if (buf == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - - - PORT_Memcpy(buf,att->attrib.pValue,keySize); - for (i=0; i < (int)keySize; i++) { - buf[i] ^= stringPtr->pData[i]; - } - - crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize); - PORT_ZFree(buf,keySize); - break; - - case CKM_EXTRACT_KEY_FROM_KEY: - { - /* the following assumes 8 bits per byte */ - CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter; - CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */ - CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */ - - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) break; - - if (keySize == 0) { - crv = CKR_TEMPLATE_INCOMPLETE; - break; - } - /* make sure we have enough bits in the original key */ - if (att->attrib.ulValueLen < - (offset + keySize + ((shift != 0)? 1 :0)) ) { - crv = CKR_MECHANISM_PARAM_INVALID; - break; - } - buf = (unsigned char*)PORT_Alloc(keySize); - if (buf == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - - /* copy the bits we need into the new key */ - for (i=0; i < (int)keySize; i++) { - unsigned char *value = - ((unsigned char *)att->attrib.pValue)+offset+i; - if (shift) { - buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift)); - } else { - buf[i] = value[0]; - } - } - - crv = sftk_forceAttribute (key,CKA_VALUE,buf,keySize); - PORT_ZFree(buf,keySize); - break; - } - case CKM_MD2_KEY_DERIVATION: - if (keySize == 0) keySize = MD2_LENGTH; - if (keySize > MD2_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - /* now allocate the hash contexts */ - md2 = MD2_NewContext(); - if (md2 == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - MD2_Begin(md2); - MD2_Update(md2,(const unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - MD2_End(md2,key_block,&outLen,MD2_LENGTH); - MD2_DestroyContext(md2, PR_TRUE); - - crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize); - break; - case CKM_MD5_KEY_DERIVATION: - if (keySize == 0) keySize = MD5_LENGTH; - if (keySize > MD5_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - /* now allocate the hash contexts */ - md5 = MD5_NewContext(); - if (md5 == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - MD5_Begin(md5); - MD5_Update(md5,(const unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - MD5_End(md5,key_block,&outLen,MD5_LENGTH); - MD5_DestroyContext(md5, PR_TRUE); - - crv = sftk_forceAttribute (key,CKA_VALUE,key_block,keySize); - break; - case CKM_SHA1_KEY_DERIVATION: - if (keySize == 0) keySize = SHA1_LENGTH; - if (keySize > SHA1_LENGTH) { - crv = CKR_TEMPLATE_INCONSISTENT; - break; - } - /* now allocate the hash contexts */ - sha = SHA1_NewContext(); - if (sha == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - SHA1_Begin(sha); - SHA1_Update(sha,(const unsigned char*)att->attrib.pValue, - att->attrib.ulValueLen); - SHA1_End(sha,key_block,&outLen,SHA1_LENGTH); - SHA1_DestroyContext(sha, PR_TRUE); - - crv = sftk_forceAttribute(key,CKA_VALUE,key_block,keySize); - break; - - case CKM_DH_PKCS_DERIVE: - { - SECItem derived, dhPublic; - SECItem dhPrime, dhValue; - /* sourceKey - values for the local existing low key */ - /* get prime and value attributes */ - crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME); - if (crv != SECSuccess) break; - crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE); - if (crv != SECSuccess) { - PORT_Free(dhPrime.data); - break; - } - - dhPublic.data = pMechanism->pParameter; - dhPublic.len = pMechanism->ulParameterLen; - - /* calculate private value - oct */ - rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize); - - PORT_Free(dhPrime.data); - PORT_Free(dhValue.data); - - if (rv == SECSuccess) { - sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len); - PORT_ZFree(derived.data, derived.len); - } else - crv = CKR_HOST_MEMORY; - - break; - } - -#ifdef NSS_ENABLE_ECC - case CKM_ECDH1_DERIVE: - case CKM_ECDH1_COFACTOR_DERIVE: - { - SECItem ecScalar, ecPoint; - SECItem tmp; - PRBool withCofactor = PR_FALSE; - unsigned char secret_hash[20]; - unsigned char *secret; - unsigned char *keyData = NULL; - int secretlen, curveLen, pubKeyLen; - CK_ECDH1_DERIVE_PARAMS *mechParams; - NSSLOWKEYPrivateKey *privKey; - PLArenaPool *arena = NULL; - - /* Check mechanism parameters */ - mechParams = (CK_ECDH1_DERIVE_PARAMS *) pMechanism->pParameter; - if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) || - ((mechParams->kdf == CKD_NULL) && - ((mechParams->ulSharedDataLen != 0) || - (mechParams->pSharedData != NULL)))) { - crv = CKR_MECHANISM_PARAM_INVALID; - break; - } - - privKey = sftk_GetPrivKey(sourceKey, CKK_EC, &crv); - if (privKey == NULL) { - break; - } - - /* Now we are working with a non-NULL private key */ - SECITEM_CopyItem(NULL, &ecScalar, &privKey->u.ec.privateValue); - - ecPoint.data = mechParams->pPublicData; - ecPoint.len = mechParams->ulPublicDataLen; - - curveLen = (privKey->u.ec.ecParams.fieldID.size +7)/8; - pubKeyLen = (2*curveLen) + 1; - - /* if the len is too small, can't be a valid point */ - if (ecPoint.len < pubKeyLen) { - goto ec_loser; - } - /* if the len is too large, must be an encoded point (length is - * equal case just falls through */ - if (ecPoint.len > pubKeyLen) { - SECItem newPoint; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - goto ec_loser; - } - - rv = SEC_QuickDERDecodeItem(arena, &newPoint, - SEC_ASN1_GET(SEC_OctetStringTemplate), - &ecPoint); - if (rv != SECSuccess) { - goto ec_loser; - } - ecPoint = newPoint; - } - - if (pMechanism->mechanism == CKM_ECDH1_COFACTOR_DERIVE) { - withCofactor = PR_TRUE; - } else { - /* When not using cofactor derivation, one should - * validate the public key to avoid small subgroup - * attacks. - */ - if (EC_ValidatePublicKey(&privKey->u.ec.ecParams, &ecPoint) - != SECSuccess) { - goto ec_loser; - } - } - - rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar, - withCofactor, &tmp); - PORT_Free(ecScalar.data); - ecScalar.data = NULL; - if (privKey != sourceKey->objectInfo) { - nsslowkey_DestroyPrivateKey(privKey); - privKey=NULL; - } - if (arena) { - PORT_FreeArena(arena,PR_FALSE); - arena=NULL; - } - - if (rv != SECSuccess) { - crv = sftk_MapCryptError(PORT_GetError()); - break; - } - - /* - * tmp is the raw data created by ECDH_Derive, - * secret and secretlen are the values we will eventually pass as our - * generated key. - */ - secret = tmp.data; - secretlen = tmp.len; - - /* - * apply the kdf function. - */ - if (mechParams->kdf == CKD_SHA1_KDF) { - /* Compute SHA1 hash */ - PORT_Memset(secret_hash, 0, 20); - rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len); - if (rv != SECSuccess) { - PORT_ZFree(tmp.data, tmp.len); - crv = CKR_HOST_MEMORY; - break; - } - secret = secret_hash; - secretlen = 20; - } - - /* - * if keySize is supplied, then we are generating a key of a specific - * length. This is done by taking the least significant 'keySize' - * bytes from the unsigned value calculated by ECDH. Note: this may - * mean padding temp with extra leading zeros from what ECDH_Derive - * already returned (which itself may contain leading zeros). - */ - if (keySize) { - if (secretlen < keySize) { - keyData = PORT_ZAlloc(keySize); - if (!keyData) { - PORT_ZFree(tmp.data, tmp.len); - crv = CKR_HOST_MEMORY; - break; - } - PORT_Memcpy(&keyData[keySize-secretlen],secret,secretlen); - secret = keyData; - } else { - secret += (secretlen - keySize); - } - secretlen = keySize; - } - - sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); - PORT_ZFree(tmp.data, tmp.len); - if (keyData) { - PORT_ZFree(keyData, keySize); - } - PORT_Memset(secret_hash, 0, 20); - - break; - -ec_loser: - crv = CKR_ARGUMENTS_BAD; - PORT_Free(ecScalar.data); - if (privKey != sourceKey->objectInfo) - nsslowkey_DestroyPrivateKey(privKey); - if (arena) { - PORT_FreeArena(arena, PR_FALSE); - } - break; - - } -#endif /* NSS_ENABLE_ECC */ - - default: - crv = CKR_MECHANISM_INVALID; - } - sftk_FreeAttribute(att); - sftk_FreeObject(sourceKey); - if (crv != CKR_OK) { - if (key) sftk_FreeObject(key); - return crv; - } - - /* link the key object into the list */ - if (key) { - SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); - PORT_Assert(sessKey); - /* get the session */ - sessKey->wasDerived = PR_TRUE; - session = sftk_SessionFromHandle(hSession); - if (session == NULL) { - sftk_FreeObject(key); - return CKR_HOST_MEMORY; - } - - crv = sftk_handleObject(key,session); - sftk_FreeSession(session); - *phKey = key->handle; - sftk_FreeObject(key); - } - return crv; -} - - -/* NSC_GetFunctionStatus obtains an updated status of a function running - * in parallel with an application. */ -CK_RV NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession) -{ - CHECK_FORK(); - - return CKR_FUNCTION_NOT_PARALLEL; -} - -/* NSC_CancelFunction cancels a function running in parallel */ -CK_RV NSC_CancelFunction(CK_SESSION_HANDLE hSession) -{ - CHECK_FORK(); - - return CKR_FUNCTION_NOT_PARALLEL; -} - -/* NSC_GetOperationState saves the state of the cryptographic - *operation in a session. - * NOTE: This code only works for digest functions for now. eventually need - * to add full flatten/resurect to our state stuff so that all types of state - * can be saved */ -CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) -{ - SFTKSessionContext *context; - SFTKSession *session; - CK_RV crv; - CK_ULONG pOSLen = *pulOperationStateLen; - - CHECK_FORK(); - - /* make sure we're legal */ - crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session); - if (crv != CKR_OK) return crv; - - *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE) - + sizeof(SFTKContextType); - if (pOperationState == NULL) { - sftk_FreeSession(session); - return CKR_OK; - } else { - if (pOSLen < *pulOperationStateLen) { - return CKR_BUFFER_TOO_SMALL; - } - } - PORT_Memcpy(pOperationState,&context->type,sizeof(SFTKContextType)); - pOperationState += sizeof(SFTKContextType); - PORT_Memcpy(pOperationState,&context->currentMech, - sizeof(CK_MECHANISM_TYPE)); - pOperationState += sizeof(CK_MECHANISM_TYPE); - PORT_Memcpy(pOperationState,context->cipherInfo,context->cipherInfoLen); - sftk_FreeSession(session); - return CKR_OK; -} - - -#define sftk_Decrement(stateSize,len) \ - stateSize = ((stateSize) > (CK_ULONG)(len)) ? \ - ((stateSize) - (CK_ULONG)(len)) : 0; - -/* NSC_SetOperationState restores the state of the cryptographic - * operation in a session. This is coded like it can restore lots of - * states, but it only works for truly flat cipher structures. */ -CK_RV NSC_SetOperationState(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, - CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) -{ - SFTKSessionContext *context; - SFTKSession *session; - SFTKContextType type; - CK_MECHANISM mech; - CK_RV crv = CKR_OK; - - CHECK_FORK(); - - while (ulOperationStateLen != 0) { - /* get what type of state we're dealing with... */ - PORT_Memcpy(&type,pOperationState, sizeof(SFTKContextType)); - - /* fix up session contexts based on type */ - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - context = sftk_ReturnContextByType(session, type); - sftk_SetContextByType(session, type, NULL); - if (context) { - sftk_FreeContext(context); - } - pOperationState += sizeof(SFTKContextType); - sftk_Decrement(ulOperationStateLen,sizeof(SFTKContextType)); - - - /* get the mechanism structure */ - PORT_Memcpy(&mech.mechanism,pOperationState,sizeof(CK_MECHANISM_TYPE)); - pOperationState += sizeof(CK_MECHANISM_TYPE); - sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE)); - /* should be filled in... but not necessary for hash */ - mech.pParameter = NULL; - mech.ulParameterLen = 0; - switch (type) { - case SFTK_HASH: - crv = NSC_DigestInit(hSession,&mech); - if (crv != CKR_OK) break; - crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, - NULL); - if (crv != CKR_OK) break; - PORT_Memcpy(context->cipherInfo,pOperationState, - context->cipherInfoLen); - pOperationState += context->cipherInfoLen; - sftk_Decrement(ulOperationStateLen,context->cipherInfoLen); - break; - default: - /* do sign/encrypt/decrypt later */ - crv = CKR_SAVED_STATE_INVALID; - } - sftk_FreeSession(session); - if (crv != CKR_OK) break; - } - return crv; -} - -/* Dual-function cryptographic operations */ - -/* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption - * operation. */ -CK_RV NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) -{ - CK_RV crv; - - CHECK_FORK(); - - crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart, - pulEncryptedPartLen); - if (crv != CKR_OK) return crv; - crv = NSC_DigestUpdate(hSession,pPart,ulPartLen); - - return crv; -} - - -/* NSC_DecryptDigestUpdate continues a multiple-part decryption and - * digesting operation. */ -CK_RV NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, - CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) -{ - CK_RV crv; - - CHECK_FORK(); - - crv = NSC_DecryptUpdate(hSession,pEncryptedPart, ulEncryptedPartLen, - pPart, pulPartLen); - if (crv != CKR_OK) return crv; - crv = NSC_DigestUpdate(hSession,pPart,*pulPartLen); - - return crv; -} - - -/* NSC_SignEncryptUpdate continues a multiple-part signing and - * encryption operation. */ -CK_RV NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, - CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, - CK_ULONG_PTR pulEncryptedPartLen) -{ - CK_RV crv; - - CHECK_FORK(); - - crv = NSC_EncryptUpdate(hSession,pPart,ulPartLen, pEncryptedPart, - pulEncryptedPartLen); - if (crv != CKR_OK) return crv; - crv = NSC_SignUpdate(hSession,pPart,ulPartLen); - - return crv; -} - - -/* NSC_DecryptVerifyUpdate continues a multiple-part decryption - * and verify operation. */ -CK_RV NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, - CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) -{ - CK_RV crv; - - CHECK_FORK(); - - crv = NSC_DecryptUpdate(hSession,pEncryptedData, ulEncryptedDataLen, - pData, pulDataLen); - if (crv != CKR_OK) return crv; - crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen); - - return crv; -} - -/* NSC_DigestKey continues a multi-part message-digesting operation, - * by digesting the value of a secret key as part of the data already digested. - */ -CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) -{ - SFTKSession *session = NULL; - SFTKObject *key = NULL; - SFTKAttribute *att; - CK_RV crv; - - CHECK_FORK(); - - session = sftk_SessionFromHandle(hSession); - if (session == NULL) return CKR_SESSION_HANDLE_INVALID; - - key = sftk_ObjectFromHandle(hKey,session); - sftk_FreeSession(session); - if (key == NULL) return CKR_KEY_HANDLE_INVALID; - - /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */ - - /* make sure it's a valid key for this operation */ - if (key->objclass != CKO_SECRET_KEY) { - sftk_FreeObject(key); - return CKR_KEY_TYPE_INCONSISTENT; - } - /* get the key value */ - att = sftk_FindAttribute(key,CKA_VALUE); - sftk_FreeObject(key); - if (!att) { - return CKR_KEY_HANDLE_INVALID; - } - crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue, - att->attrib.ulValueLen); - sftk_FreeAttribute(att); - return crv; -} diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h deleted file mode 100644 index 32d62c945..000000000 --- a/security/nss/lib/softoken/pkcs11i.h +++ /dev/null @@ -1,716 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * Internal data structures and functions used by pkcs11.c - */ -#ifndef _PKCS11I_H_ -#define _PKCS11I_H_ 1 - -#include "nssilock.h" -#include "seccomon.h" -#include "secoidt.h" -#include "lowkeyti.h" -#include "pkcs11t.h" - -#include "sftkdbt.h" - - -/* - * Configuration Defines - * - * The following defines affect the space verse speed trade offs of - * the PKCS #11 module. For the most part the current settings are optimized - * for web servers, where we want faster speed and lower lock contention at - * the expense of space. - */ - -/* - * The attribute allocation strategy is static allocation: - * Attributes are pre-allocated as part of the session object and used from - * the object array. - */ -#define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in - * the object (must me the absolute max) */ -#define ATTR_SPACE 50 /* Maximum size of attribute data before extra - * data needs to be allocated. This is set to - * enough space to hold an SSL MASTER secret */ - -#define NSC_STRICT PR_FALSE /* forces the code to do strict template - * matching when doing C_FindObject on token - * objects. This will slow down search in - * NSS. */ -/* default search block allocations and increments */ -#define NSC_CERT_BLOCK_SIZE 50 -#define NSC_SEARCH_BLOCK_SIZE 5 -#define NSC_SLOT_LIST_BLOCK_SIZE 10 - -#define NSC_FIPS_MODULE 1 -#define NSC_NON_FIPS_MODULE 0 - -/* these are data base storage hashes, not cryptographic hashes.. The define - * the effective size of the various object hash tables */ -/* clients care more about memory usage than lookup performance on - * cyrptographic objects. Clients also have less objects around to play with - * - * we eventually should make this configurable at runtime! Especially now that - * NSS is a shared library. - */ -#define SPACE_ATTRIBUTE_HASH_SIZE 32 -#define SPACE_SESSION_OBJECT_HASH_SIZE 32 -#define SPACE_SESSION_HASH_SIZE 32 -#define TIME_ATTRIBUTE_HASH_SIZE 32 -#define TIME_SESSION_OBJECT_HASH_SIZE 1024 -#define TIME_SESSION_HASH_SIZE 1024 -#define MAX_OBJECT_LIST_SIZE 800 - /* how many objects to keep on the free list - * before we start freeing them */ -#define MAX_KEY_LEN 256 /* maximum symmetric key length in bytes */ - -#define MULTIACCESS "multiaccess:" - -/* - * LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number. - * With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0. - * With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0. - * - * HASH_SIZE LOG2_BUCKETS_PER BUCKETS_PER_LOCK NUMBER_OF_BUCKETS - * 1024 9 512 2 - * 1024 5 32 32 - * 1024 1 2 512 - * 1024 0 1 1024 - * 4096 11 2048 2 - * 4096 9 512 8 - * 4096 5 32 128 - * 4096 1 2 2048 - * 4096 0 1 4096 - */ -#define LOG2_BUCKETS_PER_SESSION_LOCK 1 -#define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK)) -/* NOSPREAD sessionID to hash table index macro has been slower. */ - -/* define typedefs, double as forward declarations as well */ -typedef struct SFTKAttributeStr SFTKAttribute; -typedef struct SFTKObjectListStr SFTKObjectList; -typedef struct SFTKObjectFreeListStr SFTKObjectFreeList; -typedef struct SFTKObjectListElementStr SFTKObjectListElement; -typedef struct SFTKObjectStr SFTKObject; -typedef struct SFTKSessionObjectStr SFTKSessionObject; -typedef struct SFTKTokenObjectStr SFTKTokenObject; -typedef struct SFTKSessionStr SFTKSession; -typedef struct SFTKSlotStr SFTKSlot; -typedef struct SFTKSessionContextStr SFTKSessionContext; -typedef struct SFTKSearchResultsStr SFTKSearchResults; -typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo; -typedef struct SFTKHashSignInfoStr SFTKHashSignInfo; -typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo; -typedef struct SFTKItemTemplateStr SFTKItemTemplate; - -/* define function pointer typdefs for pointer tables */ -typedef void (*SFTKDestroy)(void *, PRBool); -typedef void (*SFTKBegin)(void *); -typedef SECStatus (*SFTKCipher)(void *,void *,unsigned int *,unsigned int, - void *, unsigned int); -typedef SECStatus (*SFTKVerify)(void *,void *,unsigned int,void *,unsigned int); -typedef void (*SFTKHash)(void *,void *,unsigned int); -typedef void (*SFTKEnd)(void *,void *,unsigned int *,unsigned int); -typedef void (*SFTKFree)(void *); - -/* Value to tell if an attribute is modifiable or not. - * NEVER: attribute is only set on creation. - * ONCOPY: attribute is set on creation and can only be changed on copy. - * SENSITIVE: attribute can only be changed to TRUE. - * ALWAYS: attribute can always be changed. - */ -typedef enum { - SFTK_NEVER = 0, - SFTK_ONCOPY = 1, - SFTK_SENSITIVE = 2, - SFTK_ALWAYS = 3 -} SFTKModifyType; - -/* - * Free Status Enum... tell us more information when we think we're - * deleting an object. - */ -typedef enum { - SFTK_DestroyFailure, - SFTK_Destroyed, - SFTK_Busy -} SFTKFreeStatus; - -/* - * attribute values of an object. - */ -struct SFTKAttributeStr { - SFTKAttribute *next; - SFTKAttribute *prev; - PRBool freeAttr; - PRBool freeData; - /*must be called handle to make sftkqueue_find work */ - CK_ATTRIBUTE_TYPE handle; - CK_ATTRIBUTE attrib; - unsigned char space[ATTR_SPACE]; -}; - - -/* - * doubly link list of objects - */ -struct SFTKObjectListStr { - SFTKObjectList *next; - SFTKObjectList *prev; - SFTKObject *parent; -}; - -struct SFTKObjectFreeListStr { - SFTKObject *head; - PZLock *lock; - int count; -}; - -/* - * PKCS 11 crypto object structure - */ -struct SFTKObjectStr { - SFTKObject *next; - SFTKObject *prev; - CK_OBJECT_CLASS objclass; - CK_OBJECT_HANDLE handle; - int refCount; - PZLock *refLock; - SFTKSlot *slot; - void *objectInfo; - SFTKFree infoFree; -}; - -struct SFTKTokenObjectStr { - SFTKObject obj; - SECItem dbKey; -}; - -struct SFTKSessionObjectStr { - SFTKObject obj; - SFTKObjectList sessionList; - PZLock *attributeLock; - SFTKSession *session; - PRBool wasDerived; - int nextAttr; - SFTKAttribute attrList[MAX_OBJS_ATTRS]; - PRBool optimizeSpace; - unsigned int hashSize; - SFTKAttribute *head[1]; -}; - -/* - * struct to deal with a temparary list of objects - */ -struct SFTKObjectListElementStr { - SFTKObjectListElement *next; - SFTKObject *object; -}; - -/* - * Area to hold Search results - */ -struct SFTKSearchResultsStr { - CK_OBJECT_HANDLE *handles; - int size; - int index; - int array_size; -}; - - -/* - * the universal crypto/hash/sign/verify context structure - */ -typedef enum { - SFTK_ENCRYPT, - SFTK_DECRYPT, - SFTK_HASH, - SFTK_SIGN, - SFTK_SIGN_RECOVER, - SFTK_VERIFY, - SFTK_VERIFY_RECOVER -} SFTKContextType; - - -#define SFTK_MAX_BLOCK_SIZE 16 -/* currently SHA512 is the biggest hash length */ -#define SFTK_MAX_MAC_LENGTH 64 -#define SFTK_INVALID_MAC_SIZE 0xffffffff - -struct SFTKSessionContextStr { - SFTKContextType type; - PRBool multi; /* is multipart */ - PRBool doPad; /* use PKCS padding for block ciphers */ - unsigned int blockSize; /* blocksize for padding */ - unsigned int padDataLength; /* length of the valid data in padbuf */ - unsigned char padBuf[SFTK_MAX_BLOCK_SIZE]; - unsigned char macBuf[SFTK_MAX_BLOCK_SIZE]; - CK_ULONG macSize; /* size of a general block cipher mac*/ - void *cipherInfo; - void *hashInfo; - unsigned int cipherInfoLen; - CK_MECHANISM_TYPE currentMech; - SFTKCipher update; - SFTKHash hashUpdate; - SFTKEnd end; - SFTKDestroy destroy; - SFTKDestroy hashdestroy; - SFTKVerify verify; - unsigned int maxLen; - SFTKObject *key; -}; - -/* - * Sessions (have objects) - */ -struct SFTKSessionStr { - SFTKSession *next; - SFTKSession *prev; - CK_SESSION_HANDLE handle; - int refCount; - PZLock *objectLock; - int objectIDCount; - CK_SESSION_INFO info; - CK_NOTIFY notify; - CK_VOID_PTR appData; - SFTKSlot *slot; - SFTKSearchResults *search; - SFTKSessionContext *enc_context; - SFTKSessionContext *hash_context; - SFTKSessionContext *sign_context; - SFTKObjectList *objects[1]; -}; - -/* - * slots (have sessions and objects) - * - * The array of sessionLock's protect the session hash table (head[]) - * as well as the reference count of session objects in that bucket - * (head[]->refCount), objectLock protects all elements of the slot's - * object hash tables (sessObjHashTable[] and tokObjHashTable), and - * sessionObjectHandleCount. - * slotLock protects the remaining protected elements: - * password, isLoggedIn, ssoLoggedIn, and sessionCount, - * and pwCheckLock serializes the key database password checks in - * NSC_SetPIN and NSC_Login. - * - * Each of the fields below has the following lifetime as commented - * next to the fields: - * invariant - This value is set when the slot is first created and - * never changed until it is destroyed. - * per load - This value is set when the slot is first created, or - * when the slot is used to open another directory. Between open and close - * this field does not change. - * variable - This value changes through the normal process of slot operation. - * - reset. The value of this variable is cleared during an open/close - * cycles. - * - preserved. The value of this variable is preserved over open/close - * cycles. - */ -struct SFTKSlotStr { - CK_SLOT_ID slotID; /* invariant */ - PZLock *slotLock; /* invariant */ - PZLock **sessionLock; /* invariant */ - unsigned int numSessionLocks; /* invariant */ - unsigned long sessionLockMask; /* invariant */ - PZLock *objectLock; /* invariant */ - PRLock *pwCheckLock; /* invariant */ - PRBool present; /* variable -set */ - PRBool hasTokens; /* per load */ - PRBool isLoggedIn; /* variable - reset */ - PRBool ssoLoggedIn; /* variable - reset */ - PRBool needLogin; /* per load */ - PRBool DB_loaded; /* per load */ - PRBool readOnly; /* per load */ - PRBool optimizeSpace; /* invariant */ - SFTKDBHandle *certDB; /* per load */ - SFTKDBHandle *keyDB; /* per load */ - int minimumPinLen; /* per load */ - PRInt32 sessionIDCount; /* atomically incremented */ - /* (preserved) */ - int sessionIDConflict; /* not protected by a lock */ - /* (preserved) */ - int sessionCount; /* variable - reset */ - PRInt32 rwSessionCount; /* set by atomic operations */ - /* (reset) */ - int sessionObjectHandleCount;/* variable - perserved */ - int index; /* invariant */ - PLHashTable *tokObjHashTable; /* invariant */ - SFTKObject **sessObjHashTable; /* variable - reset */ - unsigned int sessObjHashSize; /* invariant */ - SFTKSession **head; /* variable -reset */ - unsigned int sessHashSize; /* invariant */ - char tokDescription[33]; /* per load */ - char updateTokDescription[33]; /* per load */ - char slotDescription[65]; /* invariant */ -}; - -/* - * special joint operations Contexts - */ -struct SFTKHashVerifyInfoStr { - SECOidTag hashOid; - NSSLOWKEYPublicKey *key; -}; - -struct SFTKHashSignInfoStr { - SECOidTag hashOid; - NSSLOWKEYPrivateKey *key; -}; - -/* context for the Final SSLMAC message */ -struct SFTKSSLMACInfoStr { - void *hashContext; - SFTKBegin begin; - SFTKHash update; - SFTKEnd end; - CK_ULONG macSize; - int padSize; - unsigned char key[MAX_KEY_LEN]; - unsigned int keySize; -}; - -/* - * Template based on SECItems, suitable for passing as arrays - */ -struct SFTKItemTemplateStr { - CK_ATTRIBUTE_TYPE type; - SECItem *item; -}; - -/* macro for setting SFTKTemplates. */ -#define SFTK_SET_ITEM_TEMPLATE(templ, count, itemPtr, attr) \ - templ[count].type = attr; \ - templ[count].item = itemPtr - -#define SFTK_MAX_ITEM_TEMPLATE 10 - -/* - * session handle modifiers - */ -#define SFTK_SESSION_SLOT_MASK 0xff000000L - -/* - * object handle modifiers - */ -#define SFTK_TOKEN_MASK 0x80000000L -#define SFTK_TOKEN_MAGIC 0x80000000L -#define SFTK_TOKEN_TYPE_MASK 0x70000000L -/* keydb (high bit == 0) */ -#define SFTK_TOKEN_TYPE_PRIV 0x10000000L -#define SFTK_TOKEN_TYPE_PUB 0x20000000L -#define SFTK_TOKEN_TYPE_KEY 0x30000000L -/* certdb (high bit == 1) */ -#define SFTK_TOKEN_TYPE_TRUST 0x40000000L -#define SFTK_TOKEN_TYPE_CRL 0x50000000L -#define SFTK_TOKEN_TYPE_SMIME 0x60000000L -#define SFTK_TOKEN_TYPE_CERT 0x70000000L - -#define SFTK_TOKEN_KRL_HANDLE (SFTK_TOKEN_MAGIC|SFTK_TOKEN_TYPE_CRL|1) -/* how big (in bytes) a password/pin we can deal with */ -#define SFTK_MAX_PIN 255 -/* minimum password/pin length (in Unicode characters) in FIPS mode */ -#define FIPS_MIN_PIN 7 - -/* slot ID's */ -#define NETSCAPE_SLOT_ID 1 -#define PRIVATE_KEY_SLOT_ID 2 -#define FIPS_SLOT_ID 3 - -/* slot helper macros */ -#define sftk_SlotFromSession(sp) ((sp)->slot) -#define sftk_isToken(id) (((id) & SFTK_TOKEN_MASK) == SFTK_TOKEN_MAGIC) - -/* the session hash multiplier (see bug 201081) */ -#define SHMULTIPLIER 1791398085 - -/* queueing helper macros */ -#define sftk_hash(value,size) \ - ((PRUint32)((value) * SHMULTIPLIER) & (size-1)) -#define sftkqueue_add(element,id,head,hash_size) \ - { int tmp = sftk_hash(id,hash_size); \ - (element)->next = (head)[tmp]; \ - (element)->prev = NULL; \ - if ((head)[tmp]) (head)[tmp]->prev = (element); \ - (head)[tmp] = (element); } -#define sftkqueue_find(element,id,head,hash_size) \ - for( (element) = (head)[sftk_hash(id,hash_size)]; (element) != NULL; \ - (element) = (element)->next) { \ - if ((element)->handle == (id)) { break; } } -#define sftkqueue_is_queued(element,id,head,hash_size) \ - ( ((element)->next) || ((element)->prev) || \ - ((head)[sftk_hash(id,hash_size)] == (element)) ) -#define sftkqueue_delete(element,id,head,hash_size) \ - if ((element)->next) (element)->next->prev = (element)->prev; \ - if ((element)->prev) (element)->prev->next = (element)->next; \ - else (head)[sftk_hash(id,hash_size)] = ((element)->next); \ - (element)->next = NULL; \ - (element)->prev = NULL; \ - -#define sftkqueue_init_element(element) \ - (element)->prev = NULL; - -#define sftkqueue_add2(element, id, index, head) \ - { \ - (element)->next = (head)[index]; \ - if ((head)[index]) \ - (head)[index]->prev = (element); \ - (head)[index] = (element); \ - } - -#define sftkqueue_find2(element, id, index, head) \ - for ( (element) = (head)[index]; \ - (element) != NULL; \ - (element) = (element)->next) { \ - if ((element)->handle == (id)) { break; } \ - } - -#define sftkqueue_delete2(element, id, index, head) \ - if ((element)->next) (element)->next->prev = (element)->prev; \ - if ((element)->prev) (element)->prev->next = (element)->next; \ - else (head)[index] = ((element)->next); - -#define sftkqueue_clear_deleted_element(element) \ - (element)->next = NULL; \ - (element)->prev = NULL; \ - - -/* sessionID (handle) is used to determine session lock bucket */ -#ifdef NOSPREAD -/* NOSPREAD: (ID>>L2LPB) & (perbucket-1) */ -#define SFTK_SESSION_LOCK(slot,handle) \ - ((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) \ - & (slot)->sessionLockMask]) -#else -/* SPREAD: ID & (perbucket-1) */ -#define SFTK_SESSION_LOCK(slot,handle) \ - ((slot)->sessionLock[(handle) & (slot)->sessionLockMask]) -#endif - -/* expand an attribute & secitem structures out */ -#define sftk_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen -#define sftk_item_expand(ip) (ip)->data,(ip)->len - -typedef struct sftk_token_parametersStr { - CK_SLOT_ID slotID; - char *configdir; - char *certPrefix; - char *keyPrefix; - char *updatedir; - char *updCertPrefix; - char *updKeyPrefix; - char *updateID; - char *tokdes; - char *slotdes; - char *updtokdes; - int minPW; - PRBool readOnly; - PRBool noCertDB; - PRBool noKeyDB; - PRBool forceOpen; - PRBool pwRequired; - PRBool optimizeSpace; -} sftk_token_parameters; - -typedef struct sftk_parametersStr { - char *configdir; - char *updatedir; - char *updateID; - char *secmodName; - char *man; - char *libdes; - PRBool readOnly; - PRBool noModDB; - PRBool noCertDB; - PRBool forceOpen; - PRBool pwRequired; - PRBool optimizeSpace; - sftk_token_parameters *tokens; - int token_count; -} sftk_parameters; - - -/* machine dependent path stuff used by dbinit.c and pk11db.c */ -#ifdef macintosh -#define PATH_SEPARATOR ":" -#define SECMOD_DB "Security Modules" -#define CERT_DB_FMT "%sCertificates%s" -#define KEY_DB_FMT "%sKey Database%s" -#else -#define PATH_SEPARATOR "/" -#define SECMOD_DB "secmod.db" -#define CERT_DB_FMT "%scert%s.db" -#define KEY_DB_FMT "%skey%s.db" -#endif - -SEC_BEGIN_PROTOS - -/* shared functions between pkcs11.c and fipstokn.c */ -extern PRBool nsf_init; -extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS); -extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS); -extern PRBool sftk_ForkReset(CK_VOID_PTR pReserved, CK_RV* crv); -extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent, - CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex); - -/* slot initialization, reinit, shutdown and destruction */ -extern CK_RV SFTK_SlotInit(char *configdir, char *updatedir, char *updateID, - sftk_token_parameters *params, int moduleIndex); -extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir, - char *updatedir, char *updateID, - sftk_token_parameters *params, int moduleIndex); -extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot); -extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot); -extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout); - - -/* internal utility functions used by pkcs11.c */ -extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object, - CK_ATTRIBUTE_TYPE type); -extern void sftk_FreeAttribute(SFTKAttribute *attribute); -extern CK_RV sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type, - void *valPtr, - CK_ULONG length); -extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, - SFTKObject *object, CK_ATTRIBUTE_TYPE type); -extern CK_RV sftk_MultipleAttribute2SecItem(PLArenaPool *arena, - SFTKObject *object, SFTKItemTemplate *templ, int count); -extern unsigned int sftk_GetLengthInBits(unsigned char *buf, - unsigned int bufLen); -extern CK_RV sftk_ConstrainAttribute(SFTKObject *object, - CK_ATTRIBUTE_TYPE type, int minLength, int maxLength, int minMultiple); -extern PRBool sftk_hasAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type); -extern PRBool sftk_isTrue(SFTKObject *object, CK_ATTRIBUTE_TYPE type); -extern void sftk_DeleteAttributeType(SFTKObject *object, - CK_ATTRIBUTE_TYPE type); -extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, - SFTKObject *object, CK_ATTRIBUTE_TYPE type); -extern CK_RV sftk_Attribute2SSecItem(PLArenaPool *arena, SECItem *item, - SFTKObject *object, - CK_ATTRIBUTE_TYPE type); -extern SFTKModifyType sftk_modifyType(CK_ATTRIBUTE_TYPE type, - CK_OBJECT_CLASS inClass); -extern PRBool sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass); -extern char *sftk_getString(SFTKObject *object, CK_ATTRIBUTE_TYPE type); -extern void sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type); -extern CK_RV sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, - CK_ULONG *longData); -extern CK_RV sftk_forceAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, - void *value, unsigned int len); -extern CK_RV sftk_defaultAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, - void *value, unsigned int len); -extern unsigned int sftk_MapTrust(CK_TRUST trust, PRBool clientAuth); - -extern SFTKObject *sftk_NewObject(SFTKSlot *slot); -extern CK_RV sftk_CopyObject(SFTKObject *destObject, SFTKObject *srcObject); -extern SFTKFreeStatus sftk_FreeObject(SFTKObject *object); -extern CK_RV sftk_DeleteObject(SFTKSession *session, SFTKObject *object); -extern void sftk_ReferenceObject(SFTKObject *object); -extern SFTKObject *sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, - SFTKSession *session); -extern void sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object); -extern void sftk_AddObject(SFTKSession *session, SFTKObject *object); -/* clear out all the existing object ID to database key mappings. - * used to reinit a token */ -extern CK_RV SFTK_ClearTokenKeyHashTable(SFTKSlot *slot); - -extern CK_RV sftk_searchObjectList(SFTKSearchResults *search, - SFTKObject **head, unsigned int size, - PZLock *lock, CK_ATTRIBUTE_PTR inTemplate, - int count, PRBool isLoggedIn); -extern SFTKObjectListElement *sftk_FreeObjectListElement( - SFTKObjectListElement *objectList); -extern void sftk_FreeObjectList(SFTKObjectListElement *objectList); -extern void sftk_FreeSearch(SFTKSearchResults *search); -extern CK_RV sftk_handleObject(SFTKObject *object, SFTKSession *session); - -extern SFTKSlot *sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all); -extern SFTKSlot *sftk_SlotFromSessionHandle(CK_SESSION_HANDLE handle); -extern SFTKSession *sftk_SessionFromHandle(CK_SESSION_HANDLE handle); -extern void sftk_FreeSession(SFTKSession *session); -extern SFTKSession *sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, - CK_VOID_PTR pApplication, CK_FLAGS flags); -extern void sftk_update_state(SFTKSlot *slot,SFTKSession *session); -extern void sftk_update_all_states(SFTKSlot *slot); -extern void sftk_FreeContext(SFTKSessionContext *context); -extern void sftk_InitFreeLists(void); -extern void sftk_CleanupFreeLists(void); - -extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object, - CK_KEY_TYPE key_type, CK_RV *crvp); -extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object, - CK_KEY_TYPE key_type, CK_RV *crvp); -extern void sftk_FormatDESKey(unsigned char *key, int length); -extern PRBool sftk_CheckDESKey(unsigned char *key); -extern PRBool sftk_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type); - -/* mechanism allows this operation */ -extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op); - -/* helper function which calls nsslowkey_FindKeyByPublicKey after safely - * acquiring a reference to the keydb from the slot */ -NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey); - -/* - * narrow objects - */ -SFTKSessionObject * sftk_narrowToSessionObject(SFTKObject *); -SFTKTokenObject * sftk_narrowToTokenObject(SFTKObject *); - -/* - * token object utilities - */ -void sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle); -PRBool sftk_poisonHandle(SFTKSlot *slot, SECItem *dbkey, - CK_OBJECT_HANDLE handle); -SFTKObject * sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, - CK_OBJECT_HANDLE handle); -SFTKTokenObject *sftk_convertSessionToToken(SFTKObject *so); - -/**************************************** - * implement TLS Pseudo Random Function (PRF) - */ - -extern CK_RV -sftk_TLSPRFInit(SFTKSessionContext *context, - SFTKObject * key, - CK_KEY_TYPE key_type); - -SEC_END_PROTOS - -#endif /* _PKCS11I_H_ */ diff --git a/security/nss/lib/softoken/pkcs11ni.h b/security/nss/lib/softoken/pkcs11ni.h deleted file mode 100644 index 9e584a9f0..000000000 --- a/security/nss/lib/softoken/pkcs11ni.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 - * Red Hat, Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _PKCS11NI_H_ -#define _PKCS11NI_H_ - -/* - * pkcs11ni.h - * - * This file contains softoken private exports for NSS - */ - -/* softoken slot ID's */ -#define SFTK_MIN_USER_SLOT_ID 4 -#define SFTK_MAX_USER_SLOT_ID 100 -#define SFTK_MIN_FIPS_USER_SLOT_ID 101 -#define SFTK_MAX_FIPS_USER_SLOT_ID 127 - - -#endif /* _PKCS11NI_H_ */ diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c deleted file mode 100644 index a416c63f6..000000000 --- a/security/nss/lib/softoken/pkcs11u.c +++ /dev/null @@ -1,2012 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * Internal PKCS #11 functions. Should only be called by pkcs11.c - */ -#include "pkcs11.h" -#include "pkcs11i.h" -#include "lowkeyi.h" -#include "secasn1.h" -#include "blapi.h" -#include "secerr.h" -#include "prnetdb.h" /* for PR_ntohl */ -#include "sftkdb.h" -#include "softoken.h" - -/* - * ******************** Attribute Utilities ******************************* - */ - -/* - * create a new attribute with type, value, and length. Space is allocated - * to hold value. - */ -static SFTKAttribute * -sftk_NewAttribute(SFTKObject *object, - CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value, CK_ULONG len) -{ - SFTKAttribute *attribute; - - SFTKSessionObject *so = sftk_narrowToSessionObject(object); - int index; - - if (so == NULL) { - /* allocate new attribute in a buffer */ - PORT_Assert(0); - return NULL; - } - /* - * We attempt to keep down contention on Malloc and Arena locks by - * limiting the number of these calls on high traversed paths. This - * is done for attributes by 'allocating' them from a pool already - * allocated by the parent object. - */ - PZ_Lock(so->attributeLock); - index = so->nextAttr++; - PZ_Unlock(so->attributeLock); - PORT_Assert(index < MAX_OBJS_ATTRS); - if (index >= MAX_OBJS_ATTRS) return NULL; - - attribute = &so->attrList[index]; - attribute->attrib.type = type; - attribute->freeAttr = PR_FALSE; - attribute->freeData = PR_FALSE; - if (value) { - if (len <= ATTR_SPACE) { - attribute->attrib.pValue = attribute->space; - } else { - attribute->attrib.pValue = PORT_Alloc(len); - attribute->freeData = PR_TRUE; - } - if (attribute->attrib.pValue == NULL) { - return NULL; - } - PORT_Memcpy(attribute->attrib.pValue,value,len); - attribute->attrib.ulValueLen = len; - } else { - attribute->attrib.pValue = NULL; - attribute->attrib.ulValueLen = 0; - } - attribute->attrib.type = type; - attribute->handle = type; - attribute->next = attribute->prev = NULL; - return attribute; -} - -/* - * Free up all the memory associated with an attribute. Reference count - * must be zero to call this. - */ -static void -sftk_DestroyAttribute(SFTKAttribute *attribute) -{ - if (attribute->freeData) { - if (attribute->attrib.pValue) { - /* clear out the data in the attribute value... it may have been - * sensitive data */ - PORT_Memset(attribute->attrib.pValue, 0, - attribute->attrib.ulValueLen); - } - PORT_Free(attribute->attrib.pValue); - } - PORT_Free(attribute); -} - -/* - * release a reference to an attribute structure - */ -void -sftk_FreeAttribute(SFTKAttribute *attribute) -{ - if (attribute->freeAttr) { - sftk_DestroyAttribute(attribute); - return; - } -} - -static SFTKAttribute * -sftk_FindTokenAttribute(SFTKTokenObject *object,CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *myattribute = NULL; - SFTKDBHandle *dbHandle = NULL; - CK_RV crv; - - myattribute = (SFTKAttribute*)PORT_Alloc(sizeof(SFTKAttribute)); - if (myattribute == NULL) { - goto loser; - } - - dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle); - - myattribute->handle = type; - myattribute->attrib.type = type; - myattribute->attrib.pValue = myattribute->space; - myattribute->attrib.ulValueLen = ATTR_SPACE; - myattribute->next = myattribute->prev = NULL; - myattribute->freeAttr = PR_TRUE; - myattribute->freeData = PR_FALSE; - - crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, - &myattribute->attrib, 1); - - /* attribute is bigger than our attribute space buffer, malloc it */ - if (crv == CKR_BUFFER_TOO_SMALL) { - myattribute->attrib.pValue = NULL; - crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, - &myattribute->attrib, 1); - if (crv != CKR_OK) { - goto loser; - } - myattribute->attrib.pValue = PORT_Alloc(myattribute->attrib.ulValueLen); - if (myattribute->attrib.pValue == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - myattribute->freeData = PR_TRUE; - crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, - &myattribute->attrib, 1); - } -loser: - if (dbHandle) { - sftk_freeDB(dbHandle); - } - if (crv != CKR_OK) { - if (myattribute) { - myattribute->attrib.ulValueLen = 0; - sftk_FreeAttribute(myattribute); - myattribute = NULL; - } - } - return myattribute; -} - -/* - * look up and attribute structure from a type and Object structure. - * The returned attribute is referenced and needs to be freed when - * it is no longer needed. - */ -SFTKAttribute * -sftk_FindAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *attribute; - SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object); - - if (sessObject == NULL) { - return sftk_FindTokenAttribute(sftk_narrowToTokenObject(object),type); - } - - PZ_Lock(sessObject->attributeLock); - sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize); - PZ_Unlock(sessObject->attributeLock); - - return(attribute); -} - -/* - * Take a buffer and it's length and return it's true size in bits; - */ -unsigned int -sftk_GetLengthInBits(unsigned char *buf, unsigned int bufLen) -{ - unsigned int size = bufLen * 8; - unsigned int i; - - /* Get the real length in bytes */ - for (i=0; i < bufLen; i++) { - unsigned char c = *buf++; - if (c != 0) { - unsigned char m; - for (m=0x80; m > 0 ; m = m >> 1) { - if ((c & m) != 0) { - break; - } - size--; - } - break; - } - size-=8; - } - return size; -} - -/* - * Constrain a big num attribute. to size and padding - * minLength means length of the object must be greater than equal to minLength - * maxLength means length of the object must be less than equal to maxLength - * minMultiple means that object length mod minMultiple must equal 0. - * all input sizes are in bits. - * if any constraint is '0' that constraint is not checked. - */ -CK_RV -sftk_ConstrainAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, - int minLength, int maxLength, int minMultiple) -{ - SFTKAttribute *attribute; - int size; - unsigned char *ptr; - - attribute = sftk_FindAttribute(object, type); - if (!attribute) { - return CKR_TEMPLATE_INCOMPLETE; - } - ptr = (unsigned char *) attribute->attrib.pValue; - if (ptr == NULL) { - sftk_FreeAttribute(attribute); - return CKR_ATTRIBUTE_VALUE_INVALID; - } - size = sftk_GetLengthInBits(ptr, attribute->attrib.ulValueLen); - sftk_FreeAttribute(attribute); - - if ((minLength != 0) && (size < minLength)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - if ((maxLength != 0) && (size > maxLength)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - if ((minMultiple != 0) && ((size % minMultiple) != 0)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - return CKR_OK; -} - -PRBool -sftk_hasAttributeToken(SFTKTokenObject *object, CK_ATTRIBUTE_TYPE type) -{ - CK_ATTRIBUTE template; - CK_RV crv; - SFTKDBHandle *dbHandle; - - dbHandle = sftk_getDBForTokenObject(object->obj.slot, object->obj.handle); - template.type = type; - template.pValue = NULL; - template.ulValueLen = 0; - - crv = sftkdb_GetAttributeValue(dbHandle, object->obj.handle, &template, 1); - sftk_freeDB(dbHandle); - - /* attribute is bigger than our attribute space buffer, malloc it */ - return (crv == CKR_OK) ? PR_TRUE : PR_FALSE; -} - -/* - * return true if object has attribute - */ -PRBool -sftk_hasAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *attribute; - SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object); - - if (sessObject == NULL) { - return sftk_hasAttributeToken(sftk_narrowToTokenObject(object), type); - } - - PZ_Lock(sessObject->attributeLock); - sftkqueue_find(attribute,type,sessObject->head, sessObject->hashSize); - PZ_Unlock(sessObject->attributeLock); - - return (PRBool)(attribute != NULL); -} - -/* - * add an attribute to an object - */ -static void -sftk_AddAttribute(SFTKObject *object,SFTKAttribute *attribute) -{ - SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object); - - if (sessObject == NULL) return; - PZ_Lock(sessObject->attributeLock); - sftkqueue_add(attribute,attribute->handle, - sessObject->head, sessObject->hashSize); - PZ_Unlock(sessObject->attributeLock); -} - -/* - * copy an unsigned attribute into a SECItem. Secitem is allocated in - * the specified arena. - */ -CK_RV -sftk_Attribute2SSecItem(PLArenaPool *arena,SECItem *item,SFTKObject *object, - CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *attribute; - - item->data = NULL; - - attribute = sftk_FindAttribute(object, type); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - - (void)SECITEM_AllocItem(arena, item, attribute->attrib.ulValueLen); - if (item->data == NULL) { - sftk_FreeAttribute(attribute); - return CKR_HOST_MEMORY; - } - PORT_Memcpy(item->data, attribute->attrib.pValue, item->len); - sftk_FreeAttribute(attribute); - return CKR_OK; -} - -/* - * fetch multiple attributes into SECItems. Secitem data is allocated in - * the specified arena. - */ -CK_RV -sftk_MultipleAttribute2SecItem(PLArenaPool *arena, SFTKObject *object, - SFTKItemTemplate *itemTemplate, int itemTemplateCount) -{ - - CK_RV crv = CKR_OK; - CK_ATTRIBUTE templateSpace[SFTK_MAX_ITEM_TEMPLATE]; - CK_ATTRIBUTE *template; - SFTKTokenObject *tokObject; - SFTKDBHandle *dbHandle = NULL; - int i; - - tokObject = sftk_narrowToTokenObject(object); - - /* session objects, just loop through the list */ - if (tokObject == NULL) { - for (i=0; i < itemTemplateCount; i++) { - crv = sftk_Attribute2SecItem(arena,itemTemplate[i].item, object, - itemTemplate[i].type); - if (crv != CKR_OK) { - return crv; - } - } - return CKR_OK; - } - - /* don't do any work if none is required */ - if (itemTemplateCount == 0) { - return CKR_OK; - } - - /* don't allocate the template unless we need it */ - if (itemTemplateCount > SFTK_MAX_ITEM_TEMPLATE) { - template = PORT_NewArray(CK_ATTRIBUTE, itemTemplateCount); - } else { - template = templateSpace; - } - - if (template == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - - dbHandle = sftk_getDBForTokenObject(object->slot, object->handle); - if (dbHandle == NULL) { - crv = CKR_OBJECT_HANDLE_INVALID; - goto loser; - } - - /* set up the PKCS #11 template */ - for (i=0; i < itemTemplateCount; i++) { - template[i].type = itemTemplate[i].type; - template[i].pValue = NULL; - template[i].ulValueLen = 0; - } - - /* fetch the attribute lengths */ - crv = sftkdb_GetAttributeValue(dbHandle, object->handle, - template, itemTemplateCount); - if (crv != CKR_OK) { - goto loser; - } - - /* allocate space for the attributes */ - for (i=0; i < itemTemplateCount ; i++) { - template[i].pValue = PORT_ArenaAlloc(arena, template[i].ulValueLen); - if (template[i].pValue == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - } - - /* fetch the attributes */ - crv = sftkdb_GetAttributeValue(dbHandle, object->handle, - template, itemTemplateCount); - if (crv != CKR_OK) { - goto loser; - } - - /* Fill in the items */ - for (i=0; i < itemTemplateCount; i++) { - itemTemplate[i].item->data = template[i].pValue; - itemTemplate[i].item->len = template[i].ulValueLen; - } - -loser: - if (template != templateSpace) { - PORT_Free(template); - } - if (dbHandle) { - sftk_freeDB(dbHandle); - } - - return crv; -} - - -/* - * delete an attribute from an object - */ -static void -sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute) -{ - SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object); - - if (sessObject == NULL) { - return ; - } - PZ_Lock(sessObject->attributeLock); - if (sftkqueue_is_queued(attribute,attribute->handle, - sessObject->head, sessObject->hashSize)) { - sftkqueue_delete(attribute,attribute->handle, - sessObject->head, sessObject->hashSize); - } - PZ_Unlock(sessObject->attributeLock); -} - -/* - * this is only valid for CK_BBOOL type attributes. Return the state - * of that attribute. - */ -PRBool -sftk_isTrue(SFTKObject *object,CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *attribute; - PRBool tok = PR_FALSE; - - attribute=sftk_FindAttribute(object,type); - if (attribute == NULL) { return PR_FALSE; } - tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue); - sftk_FreeAttribute(attribute); - - return tok; -} - -/* - * force an attribute to null. - * this is for sensitive keys which are stored in the database, we don't - * want to keep this info around in memory in the clear. - */ -void -sftk_nullAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *attribute; - - attribute=sftk_FindAttribute(object,type); - if (attribute == NULL) return; - - if (attribute->attrib.pValue != NULL) { - PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen); - if (attribute->freeData) { - PORT_Free(attribute->attrib.pValue); - } - attribute->freeData = PR_FALSE; - attribute->attrib.pValue = NULL; - attribute->attrib.ulValueLen = 0; - } - sftk_FreeAttribute(attribute); -} - - -static CK_RV -sftk_forceTokenAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type, - void *value, unsigned int len) -{ - CK_ATTRIBUTE attribute; - SFTKDBHandle *dbHandle = NULL; - SFTKTokenObject *to = sftk_narrowToTokenObject(object); - CK_RV crv; - - PORT_Assert(to); - if (to == NULL) { - return CKR_DEVICE_ERROR; - } - - dbHandle = sftk_getDBForTokenObject(object->slot, object->handle); - - attribute.type = type; - attribute.pValue = value; - attribute.ulValueLen = len; - - crv = sftkdb_SetAttributeValue(dbHandle, object, &attribute, 1); - sftk_freeDB(dbHandle); - return crv; -} - -/* - * force an attribute to a specifc value. - */ -CK_RV -sftk_forceAttribute(SFTKObject *object,CK_ATTRIBUTE_TYPE type, void *value, - unsigned int len) -{ - SFTKAttribute *attribute; - void *att_val = NULL; - PRBool freeData = PR_FALSE; - - PORT_Assert(object); - PORT_Assert(object->refCount); - PORT_Assert(object->slot); - if (!object || - !object->refCount || - !object->slot) { - return CKR_DEVICE_ERROR; - } - if (sftk_isToken(object->handle)) { - return sftk_forceTokenAttribute(object,type,value,len); - } - attribute=sftk_FindAttribute(object,type); - if (attribute == NULL) return sftk_AddAttributeType(object,type,value,len); - - - if (value) { - if (len <= ATTR_SPACE) { - att_val = attribute->space; - } else { - att_val = PORT_Alloc(len); - freeData = PR_TRUE; - } - if (att_val == NULL) { - return CKR_HOST_MEMORY; - } - if (attribute->attrib.pValue == att_val) { - PORT_Memset(attribute->attrib.pValue,0, - attribute->attrib.ulValueLen); - } - PORT_Memcpy(att_val,value,len); - } - if (attribute->attrib.pValue != NULL) { - if (attribute->attrib.pValue != att_val) { - PORT_Memset(attribute->attrib.pValue,0, - attribute->attrib.ulValueLen); - } - if (attribute->freeData) { - PORT_Free(attribute->attrib.pValue); - } - attribute->freeData = PR_FALSE; - attribute->attrib.pValue = NULL; - attribute->attrib.ulValueLen = 0; - } - if (att_val) { - attribute->attrib.pValue = att_val; - attribute->attrib.ulValueLen = len; - attribute->freeData = freeData; - } - sftk_FreeAttribute(attribute); - return CKR_OK; -} - -/* - * return a null terminated string from attribute 'type'. This string - * is allocated and needs to be freed with PORT_Free() When complete. - */ -char * -sftk_getString(SFTKObject *object,CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *attribute; - char *label = NULL; - - attribute=sftk_FindAttribute(object,type); - if (attribute == NULL) return NULL; - - if (attribute->attrib.pValue != NULL) { - label = (char *) PORT_Alloc(attribute->attrib.ulValueLen+1); - if (label == NULL) { - sftk_FreeAttribute(attribute); - return NULL; - } - - PORT_Memcpy(label,attribute->attrib.pValue, - attribute->attrib.ulValueLen); - label[attribute->attrib.ulValueLen] = 0; - } - sftk_FreeAttribute(attribute); - return label; -} - -/* - * decode when a particular attribute may be modified - * SFTK_NEVER: This attribute must be set at object creation time and - * can never be modified. - * SFTK_ONCOPY: This attribute may be modified only when you copy the - * object. - * SFTK_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from - * CK_FALSE to CK_TRUE. - * SFTK_ALWAYS: This attribute can always be modified. - * Some attributes vary their modification type based on the class of the - * object. - */ -SFTKModifyType -sftk_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) -{ - /* if we don't know about it, user user defined, always allow modify */ - SFTKModifyType mtype = SFTK_ALWAYS; - - switch(type) { - /* NEVER */ - case CKA_CLASS: - case CKA_CERTIFICATE_TYPE: - case CKA_KEY_TYPE: - case CKA_MODULUS: - case CKA_MODULUS_BITS: - case CKA_PUBLIC_EXPONENT: - case CKA_PRIVATE_EXPONENT: - case CKA_PRIME: - case CKA_SUBPRIME: - case CKA_BASE: - case CKA_PRIME_1: - case CKA_PRIME_2: - case CKA_EXPONENT_1: - case CKA_EXPONENT_2: - case CKA_COEFFICIENT: - case CKA_VALUE_LEN: - case CKA_ALWAYS_SENSITIVE: - case CKA_NEVER_EXTRACTABLE: - case CKA_NETSCAPE_DB: - mtype = SFTK_NEVER; - break; - - /* ONCOPY */ - case CKA_TOKEN: - case CKA_PRIVATE: - case CKA_MODIFIABLE: - mtype = SFTK_ONCOPY; - break; - - /* SENSITIVE */ - case CKA_SENSITIVE: - case CKA_EXTRACTABLE: - mtype = SFTK_SENSITIVE; - break; - - /* ALWAYS */ - case CKA_LABEL: - case CKA_APPLICATION: - case CKA_ID: - case CKA_SERIAL_NUMBER: - case CKA_START_DATE: - case CKA_END_DATE: - case CKA_DERIVE: - case CKA_ENCRYPT: - case CKA_DECRYPT: - case CKA_SIGN: - case CKA_VERIFY: - case CKA_SIGN_RECOVER: - case CKA_VERIFY_RECOVER: - case CKA_WRAP: - case CKA_UNWRAP: - mtype = SFTK_ALWAYS; - break; - - /* DEPENDS ON CLASS */ - case CKA_VALUE: - mtype = (inClass == CKO_DATA) ? SFTK_ALWAYS : SFTK_NEVER; - break; - - case CKA_SUBJECT: - mtype = (inClass == CKO_CERTIFICATE) ? SFTK_NEVER : SFTK_ALWAYS; - break; - default: - break; - } - return mtype; -} - -/* decode if a particular attribute is sensitive (cannot be read - * back to the user of if the object is set to SENSITIVE) */ -PRBool -sftk_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) -{ - switch(type) { - /* ALWAYS */ - case CKA_PRIVATE_EXPONENT: - case CKA_PRIME_1: - case CKA_PRIME_2: - case CKA_EXPONENT_1: - case CKA_EXPONENT_2: - case CKA_COEFFICIENT: - return PR_TRUE; - - /* DEPENDS ON CLASS */ - case CKA_VALUE: - /* PRIVATE and SECRET KEYS have SENSITIVE values */ - return (PRBool)((inClass == CKO_PRIVATE_KEY) || (inClass == CKO_SECRET_KEY)); - - default: - break; - } - return PR_FALSE; -} - -/* - * copy an attribute into a SECItem. Secitem is allocated in the specified - * arena. - */ -CK_RV -sftk_Attribute2SecItem(PLArenaPool *arena,SECItem *item,SFTKObject *object, - CK_ATTRIBUTE_TYPE type) -{ - int len; - SFTKAttribute *attribute; - - attribute = sftk_FindAttribute(object, type); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - len = attribute->attrib.ulValueLen; - - if (arena) { - item->data = (unsigned char *) PORT_ArenaAlloc(arena,len); - } else { - item->data = (unsigned char *) PORT_Alloc(len); - } - if (item->data == NULL) { - sftk_FreeAttribute(attribute); - return CKR_HOST_MEMORY; - } - item->len = len; - PORT_Memcpy(item->data,attribute->attrib.pValue, len); - sftk_FreeAttribute(attribute); - return CKR_OK; -} - -CK_RV -sftk_GetULongAttribute(SFTKObject *object, CK_ATTRIBUTE_TYPE type, - CK_ULONG *longData) -{ - SFTKAttribute *attribute; - - attribute = sftk_FindAttribute(object, type); - if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE; - - if (attribute->attrib.ulValueLen != sizeof(CK_ULONG)) { - return CKR_ATTRIBUTE_VALUE_INVALID; - } - - *longData = *(CK_ULONG *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - return CKR_OK; -} - -void -sftk_DeleteAttributeType(SFTKObject *object,CK_ATTRIBUTE_TYPE type) -{ - SFTKAttribute *attribute; - attribute = sftk_FindAttribute(object, type); - if (attribute == NULL) return ; - sftk_DeleteAttribute(object,attribute); - sftk_FreeAttribute(attribute); -} - -CK_RV -sftk_AddAttributeType(SFTKObject *object,CK_ATTRIBUTE_TYPE type,void *valPtr, - CK_ULONG length) -{ - SFTKAttribute *attribute; - attribute = sftk_NewAttribute(object,type,valPtr,length); - if (attribute == NULL) { return CKR_HOST_MEMORY; } - sftk_AddAttribute(object,attribute); - return CKR_OK; -} - -/* - * ******************** Object Utilities ******************************* - */ - -/* must be called holding sftk_tokenKeyLock(slot) */ -static SECItem * -sftk_lookupTokenKeyByHandle(SFTKSlot *slot, CK_OBJECT_HANDLE handle) -{ - return (SECItem *)PL_HashTableLookup(slot->tokObjHashTable, (void *)handle); -} - -/* - * use the refLock. This operations should be very rare, so the added - * contention on the ref lock should be lower than the overhead of adding - * a new lock. We use separate functions for this just in case I'm wrong. - */ -static void -sftk_tokenKeyLock(SFTKSlot *slot) { - SKIP_AFTER_FORK(PZ_Lock(slot->objectLock)); -} - -static void -sftk_tokenKeyUnlock(SFTKSlot *slot) { - SKIP_AFTER_FORK(PZ_Unlock(slot->objectLock)); -} - -static PRIntn -sftk_freeHashItem(PLHashEntry* entry, PRIntn index, void *arg) -{ - SECItem *item = (SECItem *)entry->value; - - SECITEM_FreeItem(item, PR_TRUE); - return HT_ENUMERATE_NEXT; -} - -CK_RV -SFTK_ClearTokenKeyHashTable(SFTKSlot *slot) -{ - sftk_tokenKeyLock(slot); - PORT_Assert(!slot->present); - PL_HashTableEnumerateEntries(slot->tokObjHashTable, sftk_freeHashItem, NULL); - sftk_tokenKeyUnlock(slot); - return CKR_OK; -} - - -/* allocation hooks that allow us to recycle old object structures */ -static SFTKObjectFreeList sessionObjectList = { NULL, NULL, 0 }; -static SFTKObjectFreeList tokenObjectList = { NULL, NULL, 0 }; - -SFTKObject * -sftk_GetObjectFromList(PRBool *hasLocks, PRBool optimizeSpace, - SFTKObjectFreeList *list, unsigned int hashSize, PRBool isSessionObject) -{ - SFTKObject *object; - int size = 0; - - if (!optimizeSpace) { - PZ_Lock(list->lock); - object = list->head; - if (object) { - list->head = object->next; - list->count--; - } - PZ_Unlock(list->lock); - if (object) { - object->next = object->prev = NULL; - *hasLocks = PR_TRUE; - return object; - } - } - size = isSessionObject ? sizeof(SFTKSessionObject) - + hashSize *sizeof(SFTKAttribute *) : sizeof(SFTKTokenObject); - - object = (SFTKObject*)PORT_ZAlloc(size); - if (isSessionObject && object) { - ((SFTKSessionObject *)object)->hashSize = hashSize; - } - *hasLocks = PR_FALSE; - return object; -} - -static void -sftk_PutObjectToList(SFTKObject *object, SFTKObjectFreeList *list, - PRBool isSessionObject) { - - /* the code below is equivalent to : - * optimizeSpace = isSessionObject ? object->optimizeSpace : PR_FALSE; - * just faster. - */ - PRBool optimizeSpace = isSessionObject && - ((SFTKSessionObject *)object)->optimizeSpace; - if (object->refLock && !optimizeSpace - && (list->count < MAX_OBJECT_LIST_SIZE)) { - PZ_Lock(list->lock); - object->next = list->head; - list->head = object; - list->count++; - PZ_Unlock(list->lock); - return; - } - if (isSessionObject) { - SFTKSessionObject *so = (SFTKSessionObject *)object; - PZ_DestroyLock(so->attributeLock); - so->attributeLock = NULL; - } - if (object->refLock) { - PZ_DestroyLock(object->refLock); - object->refLock = NULL; - } - PORT_Free(object); -} - -static SFTKObject * -sftk_freeObjectData(SFTKObject *object) { - SFTKObject *next = object->next; - - PORT_Free(object); - return next; -} - -static void -sftk_InitFreeList(SFTKObjectFreeList *list) -{ - list->lock = PZ_NewLock(nssILockObject); -} - -void sftk_InitFreeLists(void) -{ - sftk_InitFreeList(&sessionObjectList); - sftk_InitFreeList(&tokenObjectList); -} - -static void -sftk_CleanupFreeList(SFTKObjectFreeList *list, PRBool isSessionList) -{ - SFTKObject *object; - - if (!list->lock) { - return; - } - SKIP_AFTER_FORK(PZ_Lock(list->lock)); - for (object= list->head; object != NULL; - object = sftk_freeObjectData(object)) { - PZ_DestroyLock(object->refLock); - if (isSessionList) { - PZ_DestroyLock(((SFTKSessionObject *)object)->attributeLock); - } - } - list->count = 0; - list->head = NULL; - SKIP_AFTER_FORK(PZ_Unlock(list->lock)); - SKIP_AFTER_FORK(PZ_DestroyLock(list->lock)); - list->lock = NULL; -} - -void -sftk_CleanupFreeLists(void) -{ - sftk_CleanupFreeList(&sessionObjectList, PR_TRUE); - sftk_CleanupFreeList(&tokenObjectList, PR_FALSE); -} - - -/* - * Create a new object - */ -SFTKObject * -sftk_NewObject(SFTKSlot *slot) -{ - SFTKObject *object; - SFTKSessionObject *sessObject; - PRBool hasLocks = PR_FALSE; - unsigned int i; - unsigned int hashSize = 0; - - hashSize = (slot->optimizeSpace) ? SPACE_ATTRIBUTE_HASH_SIZE : - TIME_ATTRIBUTE_HASH_SIZE; - - object = sftk_GetObjectFromList(&hasLocks, slot->optimizeSpace, - &sessionObjectList, hashSize, PR_TRUE); - if (object == NULL) { - return NULL; - } - sessObject = (SFTKSessionObject *)object; - sessObject->nextAttr = 0; - - for (i=0; i < MAX_OBJS_ATTRS; i++) { - sessObject->attrList[i].attrib.pValue = NULL; - sessObject->attrList[i].freeData = PR_FALSE; - } - sessObject->optimizeSpace = slot->optimizeSpace; - - object->handle = 0; - object->next = object->prev = NULL; - object->slot = slot; - - object->refCount = 1; - sessObject->sessionList.next = NULL; - sessObject->sessionList.prev = NULL; - sessObject->sessionList.parent = object; - sessObject->session = NULL; - sessObject->wasDerived = PR_FALSE; - if (!hasLocks) object->refLock = PZ_NewLock(nssILockRefLock); - if (object->refLock == NULL) { - PORT_Free(object); - return NULL; - } - if (!hasLocks) sessObject->attributeLock = PZ_NewLock(nssILockAttribute); - if (sessObject->attributeLock == NULL) { - PZ_DestroyLock(object->refLock); - PORT_Free(object); - return NULL; - } - for (i=0; i < sessObject->hashSize; i++) { - sessObject->head[i] = NULL; - } - object->objectInfo = NULL; - object->infoFree = NULL; - return object; -} - -static CK_RV -sftk_DestroySessionObjectData(SFTKSessionObject *so) -{ - int i; - - for (i=0; i < MAX_OBJS_ATTRS; i++) { - unsigned char *value = so->attrList[i].attrib.pValue; - if (value) { - PORT_Memset(value,0,so->attrList[i].attrib.ulValueLen); - if (so->attrList[i].freeData) { - PORT_Free(value); - } - so->attrList[i].attrib.pValue = NULL; - so->attrList[i].freeData = PR_FALSE; - } - } -/* PZ_DestroyLock(so->attributeLock);*/ - return CKR_OK; -} - -/* - * free all the data associated with an object. Object reference count must - * be 'zero'. - */ -static CK_RV -sftk_DestroyObject(SFTKObject *object) -{ - CK_RV crv = CKR_OK; - SFTKSessionObject *so = sftk_narrowToSessionObject(object); - SFTKTokenObject *to = sftk_narrowToTokenObject(object); - - PORT_Assert(object->refCount == 0); - - /* delete the database value */ - if (to) { - if (to->dbKey.data) { - PORT_Free(to->dbKey.data); - to->dbKey.data = NULL; - } - } - if (so) { - sftk_DestroySessionObjectData(so); - } - if (object->objectInfo) { - (*object->infoFree)(object->objectInfo); - object->objectInfo = NULL; - object->infoFree = NULL; - } - if (so) { - sftk_PutObjectToList(object,&sessionObjectList,PR_TRUE); - } else { - sftk_PutObjectToList(object,&tokenObjectList,PR_FALSE); - } - return crv; -} - -void -sftk_ReferenceObject(SFTKObject *object) -{ - PZ_Lock(object->refLock); - object->refCount++; - PZ_Unlock(object->refLock); -} - -static SFTKObject * -sftk_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, SFTKSlot *slot) -{ - SFTKObject *object; - PRUint32 index = sftk_hash(handle, slot->sessObjHashSize); - - if (sftk_isToken(handle)) { - return sftk_NewTokenObject(slot, NULL, handle); - } - - PZ_Lock(slot->objectLock); - sftkqueue_find2(object, handle, index, slot->sessObjHashTable); - if (object) { - sftk_ReferenceObject(object); - } - PZ_Unlock(slot->objectLock); - - return(object); -} -/* - * look up and object structure from a handle. OBJECT_Handles only make - * sense in terms of a given session. make a reference to that object - * structure returned. - */ -SFTKObject * -sftk_ObjectFromHandle(CK_OBJECT_HANDLE handle, SFTKSession *session) -{ - SFTKSlot *slot = sftk_SlotFromSession(session); - - return sftk_ObjectFromHandleOnSlot(handle,slot); -} - - -/* - * release a reference to an object handle - */ -SFTKFreeStatus -sftk_FreeObject(SFTKObject *object) -{ - PRBool destroy = PR_FALSE; - CK_RV crv; - - PZ_Lock(object->refLock); - if (object->refCount == 1) destroy = PR_TRUE; - object->refCount--; - PZ_Unlock(object->refLock); - - if (destroy) { - crv = sftk_DestroyObject(object); - if (crv != CKR_OK) { - return SFTK_DestroyFailure; - } - return SFTK_Destroyed; - } - return SFTK_Busy; -} - -/* - * add an object to a slot and session queue. These two functions - * adopt the object. - */ -void -sftk_AddSlotObject(SFTKSlot *slot, SFTKObject *object) -{ - PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize); - sftkqueue_init_element(object); - PZ_Lock(slot->objectLock); - sftkqueue_add2(object, object->handle, index, slot->sessObjHashTable); - PZ_Unlock(slot->objectLock); -} - -void -sftk_AddObject(SFTKSession *session, SFTKObject *object) -{ - SFTKSlot *slot = sftk_SlotFromSession(session); - SFTKSessionObject *so = sftk_narrowToSessionObject(object); - - if (so) { - PZ_Lock(session->objectLock); - sftkqueue_add(&so->sessionList,0,session->objects,0); - so->session = session; - PZ_Unlock(session->objectLock); - } - sftk_AddSlotObject(slot,object); - sftk_ReferenceObject(object); -} - -/* - * delete an object from a slot and session queue - */ -CK_RV -sftk_DeleteObject(SFTKSession *session, SFTKObject *object) -{ - SFTKSlot *slot = sftk_SlotFromSession(session); - SFTKSessionObject *so = sftk_narrowToSessionObject(object); - SFTKTokenObject *to = sftk_narrowToTokenObject(object); - CK_RV crv = CKR_OK; - PRUint32 index = sftk_hash(object->handle, slot->sessObjHashSize); - - /* Handle Token case */ - if (so && so->session) { - SFTKSession *session = so->session; - PZ_Lock(session->objectLock); - sftkqueue_delete(&so->sessionList,0,session->objects,0); - PZ_Unlock(session->objectLock); - PZ_Lock(slot->objectLock); - sftkqueue_delete2(object, object->handle, index, slot->sessObjHashTable); - PZ_Unlock(slot->objectLock); - sftkqueue_clear_deleted_element(object); - sftk_FreeObject(object); /* free the reference owned by the queue */ - } else { - SFTKDBHandle *handle = sftk_getDBForTokenObject(slot, object->handle); - - PORT_Assert(to); - crv = sftkdb_DestroyObject(handle, object->handle); - sftk_freeDB(handle); - } - return crv; -} - -/* - * Token objects don't explicitly store their attributes, so we need to know - * what attributes make up a particular token object before we can copy it. - * below are the tables by object type. - */ -static const CK_ATTRIBUTE_TYPE commonAttrs[] = { - CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_MODIFIABLE -}; -static const CK_ULONG commonAttrsCount = - sizeof(commonAttrs)/sizeof(commonAttrs[0]); - -static const CK_ATTRIBUTE_TYPE commonKeyAttrs[] = { - CKA_ID, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE, CKA_LOCAL, CKA_KEY_TYPE -}; -static const CK_ULONG commonKeyAttrsCount = - sizeof(commonKeyAttrs)/sizeof(commonKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE secretKeyAttrs[] = { - CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_ENCRYPT, CKA_DECRYPT, CKA_SIGN, - CKA_VERIFY, CKA_WRAP, CKA_UNWRAP, CKA_VALUE -}; -static const CK_ULONG secretKeyAttrsCount = - sizeof(secretKeyAttrs)/sizeof(secretKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE commonPubKeyAttrs[] = { - CKA_ENCRYPT, CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_WRAP, CKA_SUBJECT -}; -static const CK_ULONG commonPubKeyAttrsCount = - sizeof(commonPubKeyAttrs)/sizeof(commonPubKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE rsaPubKeyAttrs[] = { - CKA_MODULUS, CKA_PUBLIC_EXPONENT -}; -static const CK_ULONG rsaPubKeyAttrsCount = - sizeof(rsaPubKeyAttrs)/sizeof(rsaPubKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE dsaPubKeyAttrs[] = { - CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE -}; -static const CK_ULONG dsaPubKeyAttrsCount = - sizeof(dsaPubKeyAttrs)/sizeof(dsaPubKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE dhPubKeyAttrs[] = { - CKA_PRIME, CKA_BASE, CKA_VALUE -}; -static const CK_ULONG dhPubKeyAttrsCount = - sizeof(dhPubKeyAttrs)/sizeof(dhPubKeyAttrs[0]); -#ifdef NSS_ENABLE_ECC -static const CK_ATTRIBUTE_TYPE ecPubKeyAttrs[] = { - CKA_EC_PARAMS, CKA_EC_POINT -}; -static const CK_ULONG ecPubKeyAttrsCount = - sizeof(ecPubKeyAttrs)/sizeof(ecPubKeyAttrs[0]); -#endif - -static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = { - CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT, - CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB -}; -static const CK_ULONG commonPrivKeyAttrsCount = - sizeof(commonPrivKeyAttrs)/sizeof(commonPrivKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE rsaPrivKeyAttrs[] = { - CKA_MODULUS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT, - CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT -}; -static const CK_ULONG rsaPrivKeyAttrsCount = - sizeof(rsaPrivKeyAttrs)/sizeof(rsaPrivKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE dsaPrivKeyAttrs[] = { - CKA_SUBPRIME, CKA_PRIME, CKA_BASE, CKA_VALUE -}; -static const CK_ULONG dsaPrivKeyAttrsCount = - sizeof(dsaPrivKeyAttrs)/sizeof(dsaPrivKeyAttrs[0]); - -static const CK_ATTRIBUTE_TYPE dhPrivKeyAttrs[] = { - CKA_PRIME, CKA_BASE, CKA_VALUE -}; -static const CK_ULONG dhPrivKeyAttrsCount = - sizeof(dhPrivKeyAttrs)/sizeof(dhPrivKeyAttrs[0]); -#ifdef NSS_ENABLE_ECC -static const CK_ATTRIBUTE_TYPE ecPrivKeyAttrs[] = { - CKA_EC_PARAMS, CKA_VALUE -}; -static const CK_ULONG ecPrivKeyAttrsCount = - sizeof(ecPrivKeyAttrs)/sizeof(ecPrivKeyAttrs[0]); -#endif - -static const CK_ATTRIBUTE_TYPE certAttrs[] = { - CKA_CERTIFICATE_TYPE, CKA_VALUE, CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER -}; -static const CK_ULONG certAttrsCount = - sizeof(certAttrs)/sizeof(certAttrs[0]); - -static const CK_ATTRIBUTE_TYPE trustAttrs[] = { - CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, - CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_EMAIL_PROTECTION, - CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED -}; -static const CK_ULONG trustAttrsCount = - sizeof(trustAttrs)/sizeof(trustAttrs[0]); - -static const CK_ATTRIBUTE_TYPE smimeAttrs[] = { - CKA_SUBJECT, CKA_NETSCAPE_EMAIL, CKA_NETSCAPE_SMIME_TIMESTAMP, CKA_VALUE -}; -static const CK_ULONG smimeAttrsCount = - sizeof(smimeAttrs)/sizeof(smimeAttrs[0]); - -static const CK_ATTRIBUTE_TYPE crlAttrs[] = { - CKA_SUBJECT, CKA_VALUE, CKA_NETSCAPE_URL, CKA_NETSCAPE_KRL -}; -static const CK_ULONG crlAttrsCount = - sizeof(crlAttrs)/sizeof(crlAttrs[0]); - -/* copy an object based on it's table */ -CK_RV -stfk_CopyTokenAttributes(SFTKObject *destObject,SFTKTokenObject *src_to, - const CK_ATTRIBUTE_TYPE *attrArray, CK_ULONG attrCount) -{ - SFTKAttribute *attribute; - SFTKAttribute *newAttribute; - CK_RV crv = CKR_OK; - unsigned int i; - - for (i=0; i < attrCount; i++) { - if (!sftk_hasAttribute(destObject,attrArray[i])) { - attribute =sftk_FindAttribute(&src_to->obj, attrArray[i]); - if (!attribute) { - continue; /* return CKR_ATTRIBUTE_VALUE_INVALID; */ - } - /* we need to copy the attribute since each attribute - * only has one set of link list pointers */ - newAttribute = sftk_NewAttribute( destObject, - sftk_attr_expand(&attribute->attrib)); - sftk_FreeAttribute(attribute); /* free the old attribute */ - if (!newAttribute) { - return CKR_HOST_MEMORY; - } - sftk_AddAttribute(destObject,newAttribute); - } - } - return crv; -} - -CK_RV -stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to) -{ - CK_RV crv; - CK_KEY_TYPE key_type; - SFTKAttribute *attribute; - - /* copy the common attributes for all keys first */ - crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs, - commonKeyAttrsCount); - if (crv != CKR_OK) { - goto fail; - } - /* copy the common attributes for all private keys next */ - crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs, - commonPrivKeyAttrsCount); - if (crv != CKR_OK) { - goto fail; - } - attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE); - PORT_Assert(attribute); /* if it wasn't here, ww should have failed - * copying the common attributes */ - if (!attribute) { - /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but - * the fact is, the only reason we couldn't get the attribute would - * be a memory error or database error (an error in the 'device'). - * if we have a database error code, we could return it here */ - crv = CKR_DEVICE_ERROR; - goto fail; - } - key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - - /* finally copy the attributes for various private key types */ - switch (key_type) { - case CKK_RSA: - crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPrivKeyAttrs, - rsaPrivKeyAttrsCount); - break; - case CKK_DSA: - crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPrivKeyAttrs, - dsaPrivKeyAttrsCount); - break; - case CKK_DH: - crv = stfk_CopyTokenAttributes(destObject, src_to, dhPrivKeyAttrs, - dhPrivKeyAttrsCount); - break; -#ifdef NSS_ENABLE_ECC - case CKK_EC: - crv = stfk_CopyTokenAttributes(destObject, src_to, ecPrivKeyAttrs, - ecPrivKeyAttrsCount); - break; -#endif - default: - crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types - * of token keys into our database. */ - } -fail: - return crv; -} - -CK_RV -stfk_CopyTokenPublicKey(SFTKObject *destObject,SFTKTokenObject *src_to) -{ - CK_RV crv; - CK_KEY_TYPE key_type; - SFTKAttribute *attribute; - - /* copy the common attributes for all keys first */ - crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs, - commonKeyAttrsCount); - if (crv != CKR_OK) { - goto fail; - } - - /* copy the common attributes for all public keys next */ - crv = stfk_CopyTokenAttributes(destObject, src_to, commonPubKeyAttrs, - commonPubKeyAttrsCount); - if (crv != CKR_OK) { - goto fail; - } - attribute =sftk_FindAttribute(&src_to->obj, CKA_KEY_TYPE); - PORT_Assert(attribute); /* if it wasn't here, ww should have failed - * copying the common attributes */ - if (!attribute) { - /* OK, so CKR_ATTRIBUTE_VALUE_INVALID is the immediate error, but - * the fact is, the only reason we couldn't get the attribute would - * be a memory error or database error (an error in the 'device'). - * if we have a database error code, we could return it here */ - crv = CKR_DEVICE_ERROR; - goto fail; - } - key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; - sftk_FreeAttribute(attribute); - - /* finally copy the attributes for various public key types */ - switch (key_type) { - case CKK_RSA: - crv = stfk_CopyTokenAttributes(destObject, src_to, rsaPubKeyAttrs, - rsaPubKeyAttrsCount); - break; - case CKK_DSA: - crv = stfk_CopyTokenAttributes(destObject, src_to, dsaPubKeyAttrs, - dsaPubKeyAttrsCount); - break; - case CKK_DH: - crv = stfk_CopyTokenAttributes(destObject, src_to, dhPubKeyAttrs, - dhPubKeyAttrsCount); - break; -#ifdef NSS_ENABLE_ECC - case CKK_EC: - crv = stfk_CopyTokenAttributes(destObject, src_to, ecPubKeyAttrs, - ecPubKeyAttrsCount); - break; -#endif - default: - crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types - * of token keys into our database. */ - } -fail: - return crv; -} -CK_RV -stfk_CopyTokenSecretKey(SFTKObject *destObject,SFTKTokenObject *src_to) -{ - CK_RV crv; - crv = stfk_CopyTokenAttributes(destObject, src_to, commonKeyAttrs, - commonKeyAttrsCount); - if (crv != CKR_OK) { - goto fail; - } - crv = stfk_CopyTokenAttributes(destObject, src_to, secretKeyAttrs, - secretKeyAttrsCount); -fail: - return crv; -} - -/* - * Copy a token object. We need to explicitly copy the relevant - * attributes since token objects don't store those attributes in - * the token itself. - */ -CK_RV -sftk_CopyTokenObject(SFTKObject *destObject,SFTKObject *srcObject) -{ - SFTKTokenObject *src_to = sftk_narrowToTokenObject(srcObject); - CK_RV crv; - - PORT_Assert(src_to); - if (src_to == NULL) { - return CKR_DEVICE_ERROR; /* internal state inconsistant */ - } - - crv = stfk_CopyTokenAttributes(destObject, src_to, commonAttrs, - commonAttrsCount); - if (crv != CKR_OK) { - goto fail; - } - switch (src_to->obj.objclass) { - case CKO_CERTIFICATE: - crv = stfk_CopyTokenAttributes(destObject, src_to, certAttrs, - certAttrsCount); - break; - case CKO_NETSCAPE_TRUST: - crv = stfk_CopyTokenAttributes(destObject, src_to, trustAttrs, - trustAttrsCount); - break; - case CKO_NETSCAPE_SMIME: - crv = stfk_CopyTokenAttributes(destObject, src_to, smimeAttrs, - smimeAttrsCount); - break; - case CKO_NETSCAPE_CRL: - crv = stfk_CopyTokenAttributes(destObject, src_to, crlAttrs, - crlAttrsCount); - break; - case CKO_PRIVATE_KEY: - crv = stfk_CopyTokenPrivateKey(destObject,src_to); - break; - case CKO_PUBLIC_KEY: - crv = stfk_CopyTokenPublicKey(destObject,src_to); - break; - case CKO_SECRET_KEY: - crv = stfk_CopyTokenSecretKey(destObject,src_to); - break; - default: - crv = CKR_DEVICE_ERROR; /* shouldn't happen unless we store more types - * of token keys into our database. */ - } -fail: - return crv; -} - -/* - * copy the attributes from one object to another. Don't overwrite existing - * attributes. NOTE: This is a pretty expensive operation since it - * grabs the attribute locks for the src object for a *long* time. - */ -CK_RV -sftk_CopyObject(SFTKObject *destObject,SFTKObject *srcObject) -{ - SFTKAttribute *attribute; - SFTKSessionObject *src_so = sftk_narrowToSessionObject(srcObject); - unsigned int i; - - if (src_so == NULL) { - return sftk_CopyTokenObject(destObject,srcObject); - } - - PZ_Lock(src_so->attributeLock); - for(i=0; i < src_so->hashSize; i++) { - attribute = src_so->head[i]; - do { - if (attribute) { - if (!sftk_hasAttribute(destObject,attribute->handle)) { - /* we need to copy the attribute since each attribute - * only has one set of link list pointers */ - SFTKAttribute *newAttribute = sftk_NewAttribute( - destObject,sftk_attr_expand(&attribute->attrib)); - if (newAttribute == NULL) { - PZ_Unlock(src_so->attributeLock); - return CKR_HOST_MEMORY; - } - sftk_AddAttribute(destObject,newAttribute); - } - attribute=attribute->next; - } - } while (attribute != NULL); - } - PZ_Unlock(src_so->attributeLock); - - return CKR_OK; -} - -/* - * ******************** Search Utilities ******************************* - */ - -/* add an object to a search list */ -CK_RV -AddToList(SFTKObjectListElement **list,SFTKObject *object) -{ - SFTKObjectListElement *newElem = - (SFTKObjectListElement *)PORT_Alloc(sizeof(SFTKObjectListElement)); - - if (newElem == NULL) return CKR_HOST_MEMORY; - - newElem->next = *list; - newElem->object = object; - sftk_ReferenceObject(object); - - *list = newElem; - return CKR_OK; -} - - -/* return true if the object matches the template */ -PRBool -sftk_objectMatch(SFTKObject *object,CK_ATTRIBUTE_PTR theTemplate,int count) -{ - int i; - - for (i=0; i < count; i++) { - SFTKAttribute *attribute = sftk_FindAttribute(object,theTemplate[i].type); - if (attribute == NULL) { - return PR_FALSE; - } - if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) { - if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue, - theTemplate[i].ulValueLen) == 0) { - sftk_FreeAttribute(attribute); - continue; - } - } - sftk_FreeAttribute(attribute); - return PR_FALSE; - } - return PR_TRUE; -} - -/* search through all the objects in the queue and return the template matches - * in the object list. - */ -CK_RV -sftk_searchObjectList(SFTKSearchResults *search,SFTKObject **head, - unsigned int size, PZLock *lock, CK_ATTRIBUTE_PTR theTemplate, - int count, PRBool isLoggedIn) -{ - unsigned int i; - SFTKObject *object; - CK_RV crv = CKR_OK; - - for(i=0; i < size; i++) { - /* We need to hold the lock to copy a consistant version of - * the linked list. */ - PZ_Lock(lock); - for (object = head[i]; object != NULL; object= object->next) { - if (sftk_objectMatch(object,theTemplate,count)) { - /* don't return objects that aren't yet visible */ - if ((!isLoggedIn) && sftk_isTrue(object,CKA_PRIVATE)) continue; - sftk_addHandle(search,object->handle); - } - } - PZ_Unlock(lock); - } - return crv; -} - -/* - * free a single list element. Return the Next object in the list. - */ -SFTKObjectListElement * -sftk_FreeObjectListElement(SFTKObjectListElement *objectList) -{ - SFTKObjectListElement *ol = objectList->next; - - sftk_FreeObject(objectList->object); - PORT_Free(objectList); - return ol; -} - -/* free an entire object list */ -void -sftk_FreeObjectList(SFTKObjectListElement *objectList) -{ - SFTKObjectListElement *ol; - - for (ol= objectList; ol != NULL; ol = sftk_FreeObjectListElement(ol)) {} -} - -/* - * free a search structure - */ -void -sftk_FreeSearch(SFTKSearchResults *search) -{ - if (search->handles) { - PORT_Free(search->handles); - } - PORT_Free(search); -} - -/* - * ******************** Session Utilities ******************************* - */ - -/* update the sessions state based in it's flags and wether or not it's - * logged in */ -void -sftk_update_state(SFTKSlot *slot,SFTKSession *session) -{ - if (slot->isLoggedIn) { - if (slot->ssoLoggedIn) { - session->info.state = CKS_RW_SO_FUNCTIONS; - } else if (session->info.flags & CKF_RW_SESSION) { - session->info.state = CKS_RW_USER_FUNCTIONS; - } else { - session->info.state = CKS_RO_USER_FUNCTIONS; - } - } else { - if (session->info.flags & CKF_RW_SESSION) { - session->info.state = CKS_RW_PUBLIC_SESSION; - } else { - session->info.state = CKS_RO_PUBLIC_SESSION; - } - } -} - -/* update the state of all the sessions on a slot */ -void -sftk_update_all_states(SFTKSlot *slot) -{ - unsigned int i; - SFTKSession *session; - - for (i=0; i < slot->sessHashSize; i++) { - PZLock *lock = SFTK_SESSION_LOCK(slot,i); - PZ_Lock(lock); - for (session = slot->head[i]; session; session = session->next) { - sftk_update_state(slot,session); - } - PZ_Unlock(lock); - } -} - -/* - * context are cipher and digest contexts that are associated with a session - */ -void -sftk_FreeContext(SFTKSessionContext *context) -{ - if (context->cipherInfo) { - (*context->destroy)(context->cipherInfo,PR_TRUE); - } - if (context->hashInfo) { - (*context->hashdestroy)(context->hashInfo,PR_TRUE); - } - if (context->key) { - sftk_FreeObject(context->key); - context->key = NULL; - } - PORT_Free(context); -} - -/* - * create a new nession. NOTE: The session handle is not set, and the - * session is not added to the slot's session queue. - */ -SFTKSession * -sftk_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, - CK_FLAGS flags) -{ - SFTKSession *session; - SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); - - if (slot == NULL) return NULL; - - session = (SFTKSession*)PORT_Alloc(sizeof(SFTKSession)); - if (session == NULL) return NULL; - - session->next = session->prev = NULL; - session->refCount = 1; - session->enc_context = NULL; - session->hash_context = NULL; - session->sign_context = NULL; - session->search = NULL; - session->objectIDCount = 1; - session->objectLock = PZ_NewLock(nssILockObject); - if (session->objectLock == NULL) { - PORT_Free(session); - return NULL; - } - session->objects[0] = NULL; - - session->slot = slot; - session->notify = notify; - session->appData = pApplication; - session->info.flags = flags; - session->info.slotID = slotID; - session->info.ulDeviceError = 0; - sftk_update_state(slot,session); - return session; -} - - -/* free all the data associated with a session. */ -static void -sftk_DestroySession(SFTKSession *session) -{ - SFTKObjectList *op,*next; - PORT_Assert(session->refCount == 0); - - /* clean out the attributes */ - /* since no one is referencing us, it's safe to walk the chain - * without a lock */ - for (op = session->objects[0]; op != NULL; op = next) { - next = op->next; - /* paranoia */ - op->next = op->prev = NULL; - sftk_DeleteObject(session,op->parent); - } - PZ_DestroyLock(session->objectLock); - if (session->enc_context) { - sftk_FreeContext(session->enc_context); - } - if (session->hash_context) { - sftk_FreeContext(session->hash_context); - } - if (session->sign_context) { - sftk_FreeContext(session->sign_context); - } - if (session->search) { - sftk_FreeSearch(session->search); - } - PORT_Free(session); -} - - -/* - * look up a session structure from a session handle - * generate a reference to it. - */ -SFTKSession * -sftk_SessionFromHandle(CK_SESSION_HANDLE handle) -{ - SFTKSlot *slot = sftk_SlotFromSessionHandle(handle); - SFTKSession *session; - PZLock *lock; - - if (!slot) return NULL; - lock = SFTK_SESSION_LOCK(slot,handle); - - PZ_Lock(lock); - sftkqueue_find(session,handle,slot->head,slot->sessHashSize); - if (session) session->refCount++; - PZ_Unlock(lock); - - return (session); -} - -/* - * release a reference to a session handle - */ -void -sftk_FreeSession(SFTKSession *session) -{ - PRBool destroy = PR_FALSE; - SFTKSlot *slot = sftk_SlotFromSession(session); - PZLock *lock = SFTK_SESSION_LOCK(slot,session->handle); - - PZ_Lock(lock); - if (session->refCount == 1) destroy = PR_TRUE; - session->refCount--; - PZ_Unlock(lock); - - if (destroy) sftk_DestroySession(session); -} - -void -sftk_addHandle(SFTKSearchResults *search, CK_OBJECT_HANDLE handle) -{ - if (search->handles == NULL) { - return; - } - if (search->size >= search->array_size) { - search->array_size += NSC_SEARCH_BLOCK_SIZE; - search->handles = (CK_OBJECT_HANDLE *) PORT_Realloc(search->handles, - sizeof(CK_OBJECT_HANDLE)* search->array_size); - if (search->handles == NULL) { - return; - } - } - search->handles[search->size] = handle; - search->size++; -} - -static CK_RV -handleToClass(SFTKSlot *slot, CK_OBJECT_HANDLE handle, - CK_OBJECT_CLASS *objClass) -{ - SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, handle); - CK_ATTRIBUTE objClassTemplate; - CK_RV crv; - - *objClass = CKO_DATA; - objClassTemplate.type = CKA_CLASS; - objClassTemplate.pValue = objClass; - objClassTemplate.ulValueLen = sizeof(*objClass); - crv = sftkdb_GetAttributeValue(dbHandle, handle, &objClassTemplate, 1); - sftk_freeDB(dbHandle); - return crv; -} - -SFTKObject * -sftk_NewTokenObject(SFTKSlot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle) -{ - SFTKObject *object = NULL; - SFTKTokenObject *tokObject = NULL; - PRBool hasLocks = PR_FALSE; - CK_RV crv; - - object = sftk_GetObjectFromList(&hasLocks, PR_FALSE, &tokenObjectList, 0, - PR_FALSE); - if (object == NULL) { - return NULL; - } - tokObject = (SFTKTokenObject *) object; - - object->handle = handle; - /* every object must have a class, if we can't get it, the object - * doesn't exist */ - crv = handleToClass(slot, handle, &object->objclass); - if (crv != CKR_OK) { - goto loser; - } - object->slot = slot; - object->objectInfo = NULL; - object->infoFree = NULL; - if (!hasLocks) { - object->refLock = PZ_NewLock(nssILockRefLock); - } - if (object->refLock == NULL) { - goto loser; - } - object->refCount = 1; - - return object; -loser: - if (object) { - (void) sftk_DestroyObject(object); - } - return NULL; - -} - -SFTKTokenObject * -sftk_convertSessionToToken(SFTKObject *obj) -{ - SECItem *key; - SFTKSessionObject *so = (SFTKSessionObject *)obj; - SFTKTokenObject *to = sftk_narrowToTokenObject(obj); - SECStatus rv; - - sftk_DestroySessionObjectData(so); - PZ_DestroyLock(so->attributeLock); - if (to == NULL) { - return NULL; - } - sftk_tokenKeyLock(so->obj.slot); - key = sftk_lookupTokenKeyByHandle(so->obj.slot,so->obj.handle); - if (key == NULL) { - sftk_tokenKeyUnlock(so->obj.slot); - return NULL; - } - rv = SECITEM_CopyItem(NULL,&to->dbKey,key); - sftk_tokenKeyUnlock(so->obj.slot); - if (rv == SECFailure) { - return NULL; - } - - return to; -} - -SFTKSessionObject * -sftk_narrowToSessionObject(SFTKObject *obj) -{ - return !sftk_isToken(obj->handle) ? (SFTKSessionObject *)obj : NULL; -} - -SFTKTokenObject * -sftk_narrowToTokenObject(SFTKObject *obj) -{ - return sftk_isToken(obj->handle) ? (SFTKTokenObject *)obj : NULL; -} - diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c deleted file mode 100644 index 6c7fa0f30..000000000 --- a/security/nss/lib/softoken/rsawrapr.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * PKCS#1 encoding and decoding functions. - * This file is believed to contain no code licensed from other parties. - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#include "blapi.h" -#include "softoken.h" -#include "sechash.h" - -#include "lowkeyi.h" -#include "secerr.h" - -#define RSA_BLOCK_MIN_PAD_LEN 8 -#define RSA_BLOCK_FIRST_OCTET 0x00 -#define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00 -#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff -#define RSA_BLOCK_AFTER_PAD_OCTET 0x00 - -#define OAEP_SALT_LEN 8 -#define OAEP_PAD_LEN 8 -#define OAEP_PAD_OCTET 0x00 - -#define FLAT_BUFSIZE 512 /* bytes to hold flattened SHA1Context. */ - -static SHA1Context * -SHA1_CloneContext(SHA1Context *original) -{ - SHA1Context * clone = NULL; - unsigned char *pBuf; - int sha1ContextSize = SHA1_FlattenSize(original); - SECStatus frv; - unsigned char buf[FLAT_BUFSIZE]; - - PORT_Assert(sizeof buf >= sha1ContextSize); - if (sizeof buf >= sha1ContextSize) { - pBuf = buf; - } else { - pBuf = PORT_Alloc(sha1ContextSize); - if (!pBuf) - goto done; - } - - frv = SHA1_Flatten(original, pBuf); - if (frv == SECSuccess) { - clone = SHA1_Resurrect(pBuf, NULL); - memset(pBuf, 0, sha1ContextSize); - } -done: - if (pBuf != buf) - PORT_Free(pBuf); - return clone; -} - -/* - * Modify data by XORing it with a special hash of salt. - */ -static SECStatus -oaep_xor_with_h1(unsigned char *data, unsigned int datalen, - unsigned char *salt, unsigned int saltlen) -{ - SHA1Context *sha1cx; - unsigned char *dp, *dataend; - unsigned char end_octet; - - sha1cx = SHA1_NewContext(); - if (sha1cx == NULL) { - return SECFailure; - } - - /* - * Get a hash of salt started; we will use it several times, - * adding in a different end octet (x00, x01, x02, ...). - */ - SHA1_Begin (sha1cx); - SHA1_Update (sha1cx, salt, saltlen); - end_octet = 0; - - dp = data; - dataend = data + datalen; - - while (dp < dataend) { - SHA1Context *sha1cx_h1; - unsigned int sha1len, sha1off; - unsigned char sha1[SHA1_LENGTH]; - - /* - * Create hash of (salt || end_octet) - */ - sha1cx_h1 = SHA1_CloneContext (sha1cx); - SHA1_Update (sha1cx_h1, &end_octet, 1); - SHA1_End (sha1cx_h1, sha1, &sha1len, sizeof(sha1)); - SHA1_DestroyContext (sha1cx_h1, PR_TRUE); - PORT_Assert (sha1len == SHA1_LENGTH); - - /* - * XOR that hash with the data. - * When we have fewer than SHA1_LENGTH octets of data - * left to xor, use just the low-order ones of the hash. - */ - sha1off = 0; - if ((dataend - dp) < SHA1_LENGTH) - sha1off = SHA1_LENGTH - (dataend - dp); - while (sha1off < SHA1_LENGTH) - *dp++ ^= sha1[sha1off++]; - - /* - * Bump for next hash chunk. - */ - end_octet++; - } - - SHA1_DestroyContext (sha1cx, PR_TRUE); - return SECSuccess; -} - -/* - * Modify salt by XORing it with a special hash of data. - */ -static SECStatus -oaep_xor_with_h2(unsigned char *salt, unsigned int saltlen, - unsigned char *data, unsigned int datalen) -{ - unsigned char sha1[SHA1_LENGTH]; - unsigned char *psalt, *psha1, *saltend; - SECStatus rv; - - /* - * Create a hash of data. - */ - rv = SHA1_HashBuf (sha1, data, datalen); - if (rv != SECSuccess) { - return rv; - } - - /* - * XOR the low-order octets of that hash with salt. - */ - PORT_Assert (saltlen <= SHA1_LENGTH); - saltend = salt + saltlen; - psalt = salt; - psha1 = sha1 + SHA1_LENGTH - saltlen; - while (psalt < saltend) { - *psalt++ ^= *psha1++; - } - - return SECSuccess; -} - -/* - * Format one block of data for public/private key encryption using - * the rules defined in PKCS #1. - */ -static unsigned char * -rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, - SECItem *data) -{ - unsigned char *block; - unsigned char *bp; - int padLen; - int i; - SECStatus rv; - - block = (unsigned char *) PORT_Alloc(modulusLen); - if (block == NULL) - return NULL; - - bp = block; - - /* - * All RSA blocks start with two octets: - * 0x00 || BlockType - */ - *bp++ = RSA_BLOCK_FIRST_OCTET; - *bp++ = (unsigned char) blockType; - - switch (blockType) { - - /* - * Blocks intended for private-key operation. - */ - case RSA_BlockPrivate0: /* essentially unused */ - case RSA_BlockPrivate: /* preferred method */ - /* - * 0x00 || BT || Pad || 0x00 || ActualData - * 1 1 padLen 1 data->len - * Pad is either all 0x00 or all 0xff bytes, depending on blockType. - */ - padLen = modulusLen - data->len - 3; - PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN); - if (padLen < RSA_BLOCK_MIN_PAD_LEN) { - PORT_Free (block); - return NULL; - } - PORT_Memset (bp, - blockType == RSA_BlockPrivate0 - ? RSA_BLOCK_PRIVATE0_PAD_OCTET - : RSA_BLOCK_PRIVATE_PAD_OCTET, - padLen); - bp += padLen; - *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; - PORT_Memcpy (bp, data->data, data->len); - break; - - /* - * Blocks intended for public-key operation. - */ - case RSA_BlockPublic: - - /* - * 0x00 || BT || Pad || 0x00 || ActualData - * 1 1 padLen 1 data->len - * Pad is all non-zero random bytes. - */ - padLen = modulusLen - data->len - 3; - PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN); - if (padLen < RSA_BLOCK_MIN_PAD_LEN) { - PORT_Free (block); - return NULL; - } - for (i = 0; i < padLen; i++) { - /* Pad with non-zero random data. */ - do { - rv = RNG_GenerateGlobalRandomBytes(bp + i, 1); - } while (rv == SECSuccess && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET); - if (rv != SECSuccess) { - sftk_fatalError = PR_TRUE; - PORT_Free (block); - return NULL; - } - } - bp += padLen; - *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; - PORT_Memcpy (bp, data->data, data->len); - - break; - - /* - * Blocks intended for public-key operation, using - * Optimal Asymmetric Encryption Padding (OAEP). - */ - case RSA_BlockOAEP: - /* - * 0x00 || BT || Modified2(Salt) || Modified1(PaddedData) - * 1 1 OAEP_SALT_LEN OAEP_PAD_LEN + data->len [+ N] - * - * where: - * PaddedData is "Pad1 || ActualData [|| Pad2]" - * Salt is random data. - * Pad1 is all zeros. - * Pad2, if present, is random data. - * (The "modified" fields are all the same length as the original - * unmodified values; they are just xor'd with other values.) - * - * Modified1 is an XOR of PaddedData with a special octet - * string constructed of iterated hashing of Salt (see below). - * Modified2 is an XOR of Salt with the low-order octets of - * the hash of Modified1 (see farther below ;-). - * - * Whew! - */ - - - /* - * Salt - */ - rv = RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN); - if (rv != SECSuccess) { - sftk_fatalError = PR_TRUE; - PORT_Free (block); - return NULL; - } - bp += OAEP_SALT_LEN; - - /* - * Pad1 - */ - PORT_Memset (bp, OAEP_PAD_OCTET, OAEP_PAD_LEN); - bp += OAEP_PAD_LEN; - - /* - * Data - */ - PORT_Memcpy (bp, data->data, data->len); - bp += data->len; - - /* - * Pad2 - */ - if (bp < (block + modulusLen)) { - rv = RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen); - if (rv != SECSuccess) { - sftk_fatalError = PR_TRUE; - PORT_Free (block); - return NULL; - } - } - - /* - * Now we have the following: - * 0x00 || BT || Salt || PaddedData - * (From this point on, "Pad1 || Data [|| Pad2]" is treated - * as the one entity PaddedData.) - * - * We need to turn PaddedData into Modified1. - */ - if (oaep_xor_with_h1(block + 2 + OAEP_SALT_LEN, - modulusLen - 2 - OAEP_SALT_LEN, - block + 2, OAEP_SALT_LEN) != SECSuccess) { - PORT_Free (block); - return NULL; - } - - /* - * Now we have: - * 0x00 || BT || Salt || Modified1(PaddedData) - * - * The remaining task is to turn Salt into Modified2. - */ - if (oaep_xor_with_h2(block + 2, OAEP_SALT_LEN, - block + 2 + OAEP_SALT_LEN, - modulusLen - 2 - OAEP_SALT_LEN) != SECSuccess) { - PORT_Free (block); - return NULL; - } - - break; - - default: - PORT_Assert (0); - PORT_Free (block); - return NULL; - } - - return block; -} - -static SECStatus -rsa_FormatBlock(SECItem *result, unsigned modulusLen, - RSA_BlockType blockType, SECItem *data) -{ - /* - * XXX For now assume that the data length fits in a single - * XXX encryption block; the ASSERTs below force this. - * XXX To fix it, each case will have to loop over chunks whose - * XXX lengths satisfy the assertions, until all data is handled. - * XXX (Unless RSA has more to say about how to handle data - * XXX which does not fit in a single encryption block?) - * XXX And I do not know what the result is supposed to be, - * XXX so the interface to this function may need to change - * XXX to allow for returning multiple blocks, if they are - * XXX not wanted simply concatenated one after the other. - */ - - switch (blockType) { - case RSA_BlockPrivate0: - case RSA_BlockPrivate: - case RSA_BlockPublic: - /* - * 0x00 || BT || Pad || 0x00 || ActualData - * - * The "3" below is the first octet + the second octet + the 0x00 - * octet that always comes just before the ActualData. - */ - PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))); - - result->data = rsa_FormatOneBlock(modulusLen, blockType, data); - if (result->data == NULL) { - result->len = 0; - return SECFailure; - } - result->len = modulusLen; - - break; - - case RSA_BlockOAEP: - /* - * 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2]) - * - * The "2" below is the first octet + the second octet. - * (The other fields do not contain the clear values, but are - * the same length as the clear values.) - */ - PORT_Assert (data->len <= (modulusLen - (2 + OAEP_SALT_LEN - + OAEP_PAD_LEN))); - - result->data = rsa_FormatOneBlock(modulusLen, blockType, data); - if (result->data == NULL) { - result->len = 0; - return SECFailure; - } - result->len = modulusLen; - - break; - - case RSA_BlockRaw: - /* - * Pad || ActualData - * Pad is zeros. The application is responsible for recovering - * the actual data. - */ - if (data->len > modulusLen ) { - return SECFailure; - } - result->data = (unsigned char*)PORT_ZAlloc(modulusLen); - result->len = modulusLen; - PORT_Memcpy(result->data+(modulusLen-data->len),data->data,data->len); - break; - - default: - PORT_Assert (0); - result->data = NULL; - result->len = 0; - return SECFailure; - } - - return SECSuccess; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_Sign(NSSLOWKEYPrivateKey *key, - unsigned char * output, - unsigned int * output_len, - unsigned int maxOutputLen, - unsigned char * input, - unsigned int input_len) -{ - SECStatus rv = SECSuccess; - unsigned int modulus_len = nsslowkey_PrivateModulusLen(key); - SECItem formatted; - SECItem unformatted; - - if (maxOutputLen < modulus_len) - return SECFailure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - return SECFailure; - - unformatted.len = input_len; - unformatted.data = input; - formatted.data = NULL; - rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate, - &unformatted); - if (rv != SECSuccess) - goto done; - - rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data); - if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - *output_len = modulus_len; - - goto done; - -done: - if (formatted.data != NULL) - PORT_ZFree(formatted.data, modulus_len); - return rv; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_CheckSign(NSSLOWKEYPublicKey *key, - unsigned char * sign, - unsigned int sign_len, - unsigned char * hash, - unsigned int hash_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PublicModulusLen(key); - unsigned int i; - unsigned char * buffer; - - modulus_len = nsslowkey_PublicModulusLen(key); - if (sign_len != modulus_len) - goto failure; - /* - * 0x00 || BT || Pad || 0x00 || ActualData - * - * The "3" below is the first octet + the second octet + the 0x00 - * octet that always comes just before the ActualData. - */ - if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN)) - goto failure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - - buffer = (unsigned char *)PORT_Alloc(modulus_len + 1); - if (!buffer) - goto failure; - - rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign); - if (rv != SECSuccess) - goto loser; - - /* - * check the padding that was used - */ - if (buffer[0] != 0 || buffer[1] != 1) - goto loser; - for (i = 2; i < modulus_len - hash_len - 1; i++) { - if (buffer[i] != 0xff) - goto loser; - } - if (buffer[i] != 0) - goto loser; - - /* - * make sure we get the same results - */ - if (PORT_Memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0) - goto loser; - - PORT_Free(buffer); - return SECSuccess; - -loser: - PORT_Free(buffer); -failure: - return SECFailure; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, - unsigned char * data, - unsigned int * data_len, - unsigned int max_output_len, - unsigned char * sign, - unsigned int sign_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PublicModulusLen(key); - unsigned int i; - unsigned char * buffer; - - if (sign_len != modulus_len) - goto failure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - - buffer = (unsigned char *)PORT_Alloc(modulus_len + 1); - if (!buffer) - goto failure; - - rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign); - if (rv != SECSuccess) - goto loser; - *data_len = 0; - - /* - * check the padding that was used - */ - if (buffer[0] != 0 || buffer[1] != 1) - goto loser; - for (i = 2; i < modulus_len; i++) { - if (buffer[i] == 0) { - *data_len = modulus_len - i - 1; - break; - } - if (buffer[i] != 0xff) - goto loser; - } - if (*data_len == 0) - goto loser; - if (*data_len > max_output_len) - goto loser; - - /* - * make sure we get the same results - */ - PORT_Memcpy(data,buffer + modulus_len - *data_len, *data_len); - - PORT_Free(buffer); - return SECSuccess; - -loser: - PORT_Free(buffer); -failure: - return SECFailure; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_EncryptBlock(NSSLOWKEYPublicKey *key, - unsigned char * output, - unsigned int * output_len, - unsigned int max_output_len, - unsigned char * input, - unsigned int input_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PublicModulusLen(key); - SECItem formatted; - SECItem unformatted; - - formatted.data = NULL; - if (max_output_len < modulus_len) - goto failure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - - unformatted.len = input_len; - unformatted.data = input; - formatted.data = NULL; - rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPublic, - &unformatted); - if (rv != SECSuccess) - goto failure; - - rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data); - if (rv != SECSuccess) - goto failure; - - PORT_ZFree(formatted.data, modulus_len); - *output_len = modulus_len; - return SECSuccess; - -failure: - if (formatted.data != NULL) - PORT_ZFree(formatted.data, modulus_len); - return SECFailure; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, - unsigned char * output, - unsigned int * output_len, - unsigned int max_output_len, - unsigned char * input, - unsigned int input_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PrivateModulusLen(key); - unsigned int i; - unsigned char * buffer; - - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - if (input_len != modulus_len) - goto failure; - - buffer = (unsigned char *)PORT_Alloc(modulus_len + 1); - if (!buffer) - goto failure; - - rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - goto loser; - } - - if (buffer[0] != 0 || buffer[1] != 2) - goto loser; - *output_len = 0; - for (i = 2; i < modulus_len; i++) { - if (buffer[i] == 0) { - *output_len = modulus_len - i - 1; - break; - } - } - if (*output_len == 0) - goto loser; - if (*output_len > max_output_len) - goto loser; - - PORT_Memcpy(output, buffer + modulus_len - *output_len, *output_len); - - PORT_Free(buffer); - return SECSuccess; - -loser: - PORT_Free(buffer); -failure: - return SECFailure; -} - -/* XXX Doesn't set error code */ -/* - * added to make pkcs #11 happy - * RAW is RSA_X_509 - */ -SECStatus -RSA_SignRaw(NSSLOWKEYPrivateKey *key, - unsigned char * output, - unsigned int * output_len, - unsigned int maxOutputLen, - unsigned char * input, - unsigned int input_len) -{ - SECStatus rv = SECSuccess; - unsigned int modulus_len = nsslowkey_PrivateModulusLen(key); - SECItem formatted; - SECItem unformatted; - - if (maxOutputLen < modulus_len) - return SECFailure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - return SECFailure; - - unformatted.len = input_len; - unformatted.data = input; - formatted.data = NULL; - rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted); - if (rv != SECSuccess) - goto done; - - rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data); - if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - *output_len = modulus_len; - -done: - if (formatted.data != NULL) - PORT_ZFree(formatted.data, modulus_len); - return rv; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_CheckSignRaw(NSSLOWKEYPublicKey *key, - unsigned char * sign, - unsigned int sign_len, - unsigned char * hash, - unsigned int hash_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PublicModulusLen(key); - unsigned char * buffer; - - if (sign_len != modulus_len) - goto failure; - if (hash_len > modulus_len) - goto failure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - - buffer = (unsigned char *)PORT_Alloc(modulus_len + 1); - if (!buffer) - goto failure; - - rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign); - if (rv != SECSuccess) - goto loser; - - /* - * make sure we get the same results - */ - /* NOTE: should we verify the leading zeros? */ - if (PORT_Memcmp(buffer + (modulus_len-hash_len), hash, hash_len) != 0) - goto loser; - - PORT_Free(buffer); - return SECSuccess; - -loser: - PORT_Free(buffer); -failure: - return SECFailure; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_CheckSignRecoverRaw(NSSLOWKEYPublicKey *key, - unsigned char * data, - unsigned int * data_len, - unsigned int max_output_len, - unsigned char * sign, - unsigned int sign_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PublicModulusLen(key); - - if (sign_len != modulus_len) - goto failure; - if (max_output_len < modulus_len) - goto failure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - - rv = RSA_PublicKeyOp(&key->u.rsa, data, sign); - if (rv != SECSuccess) - goto failure; - - *data_len = modulus_len; - return SECSuccess; - -failure: - return SECFailure; -} - - -/* XXX Doesn't set error code */ -SECStatus -RSA_EncryptRaw(NSSLOWKEYPublicKey *key, - unsigned char * output, - unsigned int * output_len, - unsigned int max_output_len, - unsigned char * input, - unsigned int input_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PublicModulusLen(key); - SECItem formatted; - SECItem unformatted; - - formatted.data = NULL; - if (max_output_len < modulus_len) - goto failure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - - unformatted.len = input_len; - unformatted.data = input; - formatted.data = NULL; - rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted); - if (rv != SECSuccess) - goto failure; - - rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data); - if (rv != SECSuccess) - goto failure; - - PORT_ZFree(formatted.data, modulus_len); - *output_len = modulus_len; - return SECSuccess; - -failure: - if (formatted.data != NULL) - PORT_ZFree(formatted.data, modulus_len); - return SECFailure; -} - -/* XXX Doesn't set error code */ -SECStatus -RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, - unsigned char * output, - unsigned int * output_len, - unsigned int max_output_len, - unsigned char * input, - unsigned int input_len) -{ - SECStatus rv; - unsigned int modulus_len = nsslowkey_PrivateModulusLen(key); - - if (modulus_len <= 0) - goto failure; - if (modulus_len > max_output_len) - goto failure; - PORT_Assert(key->keyType == NSSLOWKEYRSAKey); - if (key->keyType != NSSLOWKEYRSAKey) - goto failure; - if (input_len != modulus_len) - goto failure; - - rv = RSA_PrivateKeyOp(&key->u.rsa, output, input); - if (rv != SECSuccess) { - if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { - sftk_fatalError = PR_TRUE; - } - goto failure; - } - - *output_len = modulus_len; - return SECSuccess; - -failure: - return SECFailure; -} diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c deleted file mode 100644 index 0f06a145d..000000000 --- a/security/nss/lib/softoken/sdb.c +++ /dev/null @@ -1,2058 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 Red Hat, Inc. - * - * The Initial Developer of the Original Code is - * Red Hat, Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Robert Relyea (rrelyea@redhat.com) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * This file implements PKCS 11 on top of our existing security modules - * - * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. - * This implementation has two slots: - * slot 1 is our generic crypto support. It does not require login. - * It supports Public Key ops, and all they bulk ciphers and hashes. - * It can also support Private Key ops for imported Private keys. It does - * not have any token storage. - * slot 2 is our private key support. It requires a login before use. It - * can store Private Keys and Certs as token objects. Currently only private - * keys and their associated Certificates are saved on the token. - * - * In this implementation, session objects are only visible to the session - * that created or generated them. - */ - -#include "sdb.h" -#include "pkcs11t.h" -#include "seccomon.h" -#include <sqlite3.h> -#include "prthread.h" -#include "prio.h" -#include "stdio.h" -#include "secport.h" -#include "prmon.h" -#include "prenv.h" -#include "prsystem.h" /* for PR_GetDirectorySeparator() */ -#include "sys/stat.h" -#if defined (_WIN32) -#include <io.h> -#endif - -#ifdef SQLITE_UNSAFE_THREADS -#include "prlock.h" -/* - * SQLite can be compiled to be thread safe or not. - * turn on SQLITE_UNSAFE_THREADS if the OS does not support - * a thread safe version of sqlite. - */ -static PRLock *sqlite_lock = NULL; - -#define LOCK_SQLITE() PR_Lock(sqlite_lock); -#define UNLOCK_SQLITE() PR_Unlock(sqlite_lock); -#else -#define LOCK_SQLITE() -#define UNLOCK_SQLITE() -#endif - -typedef enum { - SDB_CERT = 1, - SDB_KEY = 2 -} sdbDataType; - -/* - * defines controlling how long we wait to acquire locks. - * - * SDB_SQLITE_BUSY_TIMEOUT specifies how long (in milliseconds) - * sqlite will wait on lock. If that timeout expires, sqlite will - * return SQLITE_BUSY. - * SDB_BUSY_RETRY_TIME specifies how many seconds the sdb_ code waits - * after receiving a busy before retrying. - * SDB_MAX_BUSY_RETRIES specifies how many times the sdb_ will retry on - * a busy condition. - * - * SDB_SQLITE_BUSY_TIMEOUT affects all opertions, both manual - * (prepare/step/reset/finalize) and automatic (sqlite3_exec()). - * SDB_BUSY_RETRY_TIME and SDB_MAX_BUSY_RETRIES only affect manual operations - * - * total wait time for automatic operations: - * 1 second (SDB_SQLITE_BUSY_TIMEOUT/1000). - * total wait time for manual operations: - * (1 second + 5 seconds) * 10 = 60 seconds. - * (SDB_SQLITE_BUSY_TIMEOUT/1000 + SDB_BUSY_RETRY_TIME)*SDB_MAX_BUSY_RETRIES - */ -#define SDB_SQLITE_BUSY_TIMEOUT 1000 /* milliseconds */ -#define SDB_BUSY_RETRY_TIME 5 /* seconds */ -#define SDB_MAX_BUSY_RETRIES 10 - -/* - * Note on use of sqlReadDB: Only one thread at a time may have an actual - * operation going on given sqlite3 * database. An operation is defined as - * the time from a sqlite3_prepare() until the sqlite3_finalize(). - * Multiple sqlite3 * databases can be open and have simultaneous operations - * going. We use the sqlXactDB for all write operations. This database - * is only opened when we first create a transaction and closed when the - * transaction is complete. sqlReadDB is open when we first opened the database - * and is used for all read operation. It's use is protected by a monitor. This - * is because an operation can span the use of FindObjectsInit() through the - * call to FindObjectsFinal(). In the intermediate time it is possible to call - * other operations like NSC_GetAttributeValue */ - -struct SDBPrivateStr { - char *sqlDBName; /* invariant, path to this database */ - sqlite3 *sqlXactDB; /* access protected by dbMon, use protected - * by the transaction. Current transaction db*/ - PRThread *sqlXactThread; /* protected by dbMon, - * current transaction thread */ - sqlite3 *sqlReadDB; /* use protected by dbMon, value invariant */ - PRIntervalTime lastUpdateTime; /* last time the cache was updated */ - PRIntervalTime updateInterval; /* how long the cache can go before it - * must be updated again */ - sdbDataType type; /* invariant, database type */ - char *table; /* invariant, SQL table which contains the db */ - char *cacheTable; /* invariant, SQL table cache of db */ - PRMonitor *dbMon; /* invariant, monitor to protect - * sqlXact* fields, and use of the sqlReadDB */ -}; - -typedef struct SDBPrivateStr SDBPrivate; - -/* - * known attributes - */ -static const CK_ATTRIBUTE_TYPE known_attributes[] = { - CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION, - CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER, - CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED, - CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL, - CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY, - CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE, - CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER, - CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE, - CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT, - CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT, - CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS, - CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE, - CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, - CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS, - CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, - CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_TEMPLATE, - CKA_UNWRAP_TEMPLATE, CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, - CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, CKA_RESOLUTION, CKA_CHAR_ROWS, - CKA_CHAR_COLUMNS, CKA_COLOR, CKA_BITS_PER_PIXEL, CKA_CHAR_SETS, - CKA_ENCODING_METHODS, CKA_MIME_TYPES, CKA_MECHANISM_TYPE, - CKA_REQUIRED_CMS_ATTRIBUTES, CKA_DEFAULT_CMS_ATTRIBUTES, - CKA_SUPPORTED_CMS_ATTRIBUTES, CKA_NETSCAPE_URL, CKA_NETSCAPE_EMAIL, - CKA_NETSCAPE_SMIME_INFO, CKA_NETSCAPE_SMIME_TIMESTAMP, - CKA_NETSCAPE_PKCS8_SALT, CKA_NETSCAPE_PASSWORD_CHECK, CKA_NETSCAPE_EXPIRES, - CKA_NETSCAPE_KRL, CKA_NETSCAPE_PQG_COUNTER, CKA_NETSCAPE_PQG_SEED, - CKA_NETSCAPE_PQG_H, CKA_NETSCAPE_PQG_SEED_BITS, CKA_NETSCAPE_MODULE_SPEC, - CKA_TRUST_DIGITAL_SIGNATURE, CKA_TRUST_NON_REPUDIATION, - CKA_TRUST_KEY_ENCIPHERMENT, CKA_TRUST_DATA_ENCIPHERMENT, - CKA_TRUST_KEY_AGREEMENT, CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN, - CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING, - CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM, - CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING, - CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, - CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS -}; - -static int known_attributes_size= sizeof(known_attributes)/ - sizeof(known_attributes[0]); - -/* Magic for an explicit NULL. NOTE: ideally this should be - * out of band data. Since it's not completely out of band, pick - * a value that has no meaning to any existing PKCS #11 attributes. - * This value is 1) not a valid string (imbedded '\0'). 2) not a U_LONG - * or a normal key (too short). 3) not a bool (too long). 4) not an RSA - * public exponent (too many bits). - */ -const unsigned char SQLITE_EXPLICIT_NULL[] = { 0xa5, 0x0, 0x5a }; -#define SQLITE_EXPLICIT_NULL_LEN 3 - -/* - * determine when we've completed our tasks - */ -static int -sdb_done(int err, int *count) -{ - /* allow as many rows as the database wants to give */ - if (err == SQLITE_ROW) { - *count = 0; - return 0; - } - if (err != SQLITE_BUSY) { - return 1; - } - /* err == SQLITE_BUSY, Dont' retry forever in this case */ - if (++(*count) >= SDB_MAX_BUSY_RETRIES) { - return 1; - } - return 0; -} - -/* - * - * strdup limited to 'n' bytes. (Note: len of file is assumed to be >= len) - * - * We don't have a PORT_ version of this function, - * I suspect it's only normally available in glib, - */ -static char * -sdb_strndup(const char *file, int len) -{ - char *result = PORT_Alloc(len+1); - - if (result == NULL) { - return result; - } - - PORT_Memcpy(result, file, len); - result[len] = 0; - return result; -} - -/* - * call back from sqlite3_exec("Pragma database_list"). Looks for the - * temp directory, then return the file the temp directory is stored - * at. */ -static int -sdb_getTempDirCallback(void *arg, int columnCount, char **cval, char **cname) -{ - int i; - int found = 0; - char *file = NULL; - char *end, *dir; - char dirsep; - - /* we've already found the temp directory, don't look at any more records*/ - if (*(char **)arg) { - return SQLITE_OK; - } - - /* look at the columns to see if this record is the temp database, - * and does it say where it is stored */ - for (i=0; i < columnCount; i++) { - if (PORT_Strcmp(cname[i],"name") == 0) { - if (PORT_Strcmp(cval[i], "temp") == 0) { - found++; - continue; - } - } - if (PORT_Strcmp(cname[i],"file") == 0) { - if (cval[i] && (*cval[i] != 0)) { - file = cval[i]; - } - } - } - - /* if we couldn't find it, ask for the next record */ - if (!found || !file) { - return SQLITE_OK; - } - - /* drop of the database file name and just return the directory */ - dirsep = PR_GetDirectorySeparator(); - end = PORT_Strrchr(file, dirsep); - if (!end) { - return SQLITE_OK; - } - dir = sdb_strndup(file, end-file); - - *(char **)arg = dir; - return SQLITE_OK; -} - -/* - * find out where sqlite stores the temp tables. We do this by creating - * a temp table, then looking for the database name that sqlite3 creates. - */ -static char * -sdb_getTempDir(sqlite3 *sqlDB) -{ - char *tempDir = NULL; - int sqlerr; - - /* create a temporary table */ - sqlerr = sqlite3_exec(sqlDB, "CREATE TEMPORARY TABLE myTemp (id)", - NULL, 0, NULL); - if (sqlerr != SQLITE_OK) { - return NULL; - } - /* look for through the database list for the temp directory */ - sqlerr = sqlite3_exec(sqlDB, "PRAGMA database_list", - sdb_getTempDirCallback, &tempDir, NULL); - - /* drop the temp table we created */ - sqlite3_exec(sqlDB, "DROP TABLE myTemp", NULL, 0, NULL); - - if (sqlerr != SQLITE_OK) { - return NULL; - } - return tempDir; -} - - -/* - * Map SQL_LITE errors to PKCS #11 errors as best we can. - */ -static int -sdb_mapSQLError(sdbDataType type, int sqlerr) -{ - switch (sqlerr) { - /* good matches */ - case SQLITE_OK: - case SQLITE_DONE: - return CKR_OK; - case SQLITE_NOMEM: - return CKR_HOST_MEMORY; - case SQLITE_READONLY: - return CKR_TOKEN_WRITE_PROTECTED; - /* close matches */ - case SQLITE_AUTH: - case SQLITE_PERM: - /*return CKR_USER_NOT_LOGGED_IN; */ - case SQLITE_CANTOPEN: - case SQLITE_NOTFOUND: - /* NSS distiguishes between failure to open the cert and the key db */ - return type == SDB_CERT ? - CKR_NETSCAPE_CERTDB_FAILED : CKR_NETSCAPE_KEYDB_FAILED; - case SQLITE_IOERR: - return CKR_DEVICE_ERROR; - default: - break; - } - return CKR_GENERAL_ERROR; -} - - -/* - * build up database name from a directory, prefix, name, version and flags. - */ -static char *sdb_BuildFileName(const char * directory, - const char *prefix, const char *type, - int version, int flags) -{ - char *dbname = NULL; - /* build the full dbname */ - dbname = sqlite3_mprintf("%s/%s%s%d.db",directory, prefix, type, version); - return dbname; -} - - -/* - * find out how expensive the access system call is for non-existant files - * in the given directory. Return the number of operations done in 33 ms. - */ -static PRUint32 -sdb_measureAccess(const char *directory) -{ - PRUint32 i; - PRIntervalTime time; - PRIntervalTime delta; - PRIntervalTime duration = PR_MillisecondsToInterval(33); - - /* no directory, just return one */ - if (directory == NULL) { - return 1; - } - - /* measure number of Access operations that can be done in 33 milliseconds - * (1/30'th of a second), or 10000 operations, which ever comes first. - */ - time = PR_IntervalNow(); - for (i=0; i < 10000u; i++) { - char *temp; - PRIntervalTime next; - - temp = sdb_BuildFileName(directory,"","._dOeSnotExist_", time+i, 0); - PR_Access(temp,PR_ACCESS_EXISTS); - sqlite3_free(temp); - next = PR_IntervalNow(); - delta = next - time; - if (delta >= duration) - break; - } - - /* always return 1 or greater */ - return i ? i : 1u; -} - -/* - * some file sytems are very slow to run sqlite3 on, particularly if the - * access count is pretty high. On these filesystems is faster to create - * a temporary database on the local filesystem and access that. This - * code uses a temporary table to create that cache. Temp tables are - * automatically cleared when the database handle it was created on - * Is freed. - */ -static const char DROP_CACHE_CMD[] = "DROP TABLE %s"; -static const char CREATE_CACHE_CMD[] = - "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s"; -static const char CREATE_ISSUER_INDEX_CMD[] = - "CREATE INDEX issuer ON %s (a81)"; -static const char CREATE_SUBJECT_INDEX_CMD[] = - "CREATE INDEX subject ON %s (a101)"; -static const char CREATE_LABEL_INDEX_CMD[] = "CREATE INDEX label ON %s (a3)"; -static const char CREATE_ID_INDEX_CMD[] = "CREATE INDEX ckaid ON %s (a102)"; - -static CK_RV -sdb_buildCache(sqlite3 *sqlDB, sdbDataType type, - const char *cacheTable, const char *table) -{ - char *newStr; - int sqlerr = SQLITE_OK; - - newStr = sqlite3_mprintf(CREATE_CACHE_CMD, cacheTable, table); - if (newStr == NULL) { - return CKR_HOST_MEMORY; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) { - return sdb_mapSQLError(type, sqlerr); - } - /* failure to create the indexes is not an issue */ - newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, cacheTable); - if (newStr == NULL) { - return CKR_OK; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, cacheTable); - if (newStr == NULL) { - return CKR_OK; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, cacheTable); - if (newStr == NULL) { - return CKR_OK; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, cacheTable); - if (newStr == NULL) { - return CKR_OK; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - return CKR_OK; -} - -/* - * update the cache and the data records describing it. - * The cache is updated by dropping the temp database and recreating it. - */ -static CK_RV -sdb_updateCache(SDBPrivate *sdb_p) -{ - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - char *newStr; - - /* drop the old table */ - newStr = sqlite3_mprintf(DROP_CACHE_CMD, sdb_p->cacheTable); - if (newStr == NULL) { - return CKR_HOST_MEMORY; - } - sqlerr = sqlite3_exec(sdb_p->sqlReadDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - if ((sqlerr != SQLITE_OK) && (sqlerr != SQLITE_ERROR )) { - /* something went wrong with the drop, don't try to refresh... - * NOTE: SQLITE_ERROR is returned if the table doesn't exist. In - * that case, we just continue on and try to reload it */ - return sdb_mapSQLError(sdb_p->type, sqlerr); - } - - - /* set up the new table */ - error = sdb_buildCache(sdb_p->sqlReadDB,sdb_p->type, - sdb_p->cacheTable,sdb_p->table ); - if (error == CKR_OK) { - /* we have a new cache! */ - sdb_p->lastUpdateTime = PR_IntervalNow(); - } - return error; -} - -/* - * The sharing of sqlite3 handles across threads is tricky. Older versions - * couldn't at all, but newer ones can under strict conditions. Basically - * no 2 threads can use the same handle while another thread has an open - * stmt running. Once the sqlite3_stmt is finalized, another thread can then - * use the database handle. - * - * We use monitors to protect against trying to use a database before - * it's sqlite3_stmt is finalized. This is preferable to the opening and - * closing the database each operation because there is significant overhead - * in the open and close. Also continually opening and closing the database - * defeats the cache code as the cache table is lost on close (thus - * requiring us to have to reinitialize the cache every operation). - * - * An execption to the shared handle is transations. All writes happen - * through a transaction. When we are in a transaction, we must use the - * same database pointer for that entire transation. In this case we save - * the transaction database and use it for all accesses on the transaction - * thread. Other threads use the common database. - * - * There can only be once active transaction on the database at a time. - * - * sdb_openDBLocal() provides us with a valid database handle for whatever - * state we are in (reading or in a transaction), and acquires any locks - * appropriate to that state. It also decides when it's time to refresh - * the cache before we start an operation. Any database handle returned - * just eventually be closed with sdb_closeDBLocal(). - * - * The table returned either points to the database's physical table, or - * to the cached shadow. Tranactions always return the physical table - * and read operations return either the physical table or the cache - * depending on whether or not the cache exists. - */ -static CK_RV -sdb_openDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB, const char **table) -{ - *sqlDB = NULL; - - PR_EnterMonitor(sdb_p->dbMon); - - if (table) { - *table = sdb_p->table; - } - - /* We're in a transaction, use the transaction DB */ - if ((sdb_p->sqlXactDB) && (sdb_p->sqlXactThread == PR_GetCurrentThread())) { - *sqlDB =sdb_p->sqlXactDB; - /* only one thread can get here, safe to unlock */ - PR_ExitMonitor(sdb_p->dbMon); - return CKR_OK; - } - - /* - * if we are just reading from the table, we may have the table - * cached in a temporary table (especially if it's on a shared FS). - * In that case we want to see updates to the table, the the granularity - * is on order of human scale, not computer scale. - */ - if (table && sdb_p->cacheTable) { - PRIntervalTime now = PR_IntervalNow(); - if ((now - sdb_p->lastUpdateTime) > sdb_p->updateInterval) { - sdb_updateCache(sdb_p); - } - *table = sdb_p->cacheTable; - } - - *sqlDB = sdb_p->sqlReadDB; - - /* leave holding the lock. only one thread can actually use a given - * database connection at once */ - - return CKR_OK; -} - -/* closing the local database currenly means unlocking the monitor */ -static CK_RV -sdb_closeDBLocal(SDBPrivate *sdb_p, sqlite3 *sqlDB) -{ - if (sdb_p->sqlXactDB != sqlDB) { - /* if we weren't in a transaction, we got a lock */ - PR_ExitMonitor(sdb_p->dbMon); - } - return CKR_OK; -} - - -/* - * wrapper to sqlite3_open which also sets the busy_timeout - */ -static int -sdb_openDB(const char *name, sqlite3 **sqlDB, int flags) -{ - int sqlerr; - /* - * in sqlite3 3.5.0, there is a new open call that allows us - * to specify read only. Most new OS's are still on 3.3.x (including - * NSS's internal version and the version shipped with Firefox). - */ - *sqlDB = NULL; - sqlerr = sqlite3_open(name, sqlDB); - if (sqlerr != SQLITE_OK) { - return sqlerr; - } - - sqlerr = sqlite3_busy_timeout(*sqlDB, SDB_SQLITE_BUSY_TIMEOUT); - if (sqlerr != SQLITE_OK) { - sqlite3_close(*sqlDB); - *sqlDB = NULL; - return sqlerr; - } - return SQLITE_OK; -} - -/* Sigh, if we created a new table since we opened the database, - * the database handle will not see the new table, we need to close this - * database and reopen it. Caller must be in a transaction or holding - * the dbMon. sqlDB is changed on success. */ -static int -sdb_reopenDBLocal(SDBPrivate *sdb_p, sqlite3 **sqlDB) { - sqlite3 *newDB; - int sqlerr; - - /* open a new database */ - sqlerr = sdb_openDB(sdb_p->sqlDBName, &newDB, SDB_RDONLY); - if (sqlerr != SQLITE_OK) { - return sqlerr; - } - - /* if we are in a transaction, we may not be holding the monitor. - * grab it before we update the transaction database. This is - * safe since are using monitors. */ - PR_EnterMonitor(sdb_p->dbMon); - /* update our view of the database */ - if (sdb_p->sqlReadDB == *sqlDB) { - sdb_p->sqlReadDB = newDB; - } else if (sdb_p->sqlXactDB == *sqlDB) { - sdb_p->sqlXactDB = newDB; - } - PR_ExitMonitor(sdb_p->dbMon); - - /* close the old one */ - sqlite3_close(*sqlDB); - - *sqlDB = newDB; - return SQLITE_OK; -} - -struct SDBFindStr { - sqlite3 *sqlDB; - sqlite3_stmt *findstmt; -}; - - -static const char FIND_OBJECTS_CMD[] = "SELECT ALL * FROM %s WHERE %s;"; -static const char FIND_OBJECTS_ALL_CMD[] = "SELECT ALL * FROM %s;"; -CK_RV -sdb_FindObjectsInit(SDB *sdb, const CK_ATTRIBUTE *template, CK_ULONG count, - SDBFind **find) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - const char *table; - char *newStr, *findStr = NULL; - sqlite3_stmt *findstmt = NULL; - char *join=""; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - int i; - - LOCK_SQLITE() - *find = NULL; - error = sdb_openDBLocal(sdb_p, &sqlDB, &table); - if (error != CKR_OK) { - goto loser; - } - - findStr = sqlite3_mprintf(""); - for (i=0; findStr && i < count; i++) { - newStr = sqlite3_mprintf("%s%sa%x=$DATA%d", findStr, join, - template[i].type, i); - join=" AND "; - sqlite3_free(findStr); - findStr = newStr; - } - - if (findStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - - if (count == 0) { - newStr = sqlite3_mprintf(FIND_OBJECTS_ALL_CMD, table); - } else { - newStr = sqlite3_mprintf(FIND_OBJECTS_CMD, table, findStr); - } - sqlite3_free(findStr); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &findstmt, NULL); - sqlite3_free(newStr); - for (i=0; sqlerr == SQLITE_OK && i < count; i++) { - const void *blobData = template[i].pValue; - unsigned int blobSize = template[i].ulValueLen; - if (blobSize == 0) { - blobSize = SQLITE_EXPLICIT_NULL_LEN; - blobData = SQLITE_EXPLICIT_NULL; - } - sqlerr = sqlite3_bind_blob(findstmt, i+1, blobData, blobSize, - SQLITE_TRANSIENT); - } - if (sqlerr == SQLITE_OK) { - *find = PORT_New(SDBFind); - if (*find == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - (*find)->findstmt = findstmt; - (*find)->sqlDB = sqlDB; - UNLOCK_SQLITE() - return CKR_OK; - } - error = sdb_mapSQLError(sdb_p->type, sqlerr); - -loser: - if (findstmt) { - sqlite3_finalize(findstmt); - } - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - UNLOCK_SQLITE() - return error; -} - - -CK_RV -sdb_FindObjects(SDB *sdb, SDBFind *sdbFind, CK_OBJECT_HANDLE *object, - CK_ULONG arraySize, CK_ULONG *count) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3_stmt *stmt = sdbFind->findstmt; - int sqlerr = SQLITE_OK; - int retry = 0; - - *count = 0; - - if (arraySize == 0) { - return CKR_OK; - } - LOCK_SQLITE() - - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - if (sqlerr == SQLITE_ROW) { - /* only care about the id */ - *object++= sqlite3_column_int(stmt, 0); - arraySize--; - (*count)++; - } - } while (!sdb_done(sqlerr,&retry) && (arraySize > 0)); - - /* we only have some of the objects, there is probably more, - * set the sqlerr to an OK value so we return CKR_OK */ - if (sqlerr == SQLITE_ROW && arraySize == 0) { - sqlerr = SQLITE_DONE; - } - UNLOCK_SQLITE() - - return sdb_mapSQLError(sdb_p->type, sqlerr); -} - -CK_RV -sdb_FindObjectsFinal(SDB *sdb, SDBFind *sdbFind) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3_stmt *stmt = sdbFind->findstmt; - sqlite3 *sqlDB = sdbFind->sqlDB; - int sqlerr = SQLITE_OK; - - LOCK_SQLITE() - if (stmt) { - sqlite3_reset(stmt); - sqlerr = sqlite3_finalize(stmt); - } - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - PORT_Free(sdbFind); - - UNLOCK_SQLITE() - return sdb_mapSQLError(sdb_p->type, sqlerr); -} - -static const char GET_ATTRIBUTE_CMD[] = "SELECT ALL %s FROM %s WHERE id=$ID;"; -CK_RV -sdb_GetAttributeValueNoLock(SDB *sdb, CK_OBJECT_HANDLE object_id, - CK_ATTRIBUTE *template, CK_ULONG count) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - sqlite3_stmt *stmt = NULL; - char *getStr = NULL; - char *newStr = NULL; - const char *table = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - int found = 0; - int retry = 0; - int i; - - - /* open a new db if necessary */ - error = sdb_openDBLocal(sdb_p, &sqlDB, &table); - if (error != CKR_OK) { - goto loser; - } - - getStr = sqlite3_mprintf(""); - for (i=0; getStr && i < count; i++) { - if (i==0) { - newStr = sqlite3_mprintf("a%x", template[i].type); - } else { - newStr = sqlite3_mprintf("%s, a%x", getStr, template[i].type); - } - sqlite3_free(getStr); - getStr = newStr; - } - - if (getStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - - newStr = sqlite3_mprintf(GET_ATTRIBUTE_CMD, getStr, table); - sqlite3_free(getStr); - getStr = NULL; - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - - sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL); - if (sqlerr != SQLITE_OK) { goto loser; } - sqlerr = sqlite3_bind_int(stmt, 1, object_id); - if (sqlerr != SQLITE_OK) { goto loser; } - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - if (sqlerr == SQLITE_ROW) { - for (i=0; i < count; i++) { - int column = i; - int blobSize; - const char *blobData; - - blobSize = sqlite3_column_bytes(stmt, column); - blobData = sqlite3_column_blob(stmt, column); - if (blobData == NULL) { - template[i].ulValueLen = -1; - error = CKR_ATTRIBUTE_TYPE_INVALID; - continue; - } - /* If the blob equals our explicit NULL value, then the - * attribute is a NULL. */ - if ((blobSize == SQLITE_EXPLICIT_NULL_LEN) && - (PORT_Memcmp(blobData, SQLITE_EXPLICIT_NULL, - SQLITE_EXPLICIT_NULL_LEN) == 0)) { - blobSize = 0; - } - if (template[i].pValue) { - if (template[i].ulValueLen < blobSize) { - template[i].ulValueLen = -1; - error = CKR_BUFFER_TOO_SMALL; - continue; - } - PORT_Memcpy(template[i].pValue, blobData, blobSize); - } - template[i].ulValueLen = blobSize; - } - found = 1; - } - } while (!sdb_done(sqlerr,&retry)); - -loser: - /* fix up the error if necessary */ - if (error == CKR_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - if (!found && error == CKR_OK) { - error = CKR_OBJECT_HANDLE_INVALID; - } - } - if (newStr) { - sqlite3_free(newStr); - } - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - - /* if we had to open a new database, free it now */ - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - return error; -} - -CK_RV -sdb_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, - CK_ATTRIBUTE *template, CK_ULONG count) -{ - CK_RV crv; - - if (count == 0) { - return CKR_OK; - } - - LOCK_SQLITE() - crv = sdb_GetAttributeValueNoLock(sdb, object_id, template, count); - UNLOCK_SQLITE() - return crv; -} - -static const char SET_ATTRIBUTE_CMD[] = "UPDATE %s SET %s WHERE id=$ID;"; -CK_RV -sdb_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE object_id, - const CK_ATTRIBUTE *template, CK_ULONG count) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - sqlite3_stmt *stmt = NULL; - char *setStr = NULL; - char *newStr = NULL; - int sqlerr = SQLITE_OK; - int retry = 0; - CK_RV error = CKR_OK; - int i; - - if ((sdb->sdb_flags & SDB_RDONLY) != 0) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - if (count == 0) { - return CKR_OK; - } - - LOCK_SQLITE() - setStr = sqlite3_mprintf(""); - for (i=0; setStr && i < count; i++) { - if (i==0) { - sqlite3_free(setStr); - setStr = sqlite3_mprintf("a%x=$VALUE%d", - template[i].type, i); - continue; - } - newStr = sqlite3_mprintf("%s,a%x=$VALUE%d", setStr, - template[i].type, i); - sqlite3_free(setStr); - setStr = newStr; - } - newStr = NULL; - - if (setStr == NULL) { - return CKR_HOST_MEMORY; - } - newStr = sqlite3_mprintf(SET_ATTRIBUTE_CMD, sdb_p->table, setStr); - sqlite3_free(setStr); - if (newStr == NULL) { - UNLOCK_SQLITE() - return CKR_HOST_MEMORY; - } - error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); - if (error != CKR_OK) { - goto loser; - } - sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL); - if (sqlerr != SQLITE_OK) goto loser; - for (i=0; i < count; i++) { - if (template[i].ulValueLen != 0) { - sqlerr = sqlite3_bind_blob(stmt, i+1, template[i].pValue, - template[i].ulValueLen, SQLITE_STATIC); - } else { - sqlerr = sqlite3_bind_blob(stmt, i+2, SQLITE_EXPLICIT_NULL, - SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC); - } - if (sqlerr != SQLITE_OK) goto loser; - } - sqlerr = sqlite3_bind_int(stmt, i+1, object_id); - if (sqlerr != SQLITE_OK) goto loser; - - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - } while (!sdb_done(sqlerr,&retry)); - -loser: - if (newStr) { - sqlite3_free(newStr); - } - if (error == CKR_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - } - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - - UNLOCK_SQLITE() - return error; -} - -/* - * check to see if a candidate object handle already exists. - */ -static PRBool -sdb_objectExists(SDB *sdb, CK_OBJECT_HANDLE candidate) -{ - CK_RV crv; - CK_ATTRIBUTE template = { CKA_LABEL, NULL, 0 }; - - crv = sdb_GetAttributeValueNoLock(sdb,candidate,&template, 1); - if (crv == CKR_OBJECT_HANDLE_INVALID) { - return PR_FALSE; - } - return PR_TRUE; -} - -/* - * if we're here, we are in a transaction, so it's safe - * to examine the current state of the database - */ -static CK_OBJECT_HANDLE -sdb_getObjectId(SDB *sdb) -{ - CK_OBJECT_HANDLE candidate; - static CK_OBJECT_HANDLE next_obj = CK_INVALID_HANDLE; - int count; - /* - * get an initial object handle to use - */ - if (next_obj == CK_INVALID_HANDLE) { - PRTime time; - time = PR_Now(); - - next_obj = (CK_OBJECT_HANDLE)(time & 0x3fffffffL); - } - candidate = next_obj++; - /* detect that we've looped through all the handles... */ - for (count = 0; count < 0x40000000; count++, candidate = next_obj++) { - /* mask off excess bits */ - candidate &= 0x3fffffff; - /* if we hit zero, go to the next entry */ - if (candidate == CK_INVALID_HANDLE) { - continue; - } - /* make sure we aren't already using */ - if (!sdb_objectExists(sdb, candidate)) { - /* this one is free */ - return candidate; - } - } - - /* no handle is free, fail */ - return CK_INVALID_HANDLE; -} - -static const char CREATE_CMD[] = "INSERT INTO %s (id%s) VALUES($ID%s);"; -CK_RV -sdb_CreateObject(SDB *sdb, CK_OBJECT_HANDLE *object_id, - const CK_ATTRIBUTE *template, CK_ULONG count) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - sqlite3_stmt *stmt = NULL; - char *columnStr = NULL; - char *valueStr = NULL; - char *newStr = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - CK_OBJECT_HANDLE this_object = CK_INVALID_HANDLE; - int retry = 0; - int i; - - if ((sdb->sdb_flags & SDB_RDONLY) != 0) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - LOCK_SQLITE() - if ((*object_id != CK_INVALID_HANDLE) && - !sdb_objectExists(sdb, *object_id)) { - this_object = *object_id; - } else { - this_object = sdb_getObjectId(sdb); - } - if (this_object == CK_INVALID_HANDLE) { - UNLOCK_SQLITE(); - return CKR_HOST_MEMORY; - } - columnStr = sqlite3_mprintf(""); - valueStr = sqlite3_mprintf(""); - *object_id = this_object; - for (i=0; columnStr && valueStr && i < count; i++) { - newStr = sqlite3_mprintf("%s,a%x", columnStr, template[i].type); - sqlite3_free(columnStr); - columnStr = newStr; - newStr = sqlite3_mprintf("%s,$VALUE%d", valueStr, i); - sqlite3_free(valueStr); - valueStr = newStr; - } - newStr = NULL; - if ((columnStr == NULL) || (valueStr == NULL)) { - if (columnStr) { - sqlite3_free(columnStr); - } - if (valueStr) { - sqlite3_free(valueStr); - } - UNLOCK_SQLITE() - return CKR_HOST_MEMORY; - } - newStr = sqlite3_mprintf(CREATE_CMD, sdb_p->table, columnStr, valueStr); - sqlite3_free(columnStr); - sqlite3_free(valueStr); - error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); - if (error != CKR_OK) { - goto loser; - } - sqlerr = sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL); - if (sqlerr != SQLITE_OK) goto loser; - sqlerr = sqlite3_bind_int(stmt, 1, *object_id); - if (sqlerr != SQLITE_OK) goto loser; - for (i=0; i < count; i++) { - if (template[i].ulValueLen) { - sqlerr = sqlite3_bind_blob(stmt, i+2, template[i].pValue, - template[i].ulValueLen, SQLITE_STATIC); - } else { - sqlerr = sqlite3_bind_blob(stmt, i+2, SQLITE_EXPLICIT_NULL, - SQLITE_EXPLICIT_NULL_LEN, SQLITE_STATIC); - } - if (sqlerr != SQLITE_OK) goto loser; - } - - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - } while (!sdb_done(sqlerr,&retry)); - -loser: - if (newStr) { - sqlite3_free(newStr); - } - if (error == CKR_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - } - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - UNLOCK_SQLITE() - - return error; -} - -static const char DESTROY_CMD[] = "DELETE FROM %s WHERE (id=$ID);"; -CK_RV -sdb_DestroyObject(SDB *sdb, CK_OBJECT_HANDLE object_id) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - sqlite3_stmt *stmt = NULL; - char *newStr = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - int retry = 0; - - if ((sdb->sdb_flags & SDB_RDONLY) != 0) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - LOCK_SQLITE() - error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); - if (error != CKR_OK) { - goto loser; - } - newStr = sqlite3_mprintf(DESTROY_CMD, sdb_p->table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr =sqlite3_prepare_v2(sqlDB, newStr, -1, &stmt, NULL); - sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) goto loser; - sqlerr =sqlite3_bind_int(stmt, 1, object_id); - if (sqlerr != SQLITE_OK) goto loser; - - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - } while (!sdb_done(sqlerr,&retry)); - -loser: - if (error == CKR_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - } - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - - UNLOCK_SQLITE() - return error; -} - -static const char BEGIN_CMD[] = "BEGIN IMMEDIATE TRANSACTION;"; -/* - * start a transaction. - * - * We need to open a new database, then store that new database into - * the private data structure. We open the database first, then use locks - * to protect storing the data to prevent deadlocks. - */ -CK_RV -sdb_Begin(SDB *sdb) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - sqlite3_stmt *stmt = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - int retry = 0; - - - if ((sdb->sdb_flags & SDB_RDONLY) != 0) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - - LOCK_SQLITE() - - /* get a new version that we will use for the entire transaction */ - sqlerr = sdb_openDB(sdb_p->sqlDBName, &sqlDB, SDB_RDWR); - if (sqlerr != SQLITE_OK) { - goto loser; - } - - sqlerr =sqlite3_prepare_v2(sqlDB, BEGIN_CMD, -1, &stmt, NULL); - - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - } while (!sdb_done(sqlerr,&retry)); - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - -loser: - error = sdb_mapSQLError(sdb_p->type, sqlerr); - - /* we are starting a new transaction, - * and if we succeeded, then save this database for the rest of - * our transaction */ - if (error == CKR_OK) { - /* we hold a 'BEGIN TRANSACTION' and a sdb_p->lock. At this point - * sdb_p->sqlXactDB MUST be null */ - PR_EnterMonitor(sdb_p->dbMon); - PORT_Assert(sdb_p->sqlXactDB == NULL); - sdb_p->sqlXactDB = sqlDB; - sdb_p->sqlXactThread = PR_GetCurrentThread(); - PR_ExitMonitor(sdb_p->dbMon); - } else { - /* we failed to start our transaction, - * free any databases we opened. */ - if (sqlDB) { - sqlite3_close(sqlDB); - } - } - - UNLOCK_SQLITE() - return error; -} - -/* - * Complete a transaction. Basically undo everything we did in begin. - * There are 2 flavors Abort and Commit. Basically the only differerence between - * these 2 are what the database will show. (no change in to former, change in - * the latter). - */ -static CK_RV -sdb_complete(SDB *sdb, const char *cmd) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - sqlite3_stmt *stmt = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - int retry = 0; - - - if ((sdb->sdb_flags & SDB_RDONLY) != 0) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - /* We must have a transation database, or we shouldn't have arrived here */ - PR_EnterMonitor(sdb_p->dbMon); - PORT_Assert(sdb_p->sqlXactDB); - if (sdb_p->sqlXactDB == NULL) { - PR_ExitMonitor(sdb_p->dbMon); - return CKR_GENERAL_ERROR; /* shouldn't happen */ - } - PORT_Assert( sdb_p->sqlXactThread == PR_GetCurrentThread()); - if ( sdb_p->sqlXactThread != PR_GetCurrentThread()) { - PR_ExitMonitor(sdb_p->dbMon); - return CKR_GENERAL_ERROR; /* shouldn't happen */ - } - sqlDB = sdb_p->sqlXactDB; - sdb_p->sqlXactDB = NULL; /* no one else can get to this DB, - * safe to unlock */ - sdb_p->sqlXactThread = NULL; - PR_ExitMonitor(sdb_p->dbMon); - - sqlerr =sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL); - - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - } while (!sdb_done(sqlerr,&retry)); - - /* Pending BEGIN TRANSACTIONS Can move forward at this point. */ - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - - /* we we have a cached DB image, update it as well */ - if (sdb_p->cacheTable) { - PR_EnterMonitor(sdb_p->dbMon); - sdb_updateCache(sdb_p); - PR_ExitMonitor(sdb_p->dbMon); - } - - error = sdb_mapSQLError(sdb_p->type, sqlerr); - - /* We just finished a transaction. - * Free the database, and remove it from the list */ - sqlite3_close(sqlDB); - - return error; -} - -static const char COMMIT_CMD[] = "COMMIT TRANSACTION;"; -CK_RV -sdb_Commit(SDB *sdb) -{ - CK_RV crv; - LOCK_SQLITE() - crv = sdb_complete(sdb,COMMIT_CMD); - UNLOCK_SQLITE() - return crv; -} - -static const char ROLLBACK_CMD[] = "ROLLBACK TRANSACTION;"; -CK_RV -sdb_Abort(SDB *sdb) -{ - CK_RV crv; - LOCK_SQLITE() - crv = sdb_complete(sdb,ROLLBACK_CMD); - UNLOCK_SQLITE() - return crv; -} - -static int tableExists(sqlite3 *sqlDB, const char *tableName); - -static const char GET_PW_CMD[] = "SELECT ALL * FROM metaData WHERE id=$ID;"; -CK_RV -sdb_GetMetaData(SDB *sdb, const char *id, SECItem *item1, SECItem *item2) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = sdb_p->sqlXactDB; - sqlite3_stmt *stmt = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - int found = 0; - int retry = 0; - - LOCK_SQLITE() - error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); - if (error != CKR_OK) { - goto loser; - } - - /* handle 'test' versions of the sqlite db */ - sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL); - /* Sigh, if we created a new table since we opened the database, - * the database handle will not see the new table, we need to close this - * database and reopen it. This is safe because we are holding the lock - * still. */ - if (sqlerr == SQLITE_SCHEMA) { - sqlerr = sdb_reopenDBLocal(sdb_p, &sqlDB); - if (sqlerr != SQLITE_OK) { - goto loser; - } - sqlerr = sqlite3_prepare_v2(sqlDB, GET_PW_CMD, -1, &stmt, NULL); - } - if (sqlerr != SQLITE_OK) goto loser; - sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC); - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - if (sqlerr == SQLITE_ROW) { - const char *blobData; - unsigned int len = item1->len; - item1->len = sqlite3_column_bytes(stmt, 1); - if (item1->len > len) { - error = CKR_BUFFER_TOO_SMALL; - continue; - } - blobData = sqlite3_column_blob(stmt, 1); - PORT_Memcpy(item1->data,blobData, item1->len); - if (item2) { - len = item2->len; - item2->len = sqlite3_column_bytes(stmt, 2); - if (item2->len > len) { - error = CKR_BUFFER_TOO_SMALL; - continue; - } - blobData = sqlite3_column_blob(stmt, 2); - PORT_Memcpy(item2->data,blobData, item2->len); - } - found = 1; - } - } while (!sdb_done(sqlerr,&retry)); - -loser: - /* fix up the error if necessary */ - if (error == CKR_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - if (!found && error == CKR_OK) { - error = CKR_OBJECT_HANDLE_INVALID; - } - } - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - UNLOCK_SQLITE() - - return error; -} - -static const char PW_CREATE_TABLE_CMD[] = - "CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2);"; -static const char PW_CREATE_CMD[] = - "INSERT INTO metaData (id,item1,item2) VALUES($ID,$ITEM1,$ITEM2);"; -static const char MD_CREATE_CMD[] = - "INSERT INTO metaData (id,item1) VALUES($ID,$ITEM1);"; -CK_RV -sdb_PutMetaData(SDB *sdb, const char *id, const SECItem *item1, - const SECItem *item2) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = sdb_p->sqlXactDB; - sqlite3_stmt *stmt = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - int retry = 0; - const char *cmd = PW_CREATE_CMD; - - if ((sdb->sdb_flags & SDB_RDONLY) != 0) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - LOCK_SQLITE() - error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); - if (error != CKR_OK) { - goto loser; - } - - if (!tableExists(sqlDB, "metaData")) { - sqlerr = sqlite3_exec(sqlDB, PW_CREATE_TABLE_CMD, NULL, 0, NULL); - if (sqlerr != SQLITE_OK) goto loser; - } - if (item2 == NULL) { - cmd = MD_CREATE_CMD; - } - sqlerr = sqlite3_prepare_v2(sqlDB, cmd, -1, &stmt, NULL); - if (sqlerr != SQLITE_OK) goto loser; - sqlerr = sqlite3_bind_text(stmt, 1, id, PORT_Strlen(id), SQLITE_STATIC); - if (sqlerr != SQLITE_OK) goto loser; - sqlerr = sqlite3_bind_blob(stmt, 2, item1->data, item1->len, SQLITE_STATIC); - if (sqlerr != SQLITE_OK) goto loser; - if (item2) { - sqlerr = sqlite3_bind_blob(stmt, 3, item2->data, - item2->len, SQLITE_STATIC); - if (sqlerr != SQLITE_OK) goto loser; - } - - do { - sqlerr = sqlite3_step(stmt); - if (sqlerr == SQLITE_BUSY) { - PR_Sleep(SDB_BUSY_RETRY_TIME); - } - } while (!sdb_done(sqlerr,&retry)); - -loser: - /* fix up the error if necessary */ - if (error == CKR_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - } - - if (stmt) { - sqlite3_reset(stmt); - sqlite3_finalize(stmt); - } - - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - UNLOCK_SQLITE() - - return error; -} - -static const char RESET_CMD[] = "DROP TABLE IF EXISTS %s;"; -CK_RV -sdb_Reset(SDB *sdb) -{ - SDBPrivate *sdb_p = sdb->private; - sqlite3 *sqlDB = NULL; - char *newStr; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - - /* only Key databases can be reset */ - if (sdb_p->type != SDB_KEY) { - return CKR_OBJECT_HANDLE_INVALID; - } - - LOCK_SQLITE() - error = sdb_openDBLocal(sdb_p, &sqlDB, NULL); - if (error != CKR_OK) { - goto loser; - } - - /* delete the key table */ - newStr = sqlite3_mprintf(RESET_CMD, sdb_p->table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - - if (sqlerr != SQLITE_OK) goto loser; - - /* delete the password entry table */ - sqlerr = sqlite3_exec(sqlDB, "DROP TABLE IF EXISTS metaData;", - NULL, 0, NULL); - -loser: - /* fix up the error if necessary */ - if (error == CKR_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - } - - if (sqlDB) { - sdb_closeDBLocal(sdb_p, sqlDB) ; - } - - UNLOCK_SQLITE() - return error; -} - - -CK_RV -sdb_Close(SDB *sdb) -{ - SDBPrivate *sdb_p = sdb->private; - int sqlerr = SQLITE_OK; - sdbDataType type = sdb_p->type; - - sqlerr = sqlite3_close(sdb_p->sqlReadDB); - PORT_Free(sdb_p->sqlDBName); - if (sdb_p->cacheTable) { - sqlite3_free(sdb_p->cacheTable); - } - if (sdb_p->dbMon) { - PR_DestroyMonitor(sdb_p->dbMon); - } - free(sdb_p); - free(sdb); - return sdb_mapSQLError(type, sqlerr); -} - - -/* - * functions to support open - */ - -static const char CHECK_TABLE_CMD[] = "SELECT ALL * FROM %s LIMIT 0;"; -/* return 1 if sqlDB contains table 'tableName */ -static int tableExists(sqlite3 *sqlDB, const char *tableName) -{ - char * cmd = sqlite3_mprintf(CHECK_TABLE_CMD, tableName); - int sqlerr = SQLITE_OK; - - if (cmd == NULL) { - return 0; - } - - sqlerr = sqlite3_exec(sqlDB, cmd, NULL, 0, 0); - sqlite3_free(cmd); - - return (sqlerr == SQLITE_OK) ? 1 : 0; -} - -void sdb_SetForkState(PRBool forked) -{ - /* XXXright now this is a no-op. The global fork state in the softokn3 - * shared library is already taken care of at the PKCS#11 level. - * If and when we add fork state to the sqlite shared library and extern - * interface, we will need to set it and reset it from here */ -} - -/* - * initialize a single database - */ -static const char INIT_CMD[] = - "CREATE TABLE %s (id PRIMARY KEY UNIQUE ON CONFLICT ABORT%s)"; -static const char ALTER_CMD[] = - "ALTER TABLE %s ADD COLUMN a%x"; - -CK_RV -sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate, - int *newInit, int flags, PRUint32 accessOps, SDB **pSdb) -{ - int i; - char *initStr = NULL; - char *newStr; - int inTransaction = 0; - SDB *sdb = NULL; - SDBPrivate *sdb_p = NULL; - sqlite3 *sqlDB = NULL; - int sqlerr = SQLITE_OK; - CK_RV error = CKR_OK; - char *cacheTable = NULL; - PRIntervalTime now = 0; - char *env; - PRBool enableCache = PR_FALSE; - PRBool create; - - *pSdb = NULL; - *inUpdate = 0; - - /* sqlite3 doesn't have a flag to specify that we want to - * open the database read only. If the db doesn't exist, - * sqlite3 will always create it. - */ - LOCK_SQLITE(); - create = (PR_Access(dbname, PR_ACCESS_EXISTS) != PR_SUCCESS); - if ((flags == SDB_RDONLY) && create) { - error = sdb_mapSQLError(type, SQLITE_CANTOPEN); - goto loser; - } - sqlerr = sdb_openDB(dbname, &sqlDB, flags); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(type, sqlerr); - goto loser; - } - /* sql created the file, but it doesn't set appropriate modes for - * a database */ - if (create) { - /* NO NSPR call for this? :( */ - chmod (dbname, 0600); - } - - if (flags != SDB_RDONLY) { - sqlerr = sqlite3_exec(sqlDB, BEGIN_CMD, NULL, 0, NULL); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(type, sqlerr); - goto loser; - } - inTransaction = 1; - } - if (!tableExists(sqlDB,table)) { - *newInit = 1; - if (flags != SDB_CREATE) { - error = sdb_mapSQLError(type, SQLITE_CANTOPEN); - goto loser; - } - initStr = sqlite3_mprintf(""); - for (i=0; initStr && i < known_attributes_size; i++) { - newStr = sqlite3_mprintf("%s, a%x",initStr, known_attributes[i]); - sqlite3_free(initStr); - initStr = newStr; - } - if (initStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - - newStr = sqlite3_mprintf(INIT_CMD, table, initStr); - sqlite3_free(initStr); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(type, sqlerr); - goto loser; - } - - newStr = sqlite3_mprintf(CREATE_ISSUER_INDEX_CMD, table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(type, sqlerr); - goto loser; - } - - newStr = sqlite3_mprintf(CREATE_SUBJECT_INDEX_CMD, table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(type, sqlerr); - goto loser; - } - - newStr = sqlite3_mprintf(CREATE_LABEL_INDEX_CMD, table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(type, sqlerr); - goto loser; - } - - newStr = sqlite3_mprintf(CREATE_ID_INDEX_CMD, table); - if (newStr == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - sqlerr = sqlite3_exec(sqlDB, newStr, NULL, 0, NULL); - sqlite3_free(newStr); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(type, sqlerr); - goto loser; - } - } - /* - * detect the case where we have created the database, but have - * not yet updated it. - * - * We only check the Key database because only the key database has - * a metaData table. The metaData table is created when a password - * is set, or in the case of update, when a password is supplied. - * If no key database exists, then the update would have happened immediately - * on noticing that the cert database didn't exist (see newInit set above). - */ - if (type == SDB_KEY && !tableExists(sqlDB, "metaData")) { - *newInit = 1; - } - - /* access to network filesystems are significantly slower than local ones - * for database operations. In those cases we need to create a cached copy - * of the database in a temporary location on the local disk. SQLITE - * already provides a way to create a temporary table and initialize it, - * so we use it for the cache (see sdb_buildCache for how it's done).*/ - - /* - * we decide whether or not to use the cache based on the following input. - * - * NSS_SDB_USE_CACHE environment variable is non-existant or set to - * anything other than "no" or "yes" ("auto", for instance). - * This is the normal case. NSS will measure the performance of access - * to the temp database versus the access to the users passed in - * database location. If the temp database location is "significantly" - * faster we will use the cache. - * - * NSS_SDB_USE_CACHE environment variable is set to "no": cache will not - * be used. - * - * NSS_SDB_USE_CACHE environment variable is set to "yes": cache will - * always be used. - * - * It is expected that most applications would use the "auto" selection, - * the environment variable is primarily to simplify testing, and to - * correct potential corner cases where */ - - env = PR_GetEnv("NSS_SDB_USE_CACHE"); - - if (env && PORT_Strcasecmp(env,"no") == 0) { - enableCache = PR_FALSE; - } else if (env && PORT_Strcasecmp(env,"yes") == 0) { - enableCache = PR_TRUE; - } else { - char *tempDir = NULL; - PRUint32 tempOps = 0; - /* - * Use PR_Access to determine how expensive it - * is to check for the existance of a local file compared to the same - * check in the temp directory. If the temp directory is faster, cache - * the database there. */ - tempDir = sdb_getTempDir(sqlDB); - if (tempDir) { - tempOps = sdb_measureAccess(tempDir); - PORT_Free(tempDir); - - /* There is a cost to continually copying the database. - * Account for that cost with the arbitrary factor of 10 */ - enableCache = (PRBool)(tempOps > accessOps * 10); - } - } - - if (enableCache) { - /* try to set the temp store to memory.*/ - sqlite3_exec(sqlDB, "PRAGMA temp_store=MEMORY", NULL, 0, NULL); - /* Failure to set the temp store to memory is not fatal, - * ignore the error */ - - cacheTable = sqlite3_mprintf("%sCache",table); - if (cacheTable == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - /* build the cache table */ - error = sdb_buildCache(sqlDB, type, cacheTable, table); - if (error != CKR_OK) { - goto loser; - } - /* initialize the last cache build time */ - now = PR_IntervalNow(); - } - - sdb = (SDB *) malloc(sizeof(SDB)); - sdb_p = (SDBPrivate *) malloc(sizeof(SDBPrivate)); - - /* invariant fields */ - sdb_p->sqlDBName = PORT_Strdup(dbname); - sdb_p->type = type; - sdb_p->table = table; - sdb_p->cacheTable = cacheTable; - sdb_p->lastUpdateTime = now; - /* set the cache delay time. This is how long we will wait before we - * decide the existing cache is stale. Currently set to 10 sec */ - sdb_p->updateInterval = PR_SecondsToInterval(10); - sdb_p->dbMon = PR_NewMonitor(); - /* these fields are protected by the lock */ - sdb_p->sqlXactDB = NULL; - sdb_p->sqlXactThread = NULL; - sdb->private = sdb_p; - sdb->sdb_type = SDB_SQL; - sdb->sdb_flags = flags | SDB_HAS_META; - sdb->sdb_FindObjectsInit = sdb_FindObjectsInit; - sdb->sdb_FindObjects = sdb_FindObjects; - sdb->sdb_FindObjectsFinal = sdb_FindObjectsFinal; - sdb->sdb_GetAttributeValue = sdb_GetAttributeValue; - sdb->sdb_SetAttributeValue = sdb_SetAttributeValue; - sdb->sdb_CreateObject = sdb_CreateObject; - sdb->sdb_DestroyObject = sdb_DestroyObject; - sdb->sdb_GetMetaData = sdb_GetMetaData; - sdb->sdb_PutMetaData = sdb_PutMetaData; - sdb->sdb_Begin = sdb_Begin; - sdb->sdb_Commit = sdb_Commit; - sdb->sdb_Abort = sdb_Abort; - sdb->sdb_Close = sdb_Close; - sdb->sdb_SetForkState = sdb_SetForkState; - - if (inTransaction) { - sqlerr = sqlite3_exec(sqlDB, COMMIT_CMD, NULL, 0, NULL); - if (sqlerr != SQLITE_OK) { - error = sdb_mapSQLError(sdb_p->type, sqlerr); - goto loser; - } - inTransaction = 0; - } - - sdb_p->sqlReadDB = sqlDB; - - *pSdb = sdb; - UNLOCK_SQLITE(); - return CKR_OK; - -loser: - /* lots of stuff to do */ - if (inTransaction) { - sqlite3_exec(sqlDB, ROLLBACK_CMD, NULL, 0, NULL); - } - if (sdb) { - free(sdb); - } - if (sdb_p) { - free(sdb_p); - } - if (sqlDB) { - sqlite3_close(sqlDB); - } - UNLOCK_SQLITE(); - return error; - -} - - -/* sdbopen */ -CK_RV -s_open(const char *directory, const char *certPrefix, const char *keyPrefix, - int cert_version, int key_version, int flags, - SDB **certdb, SDB **keydb, int *newInit) -{ - char *cert = sdb_BuildFileName(directory, certPrefix, - "cert", cert_version, flags); - char *key = sdb_BuildFileName(directory, keyPrefix, - "key", key_version, flags); - CK_RV error = CKR_OK; - int inUpdate; - PRUint32 accessOps; - - *certdb = NULL; - *keydb = NULL; - *newInit = 0; - -#ifdef SQLITE_UNSAFE_THREADS - if (sqlite_lock == NULL) { - sqlite_lock = PR_NewLock(); - if (sqlite_lock == NULL) { - error = CKR_HOST_MEMORY; - goto loser; - } - } -#endif - - /* how long does it take to test for a non-existant file in our working - * directory? Allows us to test if we may be on a network file system */ - accessOps = sdb_measureAccess(directory); - - /* - * open the cert data base - */ - if (certdb) { - /* initialize Certificate database */ - error = sdb_init(cert, "nssPublic", SDB_CERT, &inUpdate, - newInit, flags, accessOps, certdb); - if (error != CKR_OK) { - goto loser; - } - } - - /* - * open the key data base: - * NOTE:if we want to implement a single database, we open - * the same database file as the certificate here. - * - * cert an key db's have different tables, so they will not - * conflict. - */ - if (keydb) { - /* initialize the Key database */ - error = sdb_init(key, "nssPrivate", SDB_KEY, &inUpdate, - newInit, flags, accessOps, keydb); - if (error != CKR_OK) { - goto loser; - } - } - - -loser: - if (cert) { - sqlite3_free(cert); - } - if (key) { - sqlite3_free(key); - } - - if (error != CKR_OK) { - /* currently redundant, but could be necessary if more code is added - * just before loser */ - if (keydb && *keydb) { - sdb_Close(*keydb); - } - if (certdb && *certdb) { - sdb_Close(*certdb); - } - } - - return error; -} - -CK_RV -s_shutdown() -{ -#ifdef SQLITE_UNSAFE_THREADS - if (sqlite_lock) { - PR_DestroyLock(sqlite_lock); - sqlite_lock = NULL; - } -#endif - return CKR_OK; -} diff --git a/security/nss/lib/softoken/sdb.h b/security/nss/lib/softoken/sdb.h deleted file mode 100644 index e4ded7271..000000000 --- a/security/nss/lib/softoken/sdb.h +++ /dev/null @@ -1,112 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 Red Hat, Inc. - * - * The Initial Developer of the Original Code is - * Red Hat, Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Robert Relyea (rrelyea@redhat.com) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * This file implements PKCS 11 on top of our existing security modules - * - * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. - * This implementation has two slots: - * slot 1 is our generic crypto support. It does not require login. - * It supports Public Key ops, and all they bulk ciphers and hashes. - * It can also support Private Key ops for imported Private keys. It does - * not have any token storage. - * slot 2 is our private key support. It requires a login before use. It - * can store Private Keys and Certs as token objects. Currently only private - * keys and their associated Certificates are saved on the token. - * - * In this implementation, session objects are only visible to the session - * that created or generated them. - */ - -/* - * the following data structures should be moved to a 'rdb.h'. - */ - -#ifndef _SDB_H -#define _SDB_H 1 -#include "pkcs11t.h" -#include "secitem.h" -#include "sftkdbt.h" -#include <sqlite3.h> - -#define STATIC_CMD_SIZE 2048 - -typedef struct SDBFindStr SDBFind; -typedef struct SDBStr SDB; - -struct SDBStr { - void *private; - int version; - SDBType sdb_type; - int sdb_flags; - void *app_private; - CK_RV (*sdb_FindObjectsInit)(SDB *sdb, const CK_ATTRIBUTE *template, - CK_ULONG count, SDBFind **find); - CK_RV (*sdb_FindObjects)(SDB *sdb, SDBFind *find, CK_OBJECT_HANDLE *ids, - CK_ULONG arraySize, CK_ULONG *count); - CK_RV (*sdb_FindObjectsFinal)(SDB *sdb, SDBFind *find); - CK_RV (*sdb_GetAttributeValue)(SDB *sdb, CK_OBJECT_HANDLE object, - CK_ATTRIBUTE *template, CK_ULONG count); - CK_RV (*sdb_SetAttributeValue)(SDB *sdb, CK_OBJECT_HANDLE object, - const CK_ATTRIBUTE *template, CK_ULONG count); - CK_RV (*sdb_CreateObject)(SDB *sdb, CK_OBJECT_HANDLE *object, - const CK_ATTRIBUTE *template, CK_ULONG count); - CK_RV (*sdb_DestroyObject)(SDB *sdb, CK_OBJECT_HANDLE object); - CK_RV (*sdb_GetMetaData)(SDB *sdb, const char *id, - SECItem *item1, SECItem *item2); - CK_RV (*sdb_PutMetaData)(SDB *sdb, const char *id, - const SECItem *item1, const SECItem *item2); - CK_RV (*sdb_Begin)(SDB *sdb); - CK_RV (*sdb_Commit)(SDB *sdb); - CK_RV (*sdb_Abort)(SDB *sdb); - CK_RV (*sdb_Reset)(SDB *sdb); - CK_RV (*sdb_Close)(SDB *sdb); - void (*sdb_SetForkState)(PRBool forked); -}; - -CK_RV s_open(const char *directory, const char *certPrefix, - const char *keyPrefix, - int cert_version, int key_version, - int flags, SDB **certdb, SDB **keydb, int *newInit); -CK_RV s_shutdown(); - -/* flags */ -#define SDB_RDONLY 1 -#define SDB_RDWR 2 -#define SDB_CREATE 4 -#define SDB_HAS_META 8 - -#endif diff --git a/security/nss/lib/softoken/secmodt.h b/security/nss/lib/softoken/secmodt.h deleted file mode 100644 index 59fdca048..000000000 --- a/security/nss/lib/softoken/secmodt.h +++ /dev/null @@ -1,503 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#ifndef _SECMODT_H_ -#define _SECMODT_H_ 1 - -#include "nssrwlkt.h" -#include "nssilckt.h" -#include "secoid.h" -#include "secasn1.h" -#include "pkcs11t.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 SEC_ASN1TemplateChooser NSS_Get_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 NSSRWLock SECMODListLock; -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; -typedef struct PK11GenericObjectStr PK11GenericObject; -typedef void (*PK11FreeDataFunc)(void *); - -struct SECMODModuleStr { - PLArenaPool *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 */ - PZLock *refLock; /* only used pk11db.c */ - int refCount; /* Module reference count */ - PK11SlotInfo **slots; /* array of slot points attached 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 */ - unsigned long evControlMask; /* control the running and shutdown of slot - * events (SECMOD_WaitForAnyTokenEvent) */ - CK_VERSION cryptokiVersion; /* version of this library */ -}; - -/* evControlMask flags */ -/* - * These bits tell the current state of a SECMOD_WaitForAnyTokenEvent. - * - * SECMOD_WAIT_PKCS11_EVENT - we're waiting in the PKCS #11 module in - * C_WaitForSlotEvent(). - * SECMOD_WAIT_SIMULATED_EVENT - we're waiting in the NSS simulation code - * which polls for token insertion and removal events. - * SECMOD_END_WAIT - SECMOD_CancelWait has been called while the module is - * waiting in SECMOD_WaitForAnyTokenEvent. SECMOD_WaitForAnyTokenEvent - * should return immediately to it's caller. - */ -#define SECMOD_END_WAIT 0x01 -#define SECMOD_WAIT_SIMULATED_EVENT 0x02 -#define SECMOD_WAIT_PKCS11_EVENT 0x04 - -struct SECMODModuleListStr { - SECMODModuleList *next; - SECMODModule *module; -}; - -struct PK11SlotListStr { - PK11SlotListElement *head; - PK11SlotListElement *tail; - PZLock *lock; -}; - -struct PK11SlotListElementStr { - PK11SlotListElement *next; - PK11SlotListElement *prev; - PK11SlotInfo *slot; - int refCount; -}; - -struct PK11RSAGenParamsStr { - int keySizeInBits; - unsigned long pe; -}; - -typedef enum { - PK11CertListUnique = 0, /* get one instance of all certs */ - PK11CertListUser = 1, /* get all instances of user certs */ - PK11CertListRootUnique = 2, /* get one instance of CA certs without a private key. - * deprecated. Use PK11CertListCAUnique - */ - PK11CertListCA = 3, /* get all instances of CA certs */ - PK11CertListCAUnique = 4, /* get one instance of CA certs */ - PK11CertListUserUnique = 5, /* get one instance of user certs */ - PK11CertListAll = 6 /* get all instances of all certs */ -} 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 -#define SECMOD_SHA256_FLAG 0x00004000L -#define SECMOD_SHA512_FLAG 0x00008000L /* also for SHA384 */ -#define SECMOD_CAMELLIA_FLAG 0x00010000L /* = PUBLIC_MECH_CAMELLIA_FLAG */ -#define SECMOD_SEED_FLAG 0x00020000L -/* 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 - -/* - * PK11AttrFlags - * - * A 32-bit bitmask of PK11_ATTR_XXX flags - */ -typedef PRUint32 PK11AttrFlags; - -/* - * PK11_ATTR_XXX - * - * The following PK11_ATTR_XXX bitflags are used to specify - * PKCS #11 object attributes that have Boolean values. Some NSS - * functions have a "PK11AttrFlags attrFlags" parameter whose value - * is the logical OR of these bitflags. NSS use these bitflags on - * private keys or secret keys. Some of these bitflags also apply - * to the public keys associated with the private keys. - * - * For each PKCS #11 object attribute, we need two bitflags to - * specify not only "true" and "false" but also "default". For - * example, PK11_ATTR_PRIVATE and PK11_ATTR_PUBLIC control the - * CKA_PRIVATE attribute. If PK11_ATTR_PRIVATE is set, we add - * { CKA_PRIVATE, &cktrue, sizeof(CK_BBOOL) } - * to the template. If PK11_ATTR_PUBLIC is set, we add - * { CKA_PRIVATE, &ckfalse, sizeof(CK_BBOOL) } - * to the template. If neither flag is set, we don't add any - * CKA_PRIVATE entry to the template. - */ - -/* - * Attributes for PKCS #11 storage objects, which include not only - * keys but also certificates and domain parameters. - */ - -/* - * PK11_ATTR_TOKEN - * PK11_ATTR_SESSION - * - * These two flags determine whether the object is a token or - * session object. - * - * These two flags are related and cannot both be set. - * If the PK11_ATTR_TOKEN flag is set, the object is a token - * object. If the PK11_ATTR_SESSION flag is set, the object is - * a session object. If neither flag is set, the object is *by - * default* a session object. - * - * These two flags specify the value of the PKCS #11 CKA_TOKEN - * attribute. - */ -#define PK11_ATTR_TOKEN 0x00000001L -#define PK11_ATTR_SESSION 0x00000002L - -/* - * PK11_ATTR_PRIVATE - * PK11_ATTR_PUBLIC - * - * These two flags determine whether the object is a private or - * public object. A user may not access a private object until the - * user has authenticated to the token. - * - * These two flags are related and cannot both be set. - * If the PK11_ATTR_PRIVATE flag is set, the object is a private - * object. If the PK11_ATTR_PUBLIC flag is set, the object is a - * public object. If neither flag is set, it is token-specific - * whether the object is private or public. - * - * These two flags specify the value of the PKCS #11 CKA_PRIVATE - * attribute. NSS only uses this attribute on private and secret - * keys, so public keys created by NSS get the token-specific - * default value of the CKA_PRIVATE attribute. - */ -#define PK11_ATTR_PRIVATE 0x00000004L -#define PK11_ATTR_PUBLIC 0x00000008L - -/* - * PK11_ATTR_MODIFIABLE - * PK11_ATTR_UNMODIFIABLE - * - * These two flags determine whether the object is modifiable or - * read-only. - * - * These two flags are related and cannot both be set. - * If the PK11_ATTR_MODIFIABLE flag is set, the object can be - * modified. If the PK11_ATTR_UNMODIFIABLE flag is set, the object - * is read-only. If neither flag is set, the object is *by default* - * modifiable. - * - * These two flags specify the value of the PKCS #11 CKA_MODIFIABLE - * attribute. - */ -#define PK11_ATTR_MODIFIABLE 0x00000010L -#define PK11_ATTR_UNMODIFIABLE 0x00000020L - -/* Attributes for PKCS #11 key objects. */ - -/* - * PK11_ATTR_SENSITIVE - * PK11_ATTR_INSENSITIVE - * - * These two flags are related and cannot both be set. - * If the PK11_ATTR_SENSITIVE flag is set, the key is sensitive. - * If the PK11_ATTR_INSENSITIVE flag is set, the key is not - * sensitive. If neither flag is set, it is token-specific whether - * the key is sensitive or not. - * - * If a key is sensitive, certain attributes of the key cannot be - * revealed in plaintext outside the token. - * - * This flag specifies the value of the PKCS #11 CKA_SENSITIVE - * attribute. Although the default value of the CKA_SENSITIVE - * attribute for secret keys is CK_FALSE per PKCS #11, some FIPS - * tokens set the default value to CK_TRUE because only CK_TRUE - * is allowed. So in practice the default value of this attribute - * is token-specific, hence the need for two bitflags. - */ -#define PK11_ATTR_SENSITIVE 0x00000040L -#define PK11_ATTR_INSENSITIVE 0x00000080L - -/* - * PK11_ATTR_EXTRACTABLE - * PK11_ATTR_UNEXTRACTABLE - * - * These two flags are related and cannot both be set. - * If the PK11_ATTR_EXTRACTABLE flag is set, the key is extractable - * and can be wrapped. If the PK11_ATTR_UNEXTRACTABLE flag is set, - * the key is not extractable, and certain attributes of the key - * cannot be revealed in plaintext outside the token (just like a - * sensitive key). If neither flag is set, it is token-specific - * whether the key is extractable or not. - * - * These two flags specify the value of the PKCS #11 CKA_EXTRACTABLE - * attribute. - */ -#define PK11_ATTR_EXTRACTABLE 0x00000100L -#define PK11_ATTR_UNEXTRACTABLE 0x00000200L - -/* 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,Camellia,SEED,SHA256,SHA512]" - -#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; - -/* types of PKCS #11 objects - * used to identify which NSS data structure is - * passed to the PK11_Raw* functions. Types map as follows: - * PK11_TypeGeneric PK11GenericObject * - * PK11_TypePrivKey SECKEYPrivateKey * - * PK11_TypePubKey SECKEYPublicKey * - * PK11_TypeSymKey PK11SymKey * - * PK11_TypeCert CERTCertificate * (currently not used). - */ -typedef enum { - PK11_TypeGeneric = 0, - PK11_TypePrivKey = 1, - PK11_TypePubKey = 2, - PK11_TypeCert = 3, - PK11_TypeSymKey = 4 -} PK11ObjectType; - - - -/* 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); - -/* - * Special strings the password callback function can return only if - * the slot is an protected auth path slot. - */ -#define PK11_PW_RETRY "RETRY" /* an failed attempt to authenticate - * has already been made, just retry - * the operation */ -#define PK11_PW_AUTHENTICATED "AUTH" /* a successful attempt to authenticate - * has completed. Continue without - * another call to C_Login */ -/* All other non-null values mean that that NSS could call C_Login to force - * the authentication. The following define is to aid applications in - * documenting that is what it's trying to do */ -#define PK11_PW_TRY "TRY" /* Default: a prompt has been presented - * to the user, initiate a C_Login - * to authenticate the token */ - -/* - * 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; - -/* - * token removal detection - */ -typedef enum { - PK11TokenNotRemovable = 0, - PK11TokenPresent = 1, - PK11TokenChanged = 2, - PK11TokenRemoved = 3 -} PK11TokenStatus; - -typedef enum { - PK11TokenRemovedOrChangedEvent = 0, - PK11TokenPresentEvent = 1 -} PK11TokenEvent; - -/* - * CRL Import Flags - */ -#define CRL_IMPORT_DEFAULT_OPTIONS 0x00000000 -#define CRL_IMPORT_BYPASS_CHECKS 0x00000001 - - -/* - * Merge Error Log - */ -typedef struct PK11MergeLogStr PK11MergeLog; -typedef struct PK11MergeLogNodeStr PK11MergeLogNode; - -/* These need to be global, leave some open fields so we can 'expand' - * these without breaking binary compatibility */ -struct PK11MergeLogNodeStr { - PK11MergeLogNode *next; /* next entry in the list */ - PK11MergeLogNode *prev; /* last entry in the list */ - PK11GenericObject *object; /* object that failed */ - int error; /* what the error was */ - CK_RV reserved1; - unsigned long reserved2; /* future flags */ - unsigned long reserved3; /* future scalar */ - void *reserved4; /* future pointer */ - void *reserved5; /* future expansion pointer */ -}; - -struct PK11MergeLogStr { - PK11MergeLogNode *head; - PK11MergeLogNode *tail; - PLArenaPool *arena; - int version; - unsigned long reserved1; - unsigned long reserved2; - unsigned long reserved3; - void *reserverd4; - void *reserverd5; -}; - - -#endif /*_SECMODT_H_ */ diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c deleted file mode 100644 index 45100cc5c..000000000 --- a/security/nss/lib/softoken/sftkdb.c +++ /dev/null @@ -1,2713 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following code handles the storage of PKCS 11 modules used by the - * NSS. For the rest of NSS, only one kind of database handle exists: - * - * SFTKDBHandle - * - * There is one SFTKDBHandle for the each key database and one for each cert - * database. These databases are opened as associated pairs, one pair per - * slot. SFTKDBHandles are reference counted objects. - * - * Each SFTKDBHandle points to a low level database handle (SDB). This handle - * represents the underlying physical database. These objects are not - * reference counted, an are 'owned' by their respective SFTKDBHandles. - * - * - */ -#include "sftkdb.h" -#include "sftkdbti.h" -#include "pkcs11t.h" -#include "pkcs11i.h" -#include "sdb.h" -#include "prprf.h" -#include "secmodt.h" -#include "pratom.h" -#include "lgglue.h" -#include "sftkpars.h" -#include "secerr.h" -#include "softoken.h" - -/* - * We want all databases to have the same binary representation independent of - * endianness or length of the host architecture. In general PKCS #11 attributes - * are endian/length independent except those attributes that pass CK_ULONG. - * - * The following functions fixes up the CK_ULONG type attributes so that the data - * base sees a machine independent view. CK_ULONGs are stored as 4 byte network - * byte order values (big endian). - */ -#define BBP 8 - -static PRBool -sftkdb_isULONGAttribute(CK_ATTRIBUTE_TYPE type) -{ - switch(type) { - case CKA_CERTIFICATE_CATEGORY: - case CKA_CERTIFICATE_TYPE: - case CKA_CLASS: - case CKA_JAVA_MIDP_SECURITY_DOMAIN: - case CKA_KEY_GEN_MECHANISM: - case CKA_KEY_TYPE: - case CKA_MECHANISM_TYPE: - case CKA_MODULUS_BITS: - case CKA_PRIME_BITS: - case CKA_SUBPRIME_BITS: - case CKA_VALUE_BITS: - case CKA_VALUE_LEN: - - case CKA_TRUST_DIGITAL_SIGNATURE: - case CKA_TRUST_NON_REPUDIATION: - case CKA_TRUST_KEY_ENCIPHERMENT: - case CKA_TRUST_DATA_ENCIPHERMENT: - case CKA_TRUST_KEY_AGREEMENT: - case CKA_TRUST_KEY_CERT_SIGN: - case CKA_TRUST_CRL_SIGN: - - case CKA_TRUST_SERVER_AUTH: - case CKA_TRUST_CLIENT_AUTH: - case CKA_TRUST_CODE_SIGNING: - case CKA_TRUST_EMAIL_PROTECTION: - case CKA_TRUST_IPSEC_END_SYSTEM: - case CKA_TRUST_IPSEC_TUNNEL: - case CKA_TRUST_IPSEC_USER: - case CKA_TRUST_TIME_STAMPING: - case CKA_TRUST_STEP_UP_APPROVED: - return PR_TRUE; - default: - break; - } - return PR_FALSE; - -} - -/* are the attributes private? */ -static PRBool -sftkdb_isPrivateAttribute(CK_ATTRIBUTE_TYPE type) -{ - switch(type) { - case CKA_VALUE: - case CKA_PRIVATE_EXPONENT: - case CKA_PRIME_1: - case CKA_PRIME_2: - case CKA_EXPONENT_1: - case CKA_EXPONENT_2: - case CKA_COEFFICIENT: - return PR_TRUE; - default: - break; - } - return PR_FALSE; -} - -/* These attributes must be authenticated with an hmac. */ -static PRBool -sftkdb_isAuthenticatedAttribute(CK_ATTRIBUTE_TYPE type) -{ - switch(type) { - case CKA_MODULUS: - case CKA_PUBLIC_EXPONENT: - case CKA_CERT_SHA1_HASH: - case CKA_CERT_MD5_HASH: - case CKA_TRUST_SERVER_AUTH: - case CKA_TRUST_CLIENT_AUTH: - case CKA_TRUST_EMAIL_PROTECTION: - case CKA_TRUST_CODE_SIGNING: - case CKA_TRUST_STEP_UP_APPROVED: - case CKA_NSS_OVERRIDE_EXTENSIONS: - return PR_TRUE; - default: - break; - } - return PR_FALSE; -} - -/* - * convert a native ULONG to a database ulong. Database ulong's - * are all 4 byte big endian values. - */ -void -sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value) -{ - int i; - - for (i=0; i < SDB_ULONG_SIZE; i++) { - data[i] = (value >> (SDB_ULONG_SIZE-1-i)*BBP) & 0xff; - } -} - -/* - * convert a database ulong back to a native ULONG. (reverse of the above - * function. - */ -static CK_ULONG -sftk_SDBULong2ULong(unsigned char *data) -{ - int i; - CK_ULONG value = 0; - - for (i=0; i < SDB_ULONG_SIZE; i++) { - value |= (((CK_ULONG)data[i]) << (SDB_ULONG_SIZE-1-i)*BBP); - } - return value; -} - -/* - * fix up the input templates. Our fixed up ints are stored in data and must - * be freed by the caller. The new template must also be freed. If there are no - * CK_ULONG attributes, the orignal template is passed in as is. - */ -static CK_ATTRIBUTE * -sftkdb_fixupTemplateIn(const CK_ATTRIBUTE *template, int count, - unsigned char **dataOut) -{ - int i; - int ulongCount = 0; - unsigned char *data; - CK_ATTRIBUTE *ntemplate; - - *dataOut = NULL; - - /* first count the number of CK_ULONG attributes */ - for (i=0; i < count; i++) { - /* Don't 'fixup' NULL values */ - if (!template[i].pValue) { - continue; - } - if (template[i].ulValueLen == sizeof (CK_ULONG)) { - if ( sftkdb_isULONGAttribute(template[i].type)) { - ulongCount++; - } - } - } - /* no attributes to fixup, just call on through */ - if (ulongCount == 0) { - return (CK_ATTRIBUTE *)template; - } - - /* allocate space for new ULONGS */ - data = (unsigned char *)PORT_Alloc(SDB_ULONG_SIZE*ulongCount); - if (!data) { - return NULL; - } - - /* allocate new template */ - ntemplate = PORT_NewArray(CK_ATTRIBUTE,count); - if (!ntemplate) { - PORT_Free(data); - return NULL; - } - *dataOut = data; - /* copy the old template, fixup the actual ulongs */ - for (i=0; i < count; i++) { - ntemplate[i] = template[i]; - /* Don't 'fixup' NULL values */ - if (!template[i].pValue) { - continue; - } - if (template[i].ulValueLen == sizeof (CK_ULONG)) { - if ( sftkdb_isULONGAttribute(template[i].type) ) { - CK_ULONG value = *(CK_ULONG *) template[i].pValue; - sftk_ULong2SDBULong(data, value); - ntemplate[i].pValue = data; - ntemplate[i].ulValueLen = SDB_ULONG_SIZE; - data += SDB_ULONG_SIZE; - } - } - } - return ntemplate; -} - - -static const char SFTKDB_META_SIG_TEMPLATE[] = "sig_%s_%08x_%08x"; - -/* - * return a string describing the database type (key or cert) - */ -const char * -sftkdb_TypeString(SFTKDBHandle *handle) -{ - return (handle->type == SFTK_KEYDB_TYPE) ? "key" : "cert"; -} - -/* - * Some attributes are signed with an Hmac and a pbe key generated from - * the password. This signature is stored indexed by object handle and - * attribute type in the meta data table in the key database. - * - * Signature entries are indexed by the string - * sig_[cert/key]_{ObjectID}_{Attribute} - * - * This function fetches that pkcs5 signature. Caller supplies a SECItem - * pre-allocated to the appropriate size if the SECItem is too small the - * function will fail with CKR_BUFFER_TOO_SMALL. - */ -static CK_RV -sftkdb_getAttributeSignature(SFTKDBHandle *handle, SFTKDBHandle *keyHandle, - CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type, - SECItem *signText) -{ - SDB *db; - char id[30]; - CK_RV crv; - - db = SFTK_GET_SDB(keyHandle); - - sprintf(id, SFTKDB_META_SIG_TEMPLATE, - sftkdb_TypeString(handle), - (unsigned int)objectID, (unsigned int)type); - - crv = (*db->sdb_GetMetaData)(db, id, signText, NULL); - return crv; -} - -/* - * Some attributes are signed with an Hmac and a pbe key generated from - * the password. This signature is stored indexed by object handle and - * attribute type in the meta data table in the key database. - * - * Signature entries are indexed by the string - * sig_[cert/key]_{ObjectID}_{Attribute} - * - * This function stores that pkcs5 signature. - */ -CK_RV -sftkdb_PutAttributeSignature(SFTKDBHandle *handle, SDB *keyTarget, - CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE type, - SECItem *signText) -{ - char id[30]; - CK_RV crv; - - sprintf(id, SFTKDB_META_SIG_TEMPLATE, - sftkdb_TypeString(handle), - (unsigned int)objectID, (unsigned int)type); - - crv = (*keyTarget->sdb_PutMetaData)(keyTarget, id, signText, NULL); - return crv; -} - -/* - * fix up returned data. NOTE: sftkdb_fixupTemplateIn has already allocated - * separate data sections for the database ULONG values. - */ -static CK_RV -sftkdb_fixupTemplateOut(CK_ATTRIBUTE *template, CK_OBJECT_HANDLE objectID, - CK_ATTRIBUTE *ntemplate, int count, SFTKDBHandle *handle) -{ - int i; - CK_RV crv = CKR_OK; - SFTKDBHandle *keyHandle; - PRBool checkSig = PR_TRUE; - PRBool checkEnc = PR_TRUE; - - PORT_Assert(handle); - - /* find the key handle */ - keyHandle = handle; - if (handle->type != SFTK_KEYDB_TYPE) { - checkEnc = PR_FALSE; - keyHandle = handle->peerDB; - } - - if ((keyHandle == NULL) || - ((SFTK_GET_SDB(keyHandle)->sdb_flags & SDB_HAS_META) == 0) || - (keyHandle->passwordKey.data == NULL)) { - checkSig = PR_FALSE; - } - - for (i=0; i < count; i++) { - CK_ULONG length = template[i].ulValueLen; - template[i].ulValueLen = ntemplate[i].ulValueLen; - /* fixup ulongs */ - if (ntemplate[i].ulValueLen == SDB_ULONG_SIZE) { - if (sftkdb_isULONGAttribute(template[i].type)) { - if (template[i].pValue) { - CK_ULONG value; - unsigned char *data; - - data = (unsigned char *)ntemplate[i].pValue; - value = sftk_SDBULong2ULong(ntemplate[i].pValue); - if (length < sizeof(CK_ULONG)) { - template[i].ulValueLen = -1; - crv = CKR_BUFFER_TOO_SMALL; - continue; - } - PORT_Memcpy(template[i].pValue,&value,sizeof(CK_ULONG)); - } - template[i].ulValueLen = sizeof(CK_ULONG); - } - } - - /* if no data was retrieved, no need to process encrypted or signed - * attributes */ - if ((template[i].pValue == NULL) || (template[i].ulValueLen == -1)) { - continue; - } - - /* fixup private attributes */ - if (checkEnc && sftkdb_isPrivateAttribute(ntemplate[i].type)) { - /* we have a private attribute */ - /* This code depends on the fact that the cipherText is bigger - * than the plain text */ - SECItem cipherText; - SECItem *plainText; - SECStatus rv; - - cipherText.data = ntemplate[i].pValue; - cipherText.len = ntemplate[i].ulValueLen; - PZ_Lock(handle->passwordLock); - if (handle->passwordKey.data == NULL) { - PZ_Unlock(handle->passwordLock); - template[i].ulValueLen = -1; - crv = CKR_USER_NOT_LOGGED_IN; - continue; - } - rv = sftkdb_DecryptAttribute(&handle->passwordKey, - &cipherText, &plainText); - PZ_Unlock(handle->passwordLock); - if (rv != SECSuccess) { - PORT_Memset(template[i].pValue, 0, template[i].ulValueLen); - template[i].ulValueLen = -1; - crv = CKR_GENERAL_ERROR; - continue; - } - PORT_Assert(template[i].ulValueLen >= plainText->len); - if (template[i].ulValueLen < plainText->len) { - SECITEM_FreeItem(plainText,PR_TRUE); - PORT_Memset(template[i].pValue, 0, template[i].ulValueLen); - template[i].ulValueLen = -1; - crv = CKR_GENERAL_ERROR; - continue; - } - - /* copy the plain text back into the template */ - PORT_Memcpy(template[i].pValue, plainText->data, plainText->len); - template[i].ulValueLen = plainText->len; - SECITEM_FreeItem(plainText,PR_TRUE); - } - /* make sure signed attributes are valid */ - if (checkSig && sftkdb_isAuthenticatedAttribute(ntemplate[i].type)) { - SECStatus rv; - SECItem signText; - SECItem plainText; - unsigned char signData[SDB_MAX_META_DATA_LEN]; - - signText.data = signData; - signText.len = sizeof(signData); - - rv = sftkdb_getAttributeSignature(handle, keyHandle, - objectID, ntemplate[i].type, &signText); - if (rv != SECSuccess) { - PORT_Memset(template[i].pValue, 0, template[i].ulValueLen); - template[i].ulValueLen = -1; - crv = CKR_DATA_INVALID; /* better error code? */ - continue; - } - - plainText.data = ntemplate[i].pValue; - plainText.len = ntemplate[i].ulValueLen; - - /* - * we do a second check holding the lock just in case the user - * loggout while we were trying to get the signature. - */ - PZ_Lock(keyHandle->passwordLock); - if (keyHandle->passwordKey.data == NULL) { - /* if we are no longer logged in, no use checking the other - * Signatures either. */ - checkSig = PR_FALSE; - PZ_Unlock(keyHandle->passwordLock); - continue; - } - - rv = sftkdb_VerifyAttribute(&keyHandle->passwordKey, - objectID, ntemplate[i].type, - &plainText, &signText); - PZ_Unlock(keyHandle->passwordLock); - if (rv != SECSuccess) { - PORT_Memset(template[i].pValue, 0, template[i].ulValueLen); - template[i].ulValueLen = -1; - crv = CKR_SIGNATURE_INVALID; /* better error code? */ - } - /* This Attribute is fine */ - } - } - return crv; -} - -/* - * Some attributes are signed with an HMAC and a pbe key generated from - * the password. This signature is stored indexed by object handle and - * - * Those attributes are: - * 1) Trust object hashes and trust values. - * 2) public key values. - * - * Certs themselves are considered properly authenticated by virtue of their - * signature, or their matching hash with the trust object. - * - * These signature is only checked for objects coming from shared databases. - * Older dbm style databases have such no signature checks. HMACs are also - * only checked when the token is logged in, as it requires a pbe generated - * from the password. - * - * Tokens which have no key database (and therefore no master password) do not - * have any stored signature values. Signature values are stored in the key - * database, since the signature data is tightly coupled to the key database - * password. - * - * This function takes a template of attributes that were either created or - * modified. These attributes are checked to see if the need to be signed. - * If they do, then this function signs the attributes and writes them - * to the meta data store. - * - * This function can fail if there are attributes that must be signed, but - * the token is not logged in. - * - * The caller is expected to abort any transaction he was in in the - * event of a failure of this function. - */ -static CK_RV -sftk_signTemplate(PLArenaPool *arena, SFTKDBHandle *handle, - PRBool mayBeUpdateDB, - CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template, - CK_ULONG count) -{ - int i; - SFTKDBHandle *keyHandle = handle; - SDB *keyTarget = NULL; - - PORT_Assert(handle); - - if (handle->type != SFTK_KEYDB_TYPE) { - keyHandle = handle->peerDB; - } - - /* no key DB defined? then no need to sign anything */ - if (keyHandle == NULL) { - return CKR_OK; - } - - /* When we are in a middle of an update, we have an update database set, - * but we want to write to the real database. The bool mayBeUpdateDB is - * set to TRUE if it's possible that we want to write an update database - * rather than a primary */ - keyTarget = (mayBeUpdateDB && keyHandle->update) ? - keyHandle->update : keyHandle->db; - - /* skip the the database does not support meta data */ - if ((keyTarget->sdb_flags & SDB_HAS_META) == 0) { - return CKR_OK; - } - - for (i=0; i < count; i ++) { - if (sftkdb_isAuthenticatedAttribute(template[i].type)) { - SECStatus rv; - SECItem *signText; - SECItem plainText; - - plainText.data = template[i].pValue; - plainText.len = template[i].ulValueLen; - PZ_Lock(keyHandle->passwordLock); - if (keyHandle->passwordKey.data == NULL) { - PZ_Unlock(keyHandle->passwordLock); - return CKR_USER_NOT_LOGGED_IN; - } - rv = sftkdb_SignAttribute(arena, &keyHandle->passwordKey, - objectID, template[i].type, - &plainText, &signText); - PZ_Unlock(keyHandle->passwordLock); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; /* better error code here? */ - } - rv = sftkdb_PutAttributeSignature(handle, keyTarget, - objectID, template[i].type, signText); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; /* better error code here? */ - } - } - } - return CKR_OK; -} - -static CK_RV -sftkdb_CreateObject(PRArenaPool *arena, SFTKDBHandle *handle, - SDB *db, CK_OBJECT_HANDLE *objectID, - CK_ATTRIBUTE *template, CK_ULONG count) -{ - PRBool inTransaction = PR_FALSE; - CK_RV crv; - - inTransaction = PR_TRUE; - - crv = (*db->sdb_CreateObject)(db, objectID, template, count); - if (crv != CKR_OK) { - goto loser; - } - crv = sftk_signTemplate(arena, handle, (db == handle->update), - *objectID, template, count); -loser: - - return crv; -} - - -CK_ATTRIBUTE * -sftk_ExtractTemplate(PLArenaPool *arena, SFTKObject *object, - SFTKDBHandle *handle,CK_ULONG *pcount, - CK_RV *crv) -{ - int count; - CK_ATTRIBUTE *template; - int i, templateIndex; - SFTKSessionObject *sessObject = sftk_narrowToSessionObject(object); - PRBool doEnc = PR_TRUE; - - *crv = CKR_OK; - - if (sessObject == NULL) { - *crv = CKR_GENERAL_ERROR; /* internal programming error */ - return NULL; - } - - PORT_Assert(handle); - /* find the key handle */ - if (handle->type != SFTK_KEYDB_TYPE) { - doEnc = PR_FALSE; - } - - PZ_Lock(sessObject->attributeLock); - count = 0; - for (i=0; i < sessObject->hashSize; i++) { - SFTKAttribute *attr; - for (attr=sessObject->head[i]; attr; attr=attr->next) { - count++; - } - } - template = PORT_ArenaNewArray(arena, CK_ATTRIBUTE, count); - if (template == NULL) { - PZ_Unlock(sessObject->attributeLock); - *crv = CKR_HOST_MEMORY; - return NULL; - } - templateIndex = 0; - for (i=0; i < sessObject->hashSize; i++) { - SFTKAttribute *attr; - for (attr=sessObject->head[i]; attr; attr=attr->next) { - CK_ATTRIBUTE *tp = &template[templateIndex++]; - /* copy the attribute */ - *tp = attr->attrib; - - /* fixup ULONG s */ - if ((tp->ulValueLen == sizeof (CK_ULONG)) && - (sftkdb_isULONGAttribute(tp->type)) ) { - CK_ULONG value = *(CK_ULONG *) tp->pValue; - unsigned char *data; - - tp->pValue = PORT_ArenaAlloc(arena, SDB_ULONG_SIZE); - data = (unsigned char *)tp->pValue; - if (data == NULL) { - *crv = CKR_HOST_MEMORY; - break; - } - sftk_ULong2SDBULong(data, value); - tp->ulValueLen = SDB_ULONG_SIZE; - } - - /* encrypt private attributes */ - if (doEnc && sftkdb_isPrivateAttribute(tp->type)) { - /* we have a private attribute */ - SECItem *cipherText; - SECItem plainText; - SECStatus rv; - - plainText.data = tp->pValue; - plainText.len = tp->ulValueLen; - PZ_Lock(handle->passwordLock); - if (handle->passwordKey.data == NULL) { - PZ_Unlock(handle->passwordLock); - *crv = CKR_USER_NOT_LOGGED_IN; - break; - } - rv = sftkdb_EncryptAttribute(arena, &handle->passwordKey, - &plainText, &cipherText); - PZ_Unlock(handle->passwordLock); - if (rv == SECSuccess) { - tp->pValue = cipherText->data; - tp->ulValueLen = cipherText->len; - } else { - *crv = CKR_GENERAL_ERROR; /* better error code here? */ - break; - } - PORT_Memset(plainText.data, 0, plainText.len); - } - } - } - PORT_Assert(templateIndex <= count); - PZ_Unlock(sessObject->attributeLock); - - if (*crv != CKR_OK) { - return NULL; - } - if (pcount) { - *pcount = count; - } - return template; - -} - -/* - * return a pointer to the attribute in the give template. - * The return value is not const, as the caller may modify - * the given attribute value, but such modifications will - * modify the actual value in the template. - */ -static CK_ATTRIBUTE * -sftkdb_getAttributeFromTemplate(CK_ATTRIBUTE_TYPE attribute, - CK_ATTRIBUTE *ptemplate, CK_ULONG len) -{ - CK_ULONG i; - - for (i=0; i < len; i++) { - if (attribute == ptemplate[i].type) { - return &ptemplate[i]; - } - } - return NULL; -} - -static const CK_ATTRIBUTE * -sftkdb_getAttributeFromConstTemplate(CK_ATTRIBUTE_TYPE attribute, - const CK_ATTRIBUTE *ptemplate, CK_ULONG len) -{ - CK_ULONG i; - - for (i=0; i < len; i++) { - if (attribute == ptemplate[i].type) { - return &ptemplate[i]; - } - } - return NULL; -} - - -/* - * fetch a template which identifies 'unique' entries based on object type - */ -static CK_RV -sftkdb_getFindTemplate(CK_OBJECT_CLASS objectType, unsigned char *objTypeData, - CK_ATTRIBUTE *findTemplate, CK_ULONG *findCount, - CK_ATTRIBUTE *ptemplate, int len) -{ - CK_ATTRIBUTE *attr; - CK_ULONG count = 1; - - sftk_ULong2SDBULong(objTypeData, objectType); - findTemplate[0].type = CKA_CLASS; - findTemplate[0].pValue = objTypeData; - findTemplate[0].ulValueLen = SDB_ULONG_SIZE; - - switch (objectType) { - case CKO_CERTIFICATE: - case CKO_NSS_TRUST: - attr = sftkdb_getAttributeFromTemplate(CKA_ISSUER, ptemplate, len); - if (attr == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - findTemplate[1] = *attr; - attr = sftkdb_getAttributeFromTemplate(CKA_SERIAL_NUMBER, - ptemplate, len); - if (attr == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - findTemplate[2] = *attr; - count = 3; - break; - - case CKO_PRIVATE_KEY: - case CKO_PUBLIC_KEY: - case CKO_SECRET_KEY: - attr = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, len); - if (attr == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - findTemplate[1] = *attr; - count = 2; - break; - - case CKO_NSS_CRL: - attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len); - if (attr == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - findTemplate[1] = *attr; - count = 2; - break; - - case CKO_NSS_SMIME: - attr = sftkdb_getAttributeFromTemplate(CKA_SUBJECT, ptemplate, len); - if (attr == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - findTemplate[1] = *attr; - attr = sftkdb_getAttributeFromTemplate(CKA_NSS_EMAIL, ptemplate, len); - if (attr == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - findTemplate[2] = *attr; - count = 3; - break; - default: - attr = sftkdb_getAttributeFromTemplate(CKA_VALUE, ptemplate, len); - if (attr == NULL) { - return CKR_TEMPLATE_INCOMPLETE; - } - findTemplate[1] = *attr; - count = 2; - break; - } - *findCount = count; - - return CKR_OK; -} - -/* - * look to see if this object already exists and return it's object ID if - * it does. - */ -static CK_RV -sftkdb_lookupObject(SDB *db, CK_OBJECT_CLASS objectType, - CK_OBJECT_HANDLE *id, CK_ATTRIBUTE *ptemplate, CK_ULONG len) -{ - CK_ATTRIBUTE findTemplate[3]; - CK_ULONG count = 1; - CK_ULONG objCount = 0; - SDBFind *find = NULL; - unsigned char objTypeData[SDB_ULONG_SIZE]; - CK_RV crv; - - *id = CK_INVALID_HANDLE; - if (objectType == CKO_NSS_CRL) { - return CKR_OK; - } - crv = sftkdb_getFindTemplate(objectType, objTypeData, - findTemplate, &count, ptemplate, len); - if (crv != CKR_OK) { - return crv; - } - - /* use the raw find, so we get the correct database */ - crv = (*db->sdb_FindObjectsInit)(db, findTemplate, count, &find); - if (crv != CKR_OK) { - return crv; - } - (*db->sdb_FindObjects)(db, find, id, 1, &objCount); - (*db->sdb_FindObjectsFinal)(db, find); - - if (objCount == 0) { - *id = CK_INVALID_HANDLE; - } - return CKR_OK; -} - - -/* - * check to see if this template conflicts with others in our current database. - */ -static CK_RV -sftkdb_checkConflicts(SDB *db, CK_OBJECT_CLASS objectType, - const CK_ATTRIBUTE *ptemplate, CK_ULONG len, - CK_OBJECT_HANDLE sourceID) -{ - CK_ATTRIBUTE findTemplate[2]; - unsigned char objTypeData[SDB_ULONG_SIZE]; - /* we may need to allocate some temporaries. Keep track of what was - * allocated so we can free it in the end */ - unsigned char *temp1 = NULL; - unsigned char *temp2 = NULL; - CK_ULONG objCount = 0; - SDBFind *find = NULL; - CK_OBJECT_HANDLE id; - const CK_ATTRIBUTE *attr, *attr2; - CK_RV crv; - CK_ATTRIBUTE subject; - - /* Currently the only conflict is with nicknames pointing to the same - * subject when creating or modifying a certificate. */ - /* If the object is not a cert, no problem. */ - if (objectType != CKO_CERTIFICATE) { - return CKR_OK; - } - /* if not setting a nickname then there's still no problem */ - attr = sftkdb_getAttributeFromConstTemplate(CKA_LABEL, ptemplate, len); - if ((attr == NULL) || (attr->ulValueLen == 0)) { - return CKR_OK; - } - /* fetch the subject of the source. For creation and merge, this should - * be found in the template */ - attr2 = sftkdb_getAttributeFromConstTemplate(CKA_SUBJECT, ptemplate, len); - if (sourceID == CK_INVALID_HANDLE) { - if ((attr2 == NULL) || ((CK_LONG)attr2->ulValueLen < 0)) { - crv = CKR_TEMPLATE_INCOMPLETE; - goto done; - } - } else if ((attr2 == NULL) || ((CK_LONG)attr2->ulValueLen <= 0)) { - /* sourceID is set if we are trying to modify an existing entry instead - * of creating a new one. In this case the subject may not be (probably - * isn't) in the template, we have to read it from the database */ - subject.type = CKA_SUBJECT; - subject.pValue = NULL; - subject.ulValueLen = 0; - crv = (*db->sdb_GetAttributeValue)(db, sourceID, &subject, 1); - if (crv != CKR_OK) { - goto done; - } - if ((CK_LONG)subject.ulValueLen < 0) { - crv = CKR_DEVICE_ERROR; /* closest pkcs11 error to corrupted DB */ - goto done; - } - temp1 = subject.pValue = PORT_Alloc(++subject.ulValueLen); - if (temp1 == NULL) { - crv = CKR_HOST_MEMORY; - goto done; - } - crv = (*db->sdb_GetAttributeValue)(db, sourceID, &subject, 1); - if (crv != CKR_OK) { - goto done; - } - attr2 = &subject; - } - - /* check for another cert in the database with the same nickname */ - sftk_ULong2SDBULong(objTypeData, objectType); - findTemplate[0].type = CKA_CLASS; - findTemplate[0].pValue = objTypeData; - findTemplate[0].ulValueLen = SDB_ULONG_SIZE; - findTemplate[1] = *attr; - - crv = (*db->sdb_FindObjectsInit)(db, findTemplate, 2, &find); - if (crv != CKR_OK) { - goto done; - } - (*db->sdb_FindObjects)(db, find, &id, 1, &objCount); - (*db->sdb_FindObjectsFinal)(db, find); - - /* object count == 0 means no conflicting certs found, - * go on with the operation */ - if (objCount == 0) { - crv = CKR_OK; - goto done; - } - - /* There is a least one cert that shares the nickname, make sure it also - * matches the subject. */ - findTemplate[0] = *attr2; - /* we know how big the source subject was. Use that length to create the - * space for the target. If it's not enough space, then it means the - * source subject is too big, and therefore not a match. GetAttributeValue - * will return CKR_BUFFER_TOO_SMALL. Otherwise it should be exactly enough - * space (or enough space to be able to compare the result. */ - temp2 = findTemplate[0].pValue = PORT_Alloc(++findTemplate[0].ulValueLen); - if (temp2 == NULL) { - crv = CKR_HOST_MEMORY; - goto done; - } - crv = (*db->sdb_GetAttributeValue)(db, id, findTemplate, 1); - if (crv != CKR_OK) { - if (crv == CKR_BUFFER_TOO_SMALL) { - /* if our buffer is too small, then the Subjects clearly do - * not match */ - crv = CKR_ATTRIBUTE_VALUE_INVALID; - goto loser; - } - /* otherwise we couldn't get the value, just fail */ - goto done; - } - - /* Ok, we have both subjects, make sure they are the same. - * Compare the subjects */ - if ((findTemplate[0].ulValueLen != attr2->ulValueLen) || - (attr2->ulValueLen > 0 && - PORT_Memcmp(findTemplate[0].pValue, attr2->pValue, attr2->ulValueLen) - != 0)) { - crv = CKR_ATTRIBUTE_VALUE_INVALID; - goto loser; - } - crv = CKR_OK; - -done: - /* If we've failed for some other reason than a conflict, make sure we - * return an error code other than CKR_ATTRIBUTE_VALUE_INVALID. - * (NOTE: neither sdb_FindObjectsInit nor sdb_GetAttributeValue should - * return CKR_ATTRIBUTE_VALUE_INVALID, so the following is paranoia). - */ - if (crv == CKR_ATTRIBUTE_VALUE_INVALID) { - crv = CKR_GENERAL_ERROR; /* clearly a programming error */ - } - - /* exit point if we found a conflict */ -loser: - PORT_Free(temp1); - PORT_Free(temp2); - return crv; -} - -/* - * try to update the template to fix any errors. This is only done - * during update. - * - * NOTE: we must update the template or return an error, or the update caller - * will loop forever! - * - * Two copies of the source code for this algorithm exist in NSS. - * Changes must be made in both copies. - * The other copy is in pk11_IncrementNickname() in pk11wrap/pk11merge.c. - * - */ -static CK_RV -sftkdb_resolveConflicts(PRArenaPool *arena, CK_OBJECT_CLASS objectType, - CK_ATTRIBUTE *ptemplate, CK_ULONG *plen) -{ - CK_ATTRIBUTE *attr; - char *nickname, *newNickname; - int end, digit; - - /* sanity checks. We should never get here with these errors */ - if (objectType != CKO_CERTIFICATE) { - return CKR_GENERAL_ERROR; /* shouldn't happen */ - } - attr = sftkdb_getAttributeFromTemplate(CKA_LABEL, ptemplate, *plen); - if ((attr == NULL) || (attr->ulValueLen == 0)) { - return CKR_GENERAL_ERROR; /* shouldn't happen */ - } - - /* update the nickname */ - /* is there a number at the end of the nickname already? - * if so just increment that number */ - nickname = (char *)attr->pValue; - - /* does nickname end with " #n*" ? */ - for (end = attr->ulValueLen - 1; - end >= 2 && (digit = nickname[end]) <= '9' && digit >= '0'; - end--) /* just scan */ ; - if (attr->ulValueLen >= 3 && - end < (attr->ulValueLen - 1) /* at least one digit */ && - nickname[end] == '#' && - nickname[end - 1] == ' ') { - /* Already has a suitable suffix string */ - } else { - /* ... append " #2" to the name */ - static const char num2[] = " #2"; - newNickname = PORT_ArenaAlloc(arena, attr->ulValueLen + sizeof(num2)); - if (!newNickname) { - return CKR_HOST_MEMORY; - } - PORT_Memcpy(newNickname, nickname, attr->ulValueLen); - PORT_Memcpy(&newNickname[attr->ulValueLen], num2, sizeof(num2)); - attr->pValue = newNickname; /* modifies ptemplate */ - attr->ulValueLen += 3; /* 3 is strlen(num2) */ - return CKR_OK; - } - - for (end = attr->ulValueLen - 1; - end >= 0 && (digit = nickname[end]) <= '9' && digit >= '0'; - end--) { - if (digit < '9') { - nickname[end]++; - return CKR_OK; - } - nickname[end] = '0'; - } - - /* we overflowed, insert a new '1' for a carry in front of the number */ - newNickname = PORT_ArenaAlloc(arena, attr->ulValueLen + 1); - if (!newNickname) { - return CKR_HOST_MEMORY; - } - /* PORT_Memcpy should handle len of '0' */ - PORT_Memcpy(newNickname, nickname, ++end); - newNickname[end] = '1'; - PORT_Memset(&newNickname[end+1],'0',attr->ulValueLen - end); - attr->pValue = newNickname; - attr->ulValueLen++; - return CKR_OK; -} - -/* - * set an attribute and sign it if necessary - */ -static CK_RV -sftkdb_setAttributeValue(PRArenaPool *arena, SFTKDBHandle *handle, - SDB *db, CK_OBJECT_HANDLE objectID, const CK_ATTRIBUTE *template, - CK_ULONG count) -{ - CK_RV crv; - crv = (*db->sdb_SetAttributeValue)(db, objectID, template, count); - if (crv != CKR_OK) { - return crv; - } - crv = sftk_signTemplate(arena, handle, db == handle->update, - objectID, template, count); - return crv; -} - -/* - * write a softoken object out to the database. - */ -CK_RV -sftkdb_write(SFTKDBHandle *handle, SFTKObject *object, - CK_OBJECT_HANDLE *objectID) -{ - CK_ATTRIBUTE *template; - PLArenaPool *arena; - CK_ULONG count; - CK_RV crv; - SDB *db; - PRBool inTransaction = PR_FALSE; - CK_OBJECT_HANDLE id; - - *objectID = CK_INVALID_HANDLE; - - if (handle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - db = SFTK_GET_SDB(handle); - - /* - * we have opened a new database, but we have not yet updated it. We are - * still running pointing to the old database (so the application can - * still read). We don't want to write to the old database at this point, - * however, since it leads to user confusion. So at this point we simply - * require a user login. Let NSS know this so it can prompt the user. - */ - if (db == handle->update) { - return CKR_USER_NOT_LOGGED_IN; - } - - arena = PORT_NewArena(256); - if (arena == NULL) { - return CKR_HOST_MEMORY; - } - - template = sftk_ExtractTemplate(arena, object, handle, &count, &crv); - if (!template) { - goto loser; - } - - crv = (*db->sdb_Begin)(db); - if (crv != CKR_OK) { - goto loser; - } - inTransaction = PR_TRUE; - - /* - * We want to make the base database as free from object specific knowledge - * as possible. To maintain compatibility, keep some of the desirable - * object specific semantics of the old database. - * - * These were 2 fold: - * 1) there were certain conflicts (like trying to set the same nickname - * on two different subjects) that would return an error. - * 2) Importing the 'same' object would silently update that object. - * - * The following 2 functions mimic the desirable effects of these two - * semantics without pushing any object knowledge to the underlying database - * code. - */ - - /* make sure we don't have attributes that conflict with the existing DB */ - crv = sftkdb_checkConflicts(db, object->objclass, template, count, - CK_INVALID_HANDLE); - if (crv != CKR_OK) { - goto loser; - } - /* Find any copies that match this particular object */ - crv = sftkdb_lookupObject(db, object->objclass, &id, template, count); - if (crv != CKR_OK) { - goto loser; - } - if (id == CK_INVALID_HANDLE) { - crv = sftkdb_CreateObject(arena, handle, db, objectID, template, count); - } else { - /* object already exists, modify it's attributes */ - *objectID = id; - crv = sftkdb_setAttributeValue(arena, handle, db, id, template, count); - } - if (crv != CKR_OK) { - goto loser; - } - - crv = (*db->sdb_Commit)(db); - inTransaction = PR_FALSE; - -loser: - if (inTransaction) { - (*db->sdb_Abort)(db); - /* It is trivial to show the following code cannot - * happen unless something is horribly wrong with our compilier or - * hardware */ - PORT_Assert(crv != CKR_OK); - if (crv == CKR_OK) crv = CKR_GENERAL_ERROR; - } - - if (arena) { - PORT_FreeArena(arena,PR_FALSE); - } - if (crv == CKR_OK) { - *objectID |= (handle->type | SFTK_TOKEN_TYPE); - } - return crv; -} - - -CK_RV -sftkdb_FindObjectsInit(SFTKDBHandle *handle, const CK_ATTRIBUTE *template, - CK_ULONG count, SDBFind **find) -{ - unsigned char *data = NULL; - CK_ATTRIBUTE *ntemplate = NULL; - CK_RV crv; - SDB *db; - - if (handle == NULL) { - return CKR_OK; - } - db = SFTK_GET_SDB(handle); - - if (count != 0) { - ntemplate = sftkdb_fixupTemplateIn(template, count, &data); - if (ntemplate == NULL) { - return CKR_HOST_MEMORY; - } - } - - crv = (*db->sdb_FindObjectsInit)(db, ntemplate, - count, find); - if (data) { - PORT_Free(ntemplate); - PORT_Free(data); - } - return crv; -} - -CK_RV -sftkdb_FindObjects(SFTKDBHandle *handle, SDBFind *find, - CK_OBJECT_HANDLE *ids, int arraySize, CK_ULONG *count) -{ - CK_RV crv; - SDB *db; - - if (handle == NULL) { - *count = 0; - return CKR_OK; - } - db = SFTK_GET_SDB(handle); - - crv = (*db->sdb_FindObjects)(db, find, ids, - arraySize, count); - if (crv == CKR_OK) { - int i; - for (i=0; i < *count; i++) { - ids[i] |= (handle->type | SFTK_TOKEN_TYPE); - } - } - return crv; -} - -CK_RV sftkdb_FindObjectsFinal(SFTKDBHandle *handle, SDBFind *find) -{ - SDB *db; - if (handle == NULL) { - return CKR_OK; - } - db = SFTK_GET_SDB(handle); - return (*db->sdb_FindObjectsFinal)(db, find); -} - -CK_RV -sftkdb_GetAttributeValue(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID, - CK_ATTRIBUTE *template, CK_ULONG count) -{ - CK_RV crv,crv2; - CK_ATTRIBUTE *ntemplate; - unsigned char *data = NULL; - SDB *db; - - if (handle == NULL) { - return CKR_GENERAL_ERROR; - } - - /* short circuit common attributes */ - if (count == 1 && - (template[0].type == CKA_TOKEN || - template[0].type == CKA_PRIVATE || - template[0].type == CKA_SENSITIVE)) { - CK_BBOOL boolVal = CK_TRUE; - - if (template[0].pValue == NULL) { - template[0].ulValueLen = sizeof(CK_BBOOL); - return CKR_OK; - } - if (template[0].ulValueLen < sizeof(CK_BBOOL)) { - template[0].ulValueLen = -1; - return CKR_BUFFER_TOO_SMALL; - } - - if ((template[0].type == CKA_PRIVATE) && - (handle->type != SFTK_KEYDB_TYPE)) { - boolVal = CK_FALSE; - } - if ((template[0].type == CKA_SENSITIVE) && - (handle->type != SFTK_KEYDB_TYPE)) { - boolVal = CK_FALSE; - } - *(CK_BBOOL *)template[0].pValue = boolVal; - template[0].ulValueLen = sizeof(CK_BBOOL); - return CKR_OK; - } - - db = SFTK_GET_SDB(handle); - /* nothing to do */ - if (count == 0) { - return CKR_OK; - } - ntemplate = sftkdb_fixupTemplateIn(template, count, &data); - if (ntemplate == NULL) { - return CKR_HOST_MEMORY; - } - objectID &= SFTK_OBJ_ID_MASK; - crv = (*db->sdb_GetAttributeValue)(db, objectID, - ntemplate, count); - crv2 = sftkdb_fixupTemplateOut(template, objectID, ntemplate, - count, handle); - if (crv == CKR_OK) crv = crv2; - if (data) { - PORT_Free(ntemplate); - PORT_Free(data); - } - return crv; - -} - -CK_RV -sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, - const CK_ATTRIBUTE *template, CK_ULONG count) -{ - CK_RV crv = CKR_OK; - CK_ATTRIBUTE *ntemplate; - unsigned char *data = NULL; - PLArenaPool *arena = NULL; - CK_OBJECT_HANDLE objectID = (object->handle & SFTK_OBJ_ID_MASK); - SDB *db; - - if (handle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - - db = SFTK_GET_SDB(handle); - /* nothing to do */ - if (count == 0) { - return CKR_OK; - } - /* - * we have opened a new database, but we have not yet updated it. We are - * still running pointing to the old database (so the application can - * still read). We don't want to write to the old database at this point, - * however, since it leads to user confusion. So at this point we simply - * require a user login. Let NSS know this so it can prompt the user. - */ - if (db == handle->update) { - return CKR_USER_NOT_LOGGED_IN; - } - - ntemplate = sftkdb_fixupTemplateIn(template, count, &data); - if (ntemplate == NULL) { - return CKR_HOST_MEMORY; - } - - /* make sure we don't have attributes that conflict with the existing DB */ - crv = sftkdb_checkConflicts(db, object->objclass, template, count, objectID); - if (crv != CKR_OK) { - return crv; - } - - arena = PORT_NewArena(256); - if (arena == NULL) { - return CKR_HOST_MEMORY; - } - - crv = (*db->sdb_Begin)(db); - if (crv != CKR_OK) { - goto loser; - } - crv = sftkdb_setAttributeValue(arena, handle, db, - objectID, template, count); - if (crv != CKR_OK) { - goto loser; - } - crv = (*db->sdb_Commit)(db); -loser: - if (crv != CKR_OK) { - (*db->sdb_Abort)(db); - } - if (data) { - PORT_Free(ntemplate); - PORT_Free(data); - } - PORT_FreeArena(arena, PR_FALSE); - return crv; -} - -CK_RV -sftkdb_DestroyObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE objectID) -{ - CK_RV crv = CKR_OK; - SDB *db; - - if (handle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - db = SFTK_GET_SDB(handle); - objectID &= SFTK_OBJ_ID_MASK; - crv = (*db->sdb_Begin)(db); - if (crv != CKR_OK) { - goto loser; - } - crv = (*db->sdb_DestroyObject)(db, objectID); - if (crv != CKR_OK) { - goto loser; - } - crv = (*db->sdb_Commit)(db); -loser: - if (crv != CKR_OK) { - (*db->sdb_Abort)(db); - } - return crv; -} - -CK_RV -sftkdb_CloseDB(SFTKDBHandle *handle) -{ -#ifdef NO_FORK_CHECK - PRBool parentForkedAfterC_Initialize = PR_FALSE; -#endif - if (handle == NULL) { - return CKR_OK; - } - if (handle->update) { - if (handle->db->sdb_SetForkState) { - (*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize); - } - (*handle->update->sdb_Close)(handle->update); - } - if (handle->db) { - if (handle->db->sdb_SetForkState) { - (*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize); - } - (*handle->db->sdb_Close)(handle->db); - } - if (handle->passwordLock) { - SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock)); - } - if (handle->updatePasswordKey) { - SECITEM_FreeItem(handle->updatePasswordKey, PR_TRUE); - } - if (handle->updateID) { - PORT_Free(handle->updateID); - } - PORT_Free(handle); - return CKR_OK; -} - -/* - * reset a database to it's uninitialized state. - */ -static CK_RV -sftkdb_ResetDB(SFTKDBHandle *handle) -{ - CK_RV crv = CKR_OK; - SDB *db; - if (handle == NULL) { - return CKR_TOKEN_WRITE_PROTECTED; - } - db = SFTK_GET_SDB(handle); - crv = (*db->sdb_Begin)(db); - if (crv != CKR_OK) { - goto loser; - } - crv = (*db->sdb_Reset)(db); - if (crv != CKR_OK) { - goto loser; - } - crv = (*db->sdb_Commit)(db); -loser: - if (crv != CKR_OK) { - (*db->sdb_Abort)(db); - } - return crv; -} - - -CK_RV -sftkdb_Begin(SFTKDBHandle *handle) -{ - CK_RV crv = CKR_OK; - SDB *db; - - if (handle == NULL) { - return CKR_OK; - } - db = SFTK_GET_SDB(handle); - if (db) { - crv = (*db->sdb_Begin)(db); - } - return crv; -} - -CK_RV -sftkdb_Commit(SFTKDBHandle *handle) -{ - CK_RV crv = CKR_OK; - SDB *db; - - if (handle == NULL) { - return CKR_OK; - } - db = SFTK_GET_SDB(handle); - if (db) { - (*db->sdb_Commit)(db); - } - return crv; -} - -CK_RV -sftkdb_Abort(SFTKDBHandle *handle) -{ - CK_RV crv = CKR_OK; - SDB *db; - - if (handle == NULL) { - return CKR_OK; - } - db = SFTK_GET_SDB(handle); - if (db) { - crv = (db->sdb_Abort)(db); - } - return crv; -} - - -/* - * functions to update the database from an old database - */ - -/* - * known attributes - */ -static const CK_ATTRIBUTE_TYPE known_attributes[] = { - CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_LABEL, CKA_APPLICATION, - CKA_VALUE, CKA_OBJECT_ID, CKA_CERTIFICATE_TYPE, CKA_ISSUER, - CKA_SERIAL_NUMBER, CKA_AC_ISSUER, CKA_OWNER, CKA_ATTR_TYPES, CKA_TRUSTED, - CKA_CERTIFICATE_CATEGORY, CKA_JAVA_MIDP_SECURITY_DOMAIN, CKA_URL, - CKA_HASH_OF_SUBJECT_PUBLIC_KEY, CKA_HASH_OF_ISSUER_PUBLIC_KEY, - CKA_CHECK_VALUE, CKA_KEY_TYPE, CKA_SUBJECT, CKA_ID, CKA_SENSITIVE, - CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP, CKA_SIGN, CKA_SIGN_RECOVER, - CKA_VERIFY, CKA_VERIFY_RECOVER, CKA_DERIVE, CKA_START_DATE, CKA_END_DATE, - CKA_MODULUS, CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_PRIVATE_EXPONENT, - CKA_PRIME_1, CKA_PRIME_2, CKA_EXPONENT_1, CKA_EXPONENT_2, CKA_COEFFICIENT, - CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_PRIME_BITS, - CKA_SUB_PRIME_BITS, CKA_VALUE_BITS, CKA_VALUE_LEN, CKA_EXTRACTABLE, - CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, - CKA_KEY_GEN_MECHANISM, CKA_MODIFIABLE, CKA_EC_PARAMS, - CKA_EC_POINT, CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, - CKA_ALWAYS_AUTHENTICATE, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_TEMPLATE, - CKA_UNWRAP_TEMPLATE, CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, - CKA_HAS_RESET, CKA_PIXEL_X, CKA_PIXEL_Y, CKA_RESOLUTION, CKA_CHAR_ROWS, - CKA_CHAR_COLUMNS, CKA_COLOR, CKA_BITS_PER_PIXEL, CKA_CHAR_SETS, - CKA_ENCODING_METHODS, CKA_MIME_TYPES, CKA_MECHANISM_TYPE, - CKA_REQUIRED_CMS_ATTRIBUTES, CKA_DEFAULT_CMS_ATTRIBUTES, - CKA_SUPPORTED_CMS_ATTRIBUTES, CKA_NSS_URL, CKA_NSS_EMAIL, - CKA_NSS_SMIME_INFO, CKA_NSS_SMIME_TIMESTAMP, - CKA_NSS_PKCS8_SALT, CKA_NSS_PASSWORD_CHECK, CKA_NSS_EXPIRES, - CKA_NSS_KRL, CKA_NSS_PQG_COUNTER, CKA_NSS_PQG_SEED, - CKA_NSS_PQG_H, CKA_NSS_PQG_SEED_BITS, CKA_NSS_MODULE_SPEC, - CKA_TRUST_DIGITAL_SIGNATURE, CKA_TRUST_NON_REPUDIATION, - CKA_TRUST_KEY_ENCIPHERMENT, CKA_TRUST_DATA_ENCIPHERMENT, - CKA_TRUST_KEY_AGREEMENT, CKA_TRUST_KEY_CERT_SIGN, CKA_TRUST_CRL_SIGN, - CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, CKA_TRUST_CODE_SIGNING, - CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM, - CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING, - CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, - CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS -}; - -static int known_attributes_size= sizeof(known_attributes)/ - sizeof(known_attributes[0]); - -static CK_RV -sftkdb_GetObjectTemplate(SDB *source, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE *ptemplate, CK_ULONG *max) -{ - int i,j; - CK_RV crv; - - if (*max < known_attributes_size) { - *max = known_attributes_size; - return CKR_BUFFER_TOO_SMALL; - } - for (i=0; i < known_attributes_size; i++) { - ptemplate[i].type = known_attributes[i]; - ptemplate[i].pValue = NULL; - ptemplate[i].ulValueLen = 0; - } - - crv = (*source->sdb_GetAttributeValue)(source, id, - ptemplate, known_attributes_size); - - if ((crv != CKR_OK) && (crv != CKR_ATTRIBUTE_TYPE_INVALID)) { - return crv; - } - - for (i=0, j=0; i < known_attributes_size; i++, j++) { - while (i < known_attributes_size && (ptemplate[i].ulValueLen == -1)) { - i++; - } - if (i >= known_attributes_size) { - break; - } - /* cheap optimization */ - if (i == j) { - continue; - } - ptemplate[j] = ptemplate[i]; - } - *max = j; - return CKR_OK; -} - -static const char SFTKDB_META_UPDATE_TEMPLATE[] = "upd_%s_%s"; - -/* - * check to see if we have already updated this database. - * a NULL updateID means we are trying to do an in place - * single database update. In that case we have already - * determined that an update was necessary. - */ -static PRBool -sftkdb_hasUpdate(const char *typeString, SDB *db, const char *updateID) -{ - char *id; - CK_RV crv; - SECItem dummy = { 0, NULL, 0 }; - unsigned char dummyData[SDB_MAX_META_DATA_LEN]; - - if (!updateID) { - return PR_FALSE; - } - id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID); - if (id == NULL) { - return PR_FALSE; - } - dummy.data = dummyData; - dummy.len = sizeof(dummyData); - - crv = (*db->sdb_GetMetaData)(db, id, &dummy, NULL); - PR_smprintf_free(id); - return crv == CKR_OK ? PR_TRUE : PR_FALSE; -} - -/* - * we just completed an update, store the update id - * so we don't need to do it again. If non was given, - * there is nothing to do. - */ -static CK_RV -sftkdb_putUpdate(const char *typeString, SDB *db, const char *updateID) -{ - char *id; - CK_RV crv; - SECItem dummy = { 0, NULL, 0 }; - - /* if no id was given, nothing to do */ - if (updateID == NULL) { - return CKR_OK; - } - - dummy.data = (unsigned char *)updateID; - dummy.len = PORT_Strlen(updateID); - - id = PR_smprintf(SFTKDB_META_UPDATE_TEMPLATE, typeString, updateID); - if (id == NULL) { - return PR_FALSE; - } - - crv = (*db->sdb_PutMetaData)(db, id, &dummy, NULL); - PR_smprintf_free(id); - return crv; -} - -/* - * get a ULong attribute from a template: - * NOTE: this is a raw templated stored in database order! - */ -static CK_ULONG -sftkdb_getULongFromTemplate(CK_ATTRIBUTE_TYPE type, - CK_ATTRIBUTE *ptemplate, CK_ULONG len) -{ - CK_ATTRIBUTE *attr = sftkdb_getAttributeFromTemplate(type, - ptemplate, len); - - if (attr && attr->pValue && attr->ulValueLen == SDB_ULONG_SIZE) { - return sftk_SDBULong2ULong(attr->pValue); - } - return (CK_ULONG)-1; -} - -/* - * we need to find a unique CKA_ID. - * The basic idea is to just increment the lowest byte. - * This code also handles the following corner cases: - * 1) the single byte overflows. On overflow we increment the next byte up - * and so forth until we have overflowed the entire CKA_ID. - * 2) If we overflow the entire CKA_ID we expand it by one byte. - * 3) the CKA_ID is non-existant, we create a new one with one byte. - * This means no matter what CKA_ID is passed, the result of this function - * is always a new CKA_ID, and this function will never return the same - * CKA_ID the it has returned in the passed. - */ -static CK_RV -sftkdb_incrementCKAID(PRArenaPool *arena, CK_ATTRIBUTE *ptemplate) -{ - unsigned char *buf = ptemplate->pValue; - CK_ULONG len = ptemplate->ulValueLen; - - if (buf == NULL || len == (CK_ULONG)-1) { - /* we have no valid CKAID, we'll create a basic one byte CKA_ID below */ - len = 0; - } else { - CK_ULONG i; - - /* walk from the back to front, incrementing - * the CKA_ID until we no longer have a carry, - * or have hit the front of the id. */ - for (i=len; i != 0; i--) { - buf[i-1]++; - if (buf[i-1] != 0) { - /* no more carries, the increment is complete */ - return CKR_OK; - } - } - /* we've now overflowed, fall through and expand the CKA_ID by - * one byte */ - } - buf = PORT_ArenaAlloc(arena, len+1); - if (!buf) { - return CKR_HOST_MEMORY; - } - if (len > 0) { - PORT_Memcpy(buf, ptemplate->pValue, len); - } - buf[len] = 0; - ptemplate->pValue = buf; - ptemplate->ulValueLen = len+1; - return CKR_OK; -} - -/* - * drop an attribute from a template. - */ -void -sftkdb_dropAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE *ptemplate, - CK_ULONG *plen) -{ - CK_ULONG count = *plen; - CK_ULONG i; - - for (i=0; i < count; i++) { - if (attr->type == ptemplate[i].type) { - break; - } - } - - if (i == count) { - /* attribute not found */ - return; - } - - /* copy the remaining attributes up */ - for ( i++; i < count; i++) { - ptemplate[i-1] = ptemplate[i]; - } - - /* decrement the template size */ - *plen = count -1; -} - -/* - * create some defines for the following functions to document the meaning - * of true/false. (make's it easier to remember what means what. - */ -typedef enum { - SFTKDB_DO_NOTHING = 0, - SFTKDB_ADD_OBJECT, - SFTKDB_MODIFY_OBJECT, - SFTKDB_DROP_ATTRIBUTE -} sftkdbUpdateStatus; - -/* - * helper function to reconcile a single trust entry. - * Identify which trust entry we want to keep. - * If we don't need to do anything (the records are already equal). - * return SFTKDB_DO_NOTHING. - * If we want to use the source version, - * return SFTKDB_MODIFY_OBJECT - * If we want to use the target version, - * return SFTKDB_DROP_ATTRIBUTE - * - * In the end the caller will remove any attributes in the source - * template when SFTKDB_DROP_ATTRIBUTE is specified, then use do a - * set attributes with that template on the target if we received - * any SFTKDB_MODIFY_OBJECT returns. - */ -sftkdbUpdateStatus -sftkdb_reconcileTrustEntry(PRArenaPool *arena, CK_ATTRIBUTE *target, - CK_ATTRIBUTE *source) -{ - CK_ULONG targetTrust = sftkdb_getULongFromTemplate(target->type, - target, 1); - CK_ULONG sourceTrust = sftkdb_getULongFromTemplate(target->type, - source, 1); - - /* - * try to pick the best solution between the source and the - * target. Update the source template if we want the target value - * to win out. Prefer cases where we don't actually update the - * trust entry. - */ - - /* they are the same, everything is already kosher */ - if (targetTrust == sourceTrust) { - return SFTKDB_DO_NOTHING; - } - - /* handle the case where the source Trust attribute may be a bit - * flakey */ - if (sourceTrust == (CK_ULONG)-1) { - /* - * The source Trust is invalid. We know that the target Trust - * must be valid here, otherwise the above - * targetTrust == sourceTrust check would have succeeded. - */ - return SFTKDB_DROP_ATTRIBUTE; - } - - /* target is invalid, use the source's idea of the trust value */ - if (targetTrust == (CK_ULONG)-1) { - /* overwriting the target in this case is OK */ - return SFTKDB_MODIFY_OBJECT; - } - - /* at this point we know that both attributes exist and have the - * appropriate length (SDB_ULONG_SIZE). We no longer need to check - * ulValueLen for either attribute. - */ - if (sourceTrust == CKT_NSS_TRUST_UNKNOWN) { - return SFTKDB_DROP_ATTRIBUTE; - } - - /* target has no idea, use the source's idea of the trust value */ - if (targetTrust == CKT_NSS_TRUST_UNKNOWN) { - /* overwriting the target in this case is OK */ - return SFTKDB_MODIFY_OBJECT; - } - - /* so both the target and the source have some idea of what this - * trust attribute should be, and neither agree exactly. - * At this point, we prefer 'hard' attributes over 'soft' ones. - * 'hard' ones are CKT_NSS_TRUSTED, CKT_NSS_TRUSTED_DELEGATOR, and - * CKT_NSS_UNTRUTED. Soft ones are ones which don't change the - * actual trust of the cert (CKT_MUST_VERIFY, CKT_NSS_VALID, - * CKT_NSS_VALID_DELEGATOR). - */ - if ((sourceTrust == CKT_NSS_MUST_VERIFY) - || (sourceTrust == CKT_NSS_VALID) - || (sourceTrust == CKT_NSS_VALID_DELEGATOR)) { - return SFTKDB_DROP_ATTRIBUTE; - } - if ((targetTrust == CKT_NSS_MUST_VERIFY) - || (targetTrust == CKT_NSS_VALID) - || (targetTrust == CKT_NSS_VALID_DELEGATOR)) { - /* again, overwriting the target in this case is OK */ - return SFTKDB_MODIFY_OBJECT; - } - - /* both have hard attributes, we have a conflict, let the target win. */ - return SFTKDB_DROP_ATTRIBUTE; -} - -const CK_ATTRIBUTE_TYPE sftkdb_trustList[] = - { CKA_TRUST_SERVER_AUTH, CKA_TRUST_CLIENT_AUTH, - CKA_TRUST_CODE_SIGNING, CKA_TRUST_EMAIL_PROTECTION, - CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, - CKA_TRUST_TIME_STAMPING }; - -#define SFTK_TRUST_TEMPLATE_COUNT \ - (sizeof(sftkdb_trustList)/sizeof(sftkdb_trustList[0])) -/* - * Run through the list of known trust types, and reconcile each trust - * entry one by one. Keep track of we really need to write out the source - * trust object (overwriting the existing one). - */ -static sftkdbUpdateStatus -sftkdb_reconcileTrust(PRArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE *ptemplate, CK_ULONG *plen) -{ - CK_ATTRIBUTE trustTemplate[SFTK_TRUST_TEMPLATE_COUNT]; - unsigned char trustData[SFTK_TRUST_TEMPLATE_COUNT*SDB_ULONG_SIZE]; - sftkdbUpdateStatus update = SFTKDB_DO_NOTHING; - CK_ULONG i; - CK_RV crv; - - - for (i=0; i < SFTK_TRUST_TEMPLATE_COUNT; i++) { - trustTemplate[i].type = sftkdb_trustList[i]; - trustTemplate[i].pValue = &trustData[i*SDB_ULONG_SIZE]; - trustTemplate[i].ulValueLen = SDB_ULONG_SIZE; - } - crv = (*db->sdb_GetAttributeValue)(db, id, - trustTemplate, SFTK_TRUST_TEMPLATE_COUNT); - if ((crv != CKR_OK) && (crv != CKR_ATTRIBUTE_TYPE_INVALID)) { - /* target trust has some problems, update it */ - update = SFTKDB_MODIFY_OBJECT; - goto done; - } - - for (i=0; i < SFTK_TRUST_TEMPLATE_COUNT; i++) { - CK_ATTRIBUTE *attr = sftkdb_getAttributeFromTemplate( - trustTemplate[i].type, ptemplate, *plen); - sftkdbUpdateStatus status; - - - /* if target trust value doesn't exist, nothing to merge */ - if (trustTemplate[i].ulValueLen == (CK_ULONG)-1) { - /* if the source exists, then we want the source entry, - * go ahead and update */ - if (attr && attr->ulValueLen != (CK_ULONG)-1) { - update = SFTKDB_MODIFY_OBJECT; - } - continue; - } - - /* - * the source doesn't have the attribute, go to the next attribute - */ - if (attr == NULL) { - continue; - - } - status = sftkdb_reconcileTrustEntry(arena, &trustTemplate[i], attr); - if (status == SFTKDB_MODIFY_OBJECT) { - update = SFTKDB_MODIFY_OBJECT; - } else if (status == SFTKDB_DROP_ATTRIBUTE) { - /* drop the source copy of the attribute, we are going with - * the target's version */ - sftkdb_dropAttribute(attr, ptemplate, plen); - } - } - - /* finally manage stepup */ - if (update == SFTKDB_MODIFY_OBJECT) { - CK_BBOOL stepUpBool = CK_FALSE; - /* if we are going to write from the source, make sure we don't - * overwrite the stepup bit if it's on*/ - trustTemplate[0].type = CKA_TRUST_STEP_UP_APPROVED; - trustTemplate[0].pValue = &stepUpBool; - trustTemplate[0].ulValueLen = sizeof(stepUpBool); - crv = (*db->sdb_GetAttributeValue)(db, id, trustTemplate, 1); - if ((crv == CKR_OK) && (stepUpBool == CK_TRUE)) { - sftkdb_dropAttribute(trustTemplate, ptemplate, plen); - } - } else { - /* we currently aren't going to update. If the source stepup bit is - * on however, do an update so the target gets it as well */ - CK_ATTRIBUTE *attr; - - attr = sftkdb_getAttributeFromTemplate(CKA_TRUST_STEP_UP_APPROVED, - ptemplate, *plen); - if (attr && (attr->ulValueLen == sizeof(CK_BBOOL)) && - (*(CK_BBOOL *)(attr->pValue) == CK_TRUE)) { - update = SFTKDB_MODIFY_OBJECT; - } - } - -done: - return update; -} - -static sftkdbUpdateStatus -sftkdb_handleIDAndName(PRArenaPool *arena, SDB *db, CK_OBJECT_HANDLE id, - CK_ATTRIBUTE *ptemplate, CK_ULONG *plen) -{ - sftkdbUpdateStatus update = SFTKDB_DO_NOTHING; - CK_ATTRIBUTE *attr1, *attr2; - CK_ATTRIBUTE ttemplate[2] = { - {CKA_ID, NULL, 0}, - {CKA_LABEL, NULL, 0} - }; - CK_RV crv; - - attr1 = sftkdb_getAttributeFromTemplate(CKA_LABEL, ptemplate, *plen); - attr2 = sftkdb_getAttributeFromTemplate(CKA_ID, ptemplate, *plen); - - /* if the source has neither an id nor label, don't bother updating */ - if ( (!attr1 || attr1->ulValueLen == 0) && - (! attr2 || attr2->ulValueLen == 0) ) { - return SFTKDB_DO_NOTHING; - } - - /* the source has either an id or a label, see what the target has */ - crv = (*db->sdb_GetAttributeValue)(db, id, ttemplate, 2); - - /* if the target has neither, update from the source */ - if ( ((ttemplate[0].ulValueLen == 0) || - (ttemplate[0].ulValueLen == (CK_ULONG)-1)) && - ((ttemplate[1].ulValueLen == 0) || - (ttemplate[1].ulValueLen == (CK_ULONG)-1)) ) { - return SFTKDB_MODIFY_OBJECT; - } - - /* check the CKA_ID */ - if ((ttemplate[0].ulValueLen != 0) && - (ttemplate[0].ulValueLen != (CK_ULONG)-1)) { - /* we have a CKA_ID in the target, don't overwrite - * the target with an empty CKA_ID from the source*/ - if (attr1 && attr1->ulValueLen == 0) { - sftkdb_dropAttribute(attr1, ptemplate, plen); - } - } else if (attr1 && attr1->ulValueLen != 0) { - /* source has a CKA_ID, but the target doesn't, update the target */ - update = SFTKDB_MODIFY_OBJECT; - } - - - /* check the nickname */ - if ((ttemplate[1].ulValueLen != 0) && - (ttemplate[1].ulValueLen != (CK_ULONG)-1)) { - - /* we have a nickname in the target, and we don't have to update - * the CKA_ID. We are done. NOTE: if we add addition attributes - * in this check, this shortcut can only go on the last of them. */ - if (update == SFTKDB_DO_NOTHING) { - return update; - } - /* we have a nickname in the target, don't overwrite - * the target with an empty nickname from the source */ - if (attr2 && attr2->ulValueLen == 0) { - sftkdb_dropAttribute(attr2, ptemplate, plen); - } - } else if (attr2 && attr2->ulValueLen != 0) { - /* source has a nickname, but the target doesn't, update the target */ - update = SFTKDB_MODIFY_OBJECT; - } - - return update; -} - - - -/* - * This function updates the template before we write the object out. - * - * If we are going to skip updating this object, return PR_FALSE. - * If it should be updated we return PR_TRUE. - * To help readability, these have been defined - * as SFTK_DONT_UPDATE and SFTK_UPDATE respectively. - */ -static PRBool -sftkdb_updateObjectTemplate(PRArenaPool *arena, SDB *db, - CK_OBJECT_CLASS objectType, - CK_ATTRIBUTE *ptemplate, CK_ULONG *plen, - CK_OBJECT_HANDLE *targetID) -{ - PRBool done; /* should we repeat the loop? */ - CK_OBJECT_HANDLE id; - CK_RV crv = CKR_OK; - - do { - crv = sftkdb_checkConflicts(db, objectType, ptemplate, - *plen, CK_INVALID_HANDLE); - if (crv != CKR_ATTRIBUTE_VALUE_INVALID) { - break; - } - crv = sftkdb_resolveConflicts(arena, objectType, ptemplate, plen); - } while (crv == CKR_OK); - - if (crv != CKR_OK) { - return SFTKDB_DO_NOTHING; - } - - do { - done = PR_TRUE; - crv = sftkdb_lookupObject(db, objectType, &id, ptemplate, *plen); - if (crv != CKR_OK) { - return SFTKDB_DO_NOTHING; - } - - /* This object already exists, merge it, don't update */ - if (id != CK_INVALID_HANDLE) { - CK_ATTRIBUTE *attr = NULL; - /* special post processing for attributes */ - switch (objectType) { - case CKO_CERTIFICATE: - case CKO_PUBLIC_KEY: - case CKO_PRIVATE_KEY: - /* update target's CKA_ID and labels if they don't already - * exist */ - *targetID = id; - return sftkdb_handleIDAndName(arena, db, id, ptemplate, plen); - case CKO_NSS_TRUST: - /* if we have conflicting trust object types, - * we need to reconcile them */ - *targetID = id; - return sftkdb_reconcileTrust(arena, db, id, ptemplate, plen); - case CKO_SECRET_KEY: - /* secret keys in the old database are all sdr keys, - * unfortunately they all appear to have the same CKA_ID, - * even though they are truly different keys, so we always - * want to update these keys, but we need to - * give them a new CKA_ID */ - /* NOTE: this changes ptemplate */ - attr = sftkdb_getAttributeFromTemplate(CKA_ID,ptemplate,*plen); - crv = sftkdb_incrementCKAID(arena, attr); - /* in the extremely rare event that we needed memory and - * couldn't get it, just drop the key */ - if (crv != CKR_OK) { - return SFTKDB_DO_NOTHING; - } - done = PR_FALSE; /* repeat this find loop */ - break; - default: - /* for all other objects, if we found the equivalent object, - * don't update it */ - return SFTKDB_DO_NOTHING; - } - } - } while (!done); - - /* this object doesn't exist, update it */ - return SFTKDB_ADD_OBJECT; -} - - -#define MAX_ATTRIBUTES 500 -static CK_RV -sftkdb_mergeObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE id, - SECItem *key) -{ - CK_ATTRIBUTE template[MAX_ATTRIBUTES]; - CK_ATTRIBUTE *ptemplate; - CK_ULONG max_attributes = MAX_ATTRIBUTES; - CK_OBJECT_CLASS objectType; - SDB *source = handle->update; - SDB *target = handle->db; - int i; - CK_RV crv; - PLArenaPool *arena = NULL; - - arena = PORT_NewArena(256); - if (arena == NULL) { - return CKR_HOST_MEMORY; - } - - ptemplate = &template[0]; - id &= SFTK_OBJ_ID_MASK; - crv = sftkdb_GetObjectTemplate(source, id, ptemplate, &max_attributes); - if (crv == CKR_BUFFER_TOO_SMALL) { - ptemplate = PORT_ArenaNewArray(arena, CK_ATTRIBUTE, max_attributes); - if (ptemplate == NULL) { - crv = CKR_HOST_MEMORY; - } else { - crv = sftkdb_GetObjectTemplate(source, id, - ptemplate, &max_attributes); - } - } - if (crv != CKR_OK) { - goto loser; - } - - for (i=0; i < max_attributes; i++) { - ptemplate[i].pValue = PORT_ArenaAlloc(arena,ptemplate[i].ulValueLen); - if (ptemplate[i].pValue == NULL) { - crv = CKR_HOST_MEMORY; - goto loser; - } - } - crv = (*source->sdb_GetAttributeValue)(source, id, - ptemplate, max_attributes); - if (crv != CKR_OK) { - goto loser; - } - - objectType = sftkdb_getULongFromTemplate(CKA_CLASS, ptemplate, - max_attributes); - - /* - * Update Object updates the object template if necessary then returns - * whether or not we need to actually write the object out to our target - * database. - */ - if (!handle->updateID) { - crv = sftkdb_CreateObject(arena, handle, target, &id, - ptemplate, max_attributes); - } else { - sftkdbUpdateStatus update_status; - update_status = sftkdb_updateObjectTemplate(arena, target, - objectType, ptemplate, &max_attributes, &id); - switch (update_status) { - case SFTKDB_ADD_OBJECT: - crv = sftkdb_CreateObject(arena, handle, target, &id, - ptemplate, max_attributes); - break; - case SFTKDB_MODIFY_OBJECT: - crv = sftkdb_setAttributeValue(arena, handle, target, - id, ptemplate, max_attributes); - break; - case SFTKDB_DO_NOTHING: - case SFTKDB_DROP_ATTRIBUTE: - break; - } - } - -loser: - if (arena) { - PORT_FreeArena(arena,PR_TRUE); - } - return crv; -} - - -#define MAX_IDS 10 -/* - * update a new database from an old one, now that we have the key - */ -CK_RV -sftkdb_Update(SFTKDBHandle *handle, SECItem *key) -{ - SDBFind *find = NULL; - CK_ULONG idCount = MAX_IDS; - CK_OBJECT_HANDLE ids[MAX_IDS]; - SECItem *updatePasswordKey = NULL; - CK_RV crv, crv2; - PRBool inTransaction = PR_FALSE; - int i; - - if (handle == NULL) { - return CKR_OK; - } - if (handle->update == NULL) { - return CKR_OK; - } - - /* - * put the whole update under a transaction. This allows us to handle - * any possible race conditions between with the updateID check. - */ - crv = (*handle->db->sdb_Begin)(handle->db); - if (crv != CKR_OK) { - goto loser; - } - inTransaction = PR_TRUE; - - /* some one else has already updated this db */ - if (sftkdb_hasUpdate(sftkdb_TypeString(handle), - handle->db, handle->updateID)) { - crv = CKR_OK; - goto done; - } - - updatePasswordKey = sftkdb_GetUpdatePasswordKey(handle); - if (updatePasswordKey) { - /* pass the source DB key to the legacy code, - * so it can decrypt things */ - handle->oldKey = updatePasswordKey; - } - - /* find all the objects */ - crv = sftkdb_FindObjectsInit(handle, NULL, 0, &find); - - if (crv != CKR_OK) { - goto loser; - } - while ((crv == CKR_OK) && (idCount == MAX_IDS)) { - crv = sftkdb_FindObjects(handle, find, ids, MAX_IDS, &idCount); - for (i=0; (crv == CKR_OK) && (i < idCount); i++) { - crv = sftkdb_mergeObject(handle, ids[i], key); - } - } - crv2 = sftkdb_FindObjectsFinal(handle, find); - if (crv == CKR_OK) crv = crv2; - -loser: - /* no longer need the old key value */ - handle->oldKey = NULL; - - /* update the password - even if we didn't update objects */ - if (handle->type == SFTK_KEYDB_TYPE) { - SECItem item1, item2; - unsigned char data1[SDB_MAX_META_DATA_LEN]; - unsigned char data2[SDB_MAX_META_DATA_LEN]; - - item1.data = data1; - item1.len = sizeof(data1); - item2.data = data2; - item2.len = sizeof(data2); - - /* if the target db already has a password, skip this. */ - crv = (*handle->db->sdb_GetMetaData)(handle->db, "password", - &item1, &item2); - if (crv == CKR_OK) { - goto done; - } - - - /* nope, update it from the source */ - crv = (*handle->update->sdb_GetMetaData)(handle->update, "password", - &item1, &item2); - if (crv != CKR_OK) { - goto done; - } - crv = (*handle->db->sdb_PutMetaData)(handle->db, "password", &item1, - &item2); - if (crv != CKR_OK) { - goto done; - } - } - -done: - /* finally mark this up to date db up to date */ - /* some one else has already updated this db */ - if (crv == CKR_OK) { - crv = sftkdb_putUpdate(sftkdb_TypeString(handle), - handle->db, handle->updateID); - } - - if (inTransaction) { - if (crv == CKR_OK) { - crv = (*handle->db->sdb_Commit)(handle->db); - } else { - (*handle->db->sdb_Abort)(handle->db); - } - } - if (handle->update) { - (*handle->update->sdb_Close)(handle->update); - handle->update = NULL; - } - if (handle->updateID) { - PORT_Free(handle->updateID); - handle->updateID = NULL; - } - sftkdb_FreeUpdatePasswordKey(handle); - if (updatePasswordKey) { - SECITEM_ZfreeItem(updatePasswordKey, PR_TRUE); - } - handle->updateDBIsInit = PR_FALSE; - return crv; -} - -/****************************************************************** - * DB handle managing functions. - * - * These functions are called by softoken to initialize, acquire, - * and release database handles. - */ - -const char * -sftkdb_GetUpdateID(SFTKDBHandle *handle) -{ - return handle->updateID; -} - -/* release a database handle */ -void -sftk_freeDB(SFTKDBHandle *handle) -{ - PRInt32 ref; - - if (!handle) return; - ref = PR_AtomicDecrement(&handle->ref); - if (ref == 0) { - sftkdb_CloseDB(handle); - } - return; -} - - -/* - * acquire a database handle for a certificate db - * (database for public objects) - */ -SFTKDBHandle * -sftk_getCertDB(SFTKSlot *slot) -{ - SFTKDBHandle *dbHandle; - - PZ_Lock(slot->slotLock); - dbHandle = slot->certDB; - if (dbHandle) { - PR_AtomicIncrement(&dbHandle->ref); - } - PZ_Unlock(slot->slotLock); - return dbHandle; -} - -/* - * acquire a database handle for a key database - * (database for private objects) - */ -SFTKDBHandle * -sftk_getKeyDB(SFTKSlot *slot) -{ - SFTKDBHandle *dbHandle; - - SKIP_AFTER_FORK(PZ_Lock(slot->slotLock)); - dbHandle = slot->keyDB; - if (dbHandle) { - PR_AtomicIncrement(&dbHandle->ref); - } - SKIP_AFTER_FORK(PZ_Unlock(slot->slotLock)); - return dbHandle; -} - -/* - * acquire the database for a specific object. NOTE: objectID must point - * to a Token object! - */ -SFTKDBHandle * -sftk_getDBForTokenObject(SFTKSlot *slot, CK_OBJECT_HANDLE objectID) -{ - SFTKDBHandle *dbHandle; - - PZ_Lock(slot->slotLock); - dbHandle = objectID & SFTK_KEYDB_TYPE ? slot->keyDB : slot->certDB; - if (dbHandle) { - PR_AtomicIncrement(&dbHandle->ref); - } - PZ_Unlock(slot->slotLock); - return dbHandle; -} - -/* - * initialize a new database handle - */ -static SFTKDBHandle * -sftk_NewDBHandle(SDB *sdb, int type) -{ - SFTKDBHandle *handle = PORT_New(SFTKDBHandle); - handle->ref = 1; - handle->db = sdb; - handle->update = NULL; - handle->peerDB = NULL; - handle->newKey = NULL; - handle->oldKey = NULL; - handle->updatePasswordKey = NULL; - handle->updateID = NULL; - handle->type = type; - handle->passwordKey.data = NULL; - handle->passwordKey.len = 0; - handle->passwordLock = NULL; - if (type == SFTK_KEYDB_TYPE) { - handle->passwordLock = PZ_NewLock(nssILockAttribute); - } - sdb->app_private = handle; - return handle; -} - -/* - * reset the key database to it's uninitialized state. This call - * will clear all the key entried. - */ -SECStatus -sftkdb_ResetKeyDB(SFTKDBHandle *handle) -{ - CK_RV crv; - - /* only rest the key db */ - if (handle->type != SFTK_KEYDB_TYPE) { - return SECFailure; - } - crv = sftkdb_ResetDB(handle); - if (crv != CKR_OK) { - /* set error */ - return SECFailure; - } - return SECSuccess; -} - -static PRBool -sftk_oldVersionExists(const char *dir, int version) -{ - int i; - PRStatus exists = PR_FAILURE; - char *file = NULL; - - for (i=version; i > 1 ; i--) { - file = PR_smprintf("%s%d.db",dir,i); - if (file == NULL) { - continue; - } - exists = PR_Access(file, PR_ACCESS_EXISTS); - PR_smprintf_free(file); - if (exists == PR_SUCCESS) { - return PR_TRUE; - } - } - return PR_FALSE; -} - -static PRBool -sftk_hasLegacyDB(const char *confdir, const char *certPrefix, - const char *keyPrefix, int certVersion, int keyVersion) -{ - char *dir; - PRBool exists; - - if (certPrefix == NULL) { - certPrefix = ""; - } - - if (keyPrefix == NULL) { - keyPrefix = ""; - } - - dir= PR_smprintf("%s/%scert", confdir, certPrefix); - if (dir == NULL) { - return PR_FALSE; - } - - exists = sftk_oldVersionExists(dir, certVersion); - PR_smprintf_free(dir); - if (exists) { - return PR_TRUE; - } - - dir= PR_smprintf("%s/%skey", confdir, keyPrefix); - if (dir == NULL) { - return PR_FALSE; - } - - exists = sftk_oldVersionExists(dir, keyVersion); - PR_smprintf_free(dir); - return exists; -} - -/* - * initialize certificate and key database handles as a pair. - * - * This function figures out what type of database we are opening and - * calls the appropriate low level function to open the database. - * It also figures out whether or not to setup up automatic update. - */ -CK_RV -sftk_DBInit(const char *configdir, const char *certPrefix, - const char *keyPrefix, const char *updatedir, - const char *updCertPrefix, const char *updKeyPrefix, - const char *updateID, PRBool readOnly, PRBool noCertDB, - PRBool noKeyDB, PRBool forceOpen, - SFTKDBHandle **certDB, SFTKDBHandle **keyDB) -{ - const char *confdir; - SDBType dbType; - char *appName = NULL; - SDB *keySDB, *certSDB; - CK_RV crv = CKR_OK; - int flags = SDB_RDONLY; - PRBool newInit = PR_FALSE; - PRBool needUpdate = PR_FALSE; - - if (!readOnly) { - flags = SDB_CREATE; - } - - *certDB = NULL; - *keyDB = NULL; - - if (noKeyDB && noCertDB) { - return CKR_OK; - } - confdir = sftk_EvaluateConfigDir(configdir, &dbType, &appName); - - /* - * now initialize the appropriate database - */ - switch (dbType) { - case SDB_LEGACY: - crv = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags, - noCertDB? NULL : &certSDB, noKeyDB ? NULL: &keySDB); - break; - case SDB_MULTIACCESS: - crv = sftkdbCall_open(configdir, certPrefix, keyPrefix, 8, 3, flags, - noCertDB? NULL : &certSDB, noKeyDB ? NULL: &keySDB); - break; - case SDB_SQL: - case SDB_EXTERN: /* SHOULD open a loadable db */ - crv = s_open(confdir, certPrefix, keyPrefix, 9, 4, flags, - noCertDB? NULL : &certSDB, noKeyDB ? NULL : &keySDB, &newInit); - - /* - * if we failed to open the DB's read only, use the old ones if - * the exists. - */ - if (crv != CKR_OK) { - if ((flags == SDB_RDONLY) && - sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { - /* we have legacy databases, if we failed to open the new format - * DB's read only, just use the legacy ones */ - crv = sftkdbCall_open(confdir, certPrefix, - keyPrefix, 8, 3, flags, noCertDB? NULL : &certSDB, - noKeyDB ? NULL : &keySDB); - } - /* Handle the database merge case. - * - * For the merge case, we need help from the application. Only - * the application knows where the old database is, and what unique - * identifier it has associated with it. - * - * If the client supplies these values, we use them to determine - * if we need to update. - */ - } else if ( - /* both update params have been supplied */ - updatedir && *updatedir && updateID && *updateID - /* old dbs exist? */ - && sftk_hasLegacyDB(updatedir, updCertPrefix, updKeyPrefix, 8, 3) - /* and they have not yet been updated? */ - && ((noKeyDB || !sftkdb_hasUpdate("key", keySDB, updateID)) - || (noCertDB || !sftkdb_hasUpdate("cert", certSDB, updateID)))) { - /* we need to update */ - confdir = updatedir; - certPrefix = updCertPrefix; - keyPrefix = updKeyPrefix; - needUpdate = PR_TRUE; - } else if (newInit) { - /* if the new format DB was also a newly created DB, and we - * succeeded, then need to update that new database with data - * from the existing legacy DB */ - if (sftk_hasLegacyDB(confdir, certPrefix, keyPrefix, 8, 3)) { - needUpdate = PR_TRUE; - } - } - break; - default: - crv = CKR_GENERAL_ERROR; /* can't happen, EvaluationConfigDir MUST - * return one of the types we already - * specified. */ - } - if (crv != CKR_OK) { - goto done; - } - if (!noCertDB) { - *certDB = sftk_NewDBHandle(certSDB, SFTK_CERTDB_TYPE); - } else { - *certDB = NULL; - } - if (!noKeyDB) { - *keyDB = sftk_NewDBHandle(keySDB, SFTK_KEYDB_TYPE); - } else { - *keyDB = NULL; - } - - /* link them together */ - if (*certDB) { - (*certDB)->peerDB = *keyDB; - } - if (*keyDB) { - (*keyDB)->peerDB = *certDB; - } - - /* - * if we need to update, open the legacy database and - * mark the handle as needing update. - */ - if (needUpdate) { - SDB *updateCert = NULL; - SDB *updateKey = NULL; - CK_RV crv2; - - crv2 = sftkdbCall_open(confdir, certPrefix, keyPrefix, 8, 3, flags, - noCertDB ? NULL : &updateCert, noKeyDB ? NULL : &updateKey); - if (crv2 == CKR_OK) { - if (*certDB) { - (*certDB)->update = updateCert; - (*certDB)->updateID = updateID && *updateID - ? PORT_Strdup(updateID) : NULL; - updateCert->app_private = (*certDB); - } - if (*keyDB) { - PRBool tokenRemoved = PR_FALSE; - (*keyDB)->update = updateKey; - (*keyDB)->updateID = updateID && *updateID ? - PORT_Strdup(updateID) : NULL; - updateKey->app_private = (*keyDB); - (*keyDB)->updateDBIsInit = PR_TRUE; - (*keyDB)->updateDBIsInit = - (sftkdb_HasPasswordSet(*keyDB) == SECSuccess) ? - PR_TRUE : PR_FALSE; - /* if the password on the key db is NULL, kick off our update - * chain of events */ - sftkdb_CheckPassword((*keyDB), "", &tokenRemoved); - } else { - /* we don't have a key DB, update the certificate DB now */ - sftkdb_Update(*certDB, NULL); - } - } - } -done: - if (appName) { - PORT_Free(appName); - } - return forceOpen ? CKR_OK : crv; -} - -CK_RV -sftkdb_Shutdown(void) -{ - s_shutdown(); - sftkdbCall_Shutdown(); - return CKR_OK; -} - diff --git a/security/nss/lib/softoken/sftkdb.h b/security/nss/lib/softoken/sftkdb.h deleted file mode 100644 index 36daddea0..000000000 --- a/security/nss/lib/softoken/sftkdb.h +++ /dev/null @@ -1,118 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 - * Red Hat Inc. - * Portions created by the Initial Developer are Copyright (C) 2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "sftkdbt.h" -#include "sdb.h" -#include "pkcs11i.h" -#include "pkcs11t.h" - -/* raw database stuff */ -CK_RV sftkdb_write(SFTKDBHandle *handle, SFTKObject *,CK_OBJECT_HANDLE *); -CK_RV sftkdb_FindObjectsInit(SFTKDBHandle *sdb, const CK_ATTRIBUTE *template, - CK_ULONG count, SDBFind **find); -CK_RV sftkdb_FindObjects(SFTKDBHandle *sdb, SDBFind *find, - CK_OBJECT_HANDLE *ids, int arraySize, CK_ULONG *count); -CK_RV sftkdb_FindObjectsFinal(SFTKDBHandle *sdb, SDBFind *find); -CK_RV sftkdb_GetAttributeValue(SFTKDBHandle *handle, - CK_OBJECT_HANDLE object_id, CK_ATTRIBUTE *template, CK_ULONG count); -CK_RV sftkdb_SetAttributeValue(SFTKDBHandle *handle, SFTKObject *object, - const CK_ATTRIBUTE *template, CK_ULONG count); -CK_RV sftkdb_DestroyObject(SFTKDBHandle *handle, CK_OBJECT_HANDLE object_id); -CK_RV sftkdb_closeDB(SFTKDBHandle *handle); - - -/* secmod.db functions */ -char ** sftkdb_ReadSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *params, PRBool rw); -SECStatus sftkdb_ReleaseSecmodDBData(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char **moduleSpecList, PRBool rw); -SECStatus sftkdb_DeleteSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *args, PRBool rw); -SECStatus sftkdb_AddSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *module, PRBool rw); - -/* keydb functions */ - -SECStatus sftkdb_PWIsInitialized(SFTKDBHandle *keydb); -SECStatus sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, - PRBool *tokenRemoved); -SECStatus sftkdb_PWCached(SFTKDBHandle *keydb); -SECStatus sftkdb_HasPasswordSet(SFTKDBHandle *keydb); -SECStatus sftkdb_ResetKeyDB(SFTKDBHandle *keydb); -SECStatus sftkdb_ChangePassword(SFTKDBHandle *keydb, - char *oldPin, char *newPin, - PRBool *tokenRemoved); -SECStatus sftkdb_ClearPassword(SFTKDBHandle *keydb); -PRBool sftkdb_InUpdateMerge(SFTKDBHandle *keydb); -PRBool sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb); -const char *sftkdb_GetUpdateID(SFTKDBHandle *keydb); -SECItem *sftkdb_GetUpdatePasswordKey(SFTKDBHandle *keydb); -void sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *keydb); - -/* Utility functions */ -/* - * OK there are now lots of options here, lets go through them all: - * - * configdir - base directory where all the cert, key, and module datbases live. - * certPrefix - prefix added to the beginning of the cert database example: " - * "https-server1-" - * keyPrefix - prefix added to the beginning of the key database example: " - * "https-server1-" - * secmodName - name of the security module database (usually "secmod.db"). - * readOnly - Boolean: true if the databases are to be openned read only. - * nocertdb - Don't open the cert DB and key DB's, just initialize the - * Volatile certdb. - * nomoddb - Don't open the security module DB, just initialize the - * PKCS #11 module. - * forceOpen - Continue to force initializations even if the databases cannot - * be opened. - */ -CK_RV sftk_DBInit(const char *configdir, const char *certPrefix, - const char *keyPrefix, const char *updatedir, - const char *updCertPrefix, const char *updKeyPrefix, - const char *updateID, PRBool readOnly, PRBool noCertDB, - PRBool noKeyDB, PRBool forceOpen, - SFTKDBHandle **certDB, SFTKDBHandle **keyDB); -CK_RV sftkdb_Shutdown(void); - -SFTKDBHandle *sftk_getCertDB(SFTKSlot *slot); -SFTKDBHandle *sftk_getKeyDB(SFTKSlot *slot); -SFTKDBHandle *sftk_getDBForTokenObject(SFTKSlot *slot, - CK_OBJECT_HANDLE objectID); -void sftk_freeDB(SFTKDBHandle *certHandle); diff --git a/security/nss/lib/softoken/sftkdbt.h b/security/nss/lib/softoken/sftkdbt.h deleted file mode 100644 index f8cdb0639..000000000 --- a/security/nss/lib/softoken/sftkdbt.h +++ /dev/null @@ -1,51 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 - * Red Hat Inc. - * Portions created by the Initial Developer are Copyright (C) 2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef SFTKDBT_H -#define SFTKDBT_H 1 -typedef struct SFTKDBHandleStr SFTKDBHandle; - -#define SDB_MAX_META_DATA_LEN 256 -#define SDB_ULONG_SIZE 4 - -typedef enum { - SDB_SQL, - SDB_EXTERN, - SDB_LEGACY, - SDB_MULTIACCESS -} SDBType; - -#endif diff --git a/security/nss/lib/softoken/sftkdbti.h b/security/nss/lib/softoken/sftkdbti.h deleted file mode 100644 index efaf842cb..000000000 --- a/security/nss/lib/softoken/sftkdbti.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 - * Red Hat Inc. - * Portions created by the Initial Developer are Copyright (C) 2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef SFTKDBTI_H -#define SFTKDBTI_H 1 - -/* - * private defines - */ -struct SFTKDBHandleStr { - SDB *db; - PRInt32 ref; - CK_OBJECT_HANDLE type; - SECItem passwordKey; - SECItem *newKey; - SECItem *oldKey; - SECItem *updatePasswordKey; - PZLock *passwordLock; - SFTKDBHandle *peerDB; - SDB *update; - char *updateID; - PRBool updateDBIsInit; -}; - -#define SFTK_KEYDB_TYPE 0x40000000 -#define SFTK_CERTDB_TYPE 0x00000000 -#define SFTK_OBJ_TYPE_MASK 0xc0000000 -#define SFTK_OBJ_ID_MASK (~SFTK_OBJ_TYPE_MASK) -#define SFTK_TOKEN_TYPE 0x80000000 - -/* the following is the number of id's to handle on the stack at a time, - * it's not an upper limit of IDS that can be stored in the database */ -#define SFTK_MAX_IDS 10 - -#define SFTK_GET_SDB(handle) \ - ((handle)->update ? (handle)->update : (handle)->db) - -SECStatus sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, - SECItem **plainText); -SECStatus sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, - SECItem *plainText, SECItem **cipherText); -SECStatus sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, - CK_OBJECT_HANDLE objectID, - CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem **sigText); -SECStatus sftkdb_VerifyAttribute(SECItem *passKey, - CK_OBJECT_HANDLE objectID, - CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem *sigText); - -void sftk_ULong2SDBULong(unsigned char *data, CK_ULONG value); -CK_RV sftkdb_Update(SFTKDBHandle *handle, SECItem *key); -CK_RV sftkdb_PutAttributeSignature(SFTKDBHandle *handle, - SDB *keyTarget, CK_OBJECT_HANDLE objectID, - CK_ATTRIBUTE_TYPE type, SECItem *signText); - - - -#endif diff --git a/security/nss/lib/softoken/sftkmod.c b/security/nss/lib/softoken/sftkmod.c deleted file mode 100644 index 6ebfee5c0..000000000 --- a/security/nss/lib/softoken/sftkmod.c +++ /dev/null @@ -1,718 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following code handles the storage of PKCS 11 modules used by the - * NSS. For the rest of NSS, only one kind of database handle exists: - * - * SFTKDBHandle - * - * There is one SFTKDBHandle for the each key database and one for each cert - * database. These databases are opened as associated pairs, one pair per - * slot. SFTKDBHandles are reference counted objects. - * - * Each SFTKDBHandle points to a low level database handle (SDB). This handle - * represents the underlying physical database. These objects are not - * reference counted, an are 'owned' by their respective SFTKDBHandles. - * - * - */ -#include "sftkdb.h" -#include "sftkpars.h" -#include "prprf.h" -#include "prsystem.h" -#include "lgglue.h" -#include "secmodt.h" -#if defined (_WIN32) -#include <io.h> -#endif - -/**************************************************************** - * - * Secmod database. - * - * The new secmod database is simply a text file with each of the module - * entries. in the following form: - * - * # - * # This is a comment The next line is the library to load - * library=libmypkcs11.so - * name="My PKCS#11 module" - * params="my library's param string" - * nss="NSS parameters" - * other="parameters for other libraries and applications" - * - * library=libmynextpk11.so - * name="My other PKCS#11 module" - */ - -static char * -sftkdb_quote(const char *string, char quote) -{ - char *newString = 0; - int escapes = 0, size = 0; - const char *src; - char *dest; - - size=2; - for (src=string; *src ; src++) { - if ((*src == quote) || (*src == '\\')) escapes++; - size++; - } - - dest = newString = PORT_ZAlloc(escapes+size+1); - if (newString == NULL) { - return NULL; - } - - *dest++=quote; - for (src=string; *src; src++,dest++) { - if ((*src == '\\') || (*src == quote)) { - *dest++ = '\\'; - } - *dest = *src; - } - *dest=quote; - - return newString; -} - -/* - * Smart string cat functions. Automatically manage the memory. - * The first parameter is the source string. If it's null, we - * allocate memory for it. If it's not, we reallocate memory - * so the the concanenated string fits. - */ -static char * -sftkdb_DupnCat(char *baseString, const char *str, int str_len) -{ - int len = (baseString ? PORT_Strlen(baseString) : 0) + 1; - char *newString; - - len += str_len; - newString = (char *) PORT_Realloc(baseString,len); - if (newString == NULL) { - PORT_Free(baseString); - return NULL; - } - if (baseString == NULL) *newString = 0; - return PORT_Strncat(newString,str, str_len); -} - -/* Same as sftkdb_DupnCat except it concatenates the full string, not a - * partial one */ -static char * -sftkdb_DupCat(char *baseString, const char *str) -{ - return sftkdb_DupnCat(baseString, str, PORT_Strlen(str)); -} - -/* function to free up all the memory associated with a null terminated - * array of module specs */ -static SECStatus -sftkdb_releaseSpecList(char **moduleSpecList) -{ - if (moduleSpecList) { - char **index; - for(index = moduleSpecList; *index; index++) { - PORT_Free(*index); - } - PORT_Free(moduleSpecList); - } - return SECSuccess; -} - -#define SECMOD_STEP 10 -static SECStatus -sftkdb_growList(char ***pModuleList, int *useCount, int last) -{ - char **newModuleList; - - *useCount += SECMOD_STEP; - newModuleList = (char **)PORT_Realloc(*pModuleList, - *useCount*sizeof(char *)); - if (newModuleList == NULL) { - return SECFailure; - } - PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP); - *pModuleList = newModuleList; - return SECSuccess; -} - -static -char *sftk_getOldSecmodName(const char *dbname,const char *filename) -{ - char *file = NULL; - char *dirPath = PORT_Strdup(dbname); - char *sep; - - sep = PORT_Strrchr(dirPath,*PATH_SEPARATOR); -#ifdef WINDOWS - if (!sep) { - sep = PORT_Strrchr(dirPath,'/'); - } -#endif - if (sep) { - *(sep)=0; - } - file= PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename); - PORT_Free(dirPath); - return file; -} - -#ifdef XP_UNIX -#include <unistd.h> -#endif -#include <fcntl.h> - -/* same as fopen, except it doesn't use umask, but explicit */ -FILE * -lfopen(const char *name, const char *mode, int flags) -{ - int fd; - FILE *file; - - fd = open(name, flags, 0600); - if (fd < 0) { - return NULL; - } - file = fdopen(fd, mode); - if (!file) { - close(fd); - } - /* file inherits fd */ - return file; -} - -#define MAX_LINE_LENGTH 2048 -#define SFTK_DEFAULT_INTERNAL_INIT1 "library= name=\"NSS Internal PKCS #11 Module\" parameters=" -#define SFTK_DEFAULT_INTERNAL_INIT2 " NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={" -#define SFTK_DEFAULT_INTERNAL_INIT3 " askpw=any timeout=30})\"" - -/* - * Read all the existing modules in out of the file. - */ -char ** -sftkdb_ReadSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *params, PRBool rw) -{ - FILE *fd = NULL; - char **moduleList = NULL; - int moduleCount = 1; - int useCount = SECMOD_STEP; - char line[MAX_LINE_LENGTH]; - PRBool internal = PR_FALSE; - PRBool skipParams = PR_FALSE; - char *moduleString = NULL; - char *paramsValue=NULL; - PRBool failed = PR_TRUE; - - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_ReadSecmodDB(appName, filename, dbname, params, rw); - } - - moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **)); - if (moduleList == NULL) return NULL; - - /* do we really want to use streams here */ - fd = fopen(dbname, "r"); - if (fd == NULL) goto done; - - /* - * the following loop takes line separated config lines and colapses - * the lines to a single string, escaping and quoting as necessary. - */ - /* loop state variables */ - moduleString = NULL; /* current concatenated string */ - internal = PR_FALSE; /* is this an internal module */ - skipParams = PR_FALSE; /* did we find an override parameter block*/ - paramsValue = NULL; /* the current parameter block value */ - while (fgets(line, sizeof(line), fd) != NULL) { - int len = PORT_Strlen(line); - - /* remove the ending newline */ - if (len && line[len-1] == '\n') { - len--; - line[len] = 0; - } - if (*line == '#') { - continue; - } - if (*line != 0) { - /* - * The PKCS #11 group standard assumes blocks of strings - * separated by new lines, clumped by new lines. Internally - * we take strings separated by spaces, so we may need to escape - * certain spaces. - */ - char *value = PORT_Strchr(line,'='); - - /* there is no value, write out the stanza as is */ - if (value == NULL || value[1] == 0) { - if (moduleString) { - moduleString = sftkdb_DupnCat(moduleString," ", 1); - if (moduleString == NULL) goto loser; - } - moduleString = sftkdb_DupCat(moduleString, line); - if (moduleString == NULL) goto loser; - /* value is already quoted, just write it out */ - } else if (value[1] == '"') { - if (moduleString) { - moduleString = sftkdb_DupnCat(moduleString," ", 1); - if (moduleString == NULL) goto loser; - } - moduleString = sftkdb_DupCat(moduleString, line); - if (moduleString == NULL) goto loser; - /* we have an override parameter section, remember that - * we found this (see following comment about why this - * is necessary). */ - if (PORT_Strncasecmp(line, "parameters", 10) == 0) { - skipParams = PR_TRUE; - } - /* - * The internal token always overrides it's parameter block - * from the passed in parameters, so wait until then end - * before we include the parameter block in case we need to - * override it. NOTE: if the parameter block is quoted with ("), - * this override does not happen. This allows you to override - * the application's parameter configuration. - * - * parameter block state is controlled by the following variables: - * skipParams - Bool : set to true of we have an override param - * block (all other blocks, either implicit or explicit are - * ignored). - * paramsValue - char * : pointer to the current param block. In - * the absence of overrides, paramsValue is set to the first - * parameter block we find. All subsequent blocks are ignored. - * When we find an internal token, the application passed - * parameters take precident. - */ - } else if (PORT_Strncasecmp(line, "parameters", 10) == 0) { - /* already have parameters */ - if (paramsValue) { - continue; - } - paramsValue = sftkdb_quote(&value[1], '"'); - if (paramsValue == NULL) goto loser; - continue; - } else { - /* may need to quote */ - char *newLine; - if (moduleString) { - moduleString = sftkdb_DupnCat(moduleString," ", 1); - if (moduleString == NULL) goto loser; - } - moduleString = sftkdb_DupnCat(moduleString,line,value-line+1); - if (moduleString == NULL) goto loser; - newLine = sftkdb_quote(&value[1],'"'); - if (newLine == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString,newLine); - PORT_Free(newLine); - if (moduleString == NULL) goto loser; - } - - /* check to see if it's internal? */ - if (PORT_Strncasecmp(line, "NSS=", 4) == 0) { - /* This should be case insensitive! reviewers make - * me fix it if it's not */ - if (PORT_Strstr(line,"internal")) { - internal = PR_TRUE; - /* override the parameters */ - if (paramsValue) { - PORT_Free(paramsValue); - } - paramsValue = sftkdb_quote(params, '"'); - } - } - continue; - } - if ((moduleString == NULL) || (*moduleString == 0)) { - continue; - } - - /* - * if we are here, we have found a complete stanza. Now write out - * any param section we may have found. - */ - if (paramsValue) { - /* we had an override */ - if (!skipParams) { - moduleString = sftkdb_DupnCat(moduleString," parameters=", 12); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, paramsValue); - if (moduleString == NULL) goto loser; - } - PORT_Free(paramsValue); - paramsValue = NULL; - } - - if ((moduleCount+1) >= useCount) { - SECStatus rv; - rv = sftkdb_growList(&moduleList, &useCount, moduleCount+1); - if (rv != SECSuccess) { - goto loser; - } - } - - if (internal) { - moduleList[0] = moduleString; - } else { - moduleList[moduleCount] = moduleString; - moduleCount++; - } - moduleString = NULL; - internal = PR_FALSE; - skipParams = PR_FALSE; - } - - if (moduleString) { - PORT_Free(moduleString); - moduleString = NULL; - } -done: - /* if we couldn't open a pkcs11 database, look for the old one */ - if (fd == NULL) { - char *olddbname = sftk_getOldSecmodName(dbname,filename); - PRStatus status; - char **oldModuleList; - int i; - - /* couldn't get the old name */ - if (!olddbname) { - goto bail; - } - - /* old one doesn't exist */ - status = PR_Access(olddbname, PR_ACCESS_EXISTS); - if (status != PR_SUCCESS) { - goto bail; - } - - oldModuleList = sftkdbCall_ReadSecmodDB(appName, filename, - olddbname, params, rw); - /* old one had no modules */ - if (!oldModuleList) { - goto bail; - } - - /* count the modules */ - for (i=0; oldModuleList[i]; i++) { } - - /* grow the moduleList if necessary */ - if (i >= useCount) { - SECStatus rv; - rv = sftkdb_growList(&moduleList,&useCount,moduleCount+1); - if (rv != SECSuccess) { - goto loser; - } - } - - /* write each module out, and copy it */ - for (i=0; oldModuleList[i]; i++) { - if (rw) { - sftkdb_AddSecmodDB(dbType,appName,filename,dbname, - oldModuleList[i],rw); - } - if (moduleList[i]) { - PORT_Free(moduleList[i]); - } - moduleList[i] = PORT_Strdup(oldModuleList[i]); - } - - /* done with the old module list */ - sftkdbCall_ReleaseSecmodDBData(appName, filename, olddbname, - oldModuleList, rw); -bail: - if (olddbname) { - PR_smprintf_free(olddbname); - } - } - - if (!moduleList[0]) { - char * newParams; - moduleString = PORT_Strdup(SFTK_DEFAULT_INTERNAL_INIT1); - newParams = sftkdb_quote(params,'"'); - if (newParams == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, newParams); - PORT_Free(newParams); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, SFTK_DEFAULT_INTERNAL_INIT2); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, SECMOD_SLOT_FLAGS); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, SFTK_DEFAULT_INTERNAL_INIT3); - if (moduleString == NULL) goto loser; - moduleList[0] = moduleString; - moduleString = NULL; - } - failed = PR_FALSE; - -loser: - /* - * cleanup - */ - /* deal with trust cert db here */ - if (moduleString) { - PORT_Free(moduleString); - moduleString = NULL; - } - if (paramsValue) { - PORT_Free(paramsValue); - paramsValue = NULL; - } - if (failed || (moduleList[0] == NULL)) { - /* This is wrong! FIXME */ - sftkdb_releaseSpecList(moduleList); - moduleList = NULL; - failed = PR_TRUE; - } - if (fd != NULL) { - fclose(fd); - } else if (!failed && rw) { - /* update our internal module */ - sftkdb_AddSecmodDB(dbType,appName,filename,dbname,moduleList[0],rw); - } - return moduleList; -} - -SECStatus -sftkdb_ReleaseSecmodDBData(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char **moduleSpecList, PRBool rw) -{ - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_ReleaseSecmodDBData(appName, filename, dbname, - moduleSpecList, rw); - } - if (moduleSpecList) { - sftkdb_releaseSpecList(moduleSpecList); - } - return SECSuccess; -} - - -/* - * Delete a module from the Data Base - */ -SECStatus -sftkdb_DeleteSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *args, PRBool rw) -{ - /* SHDB_FIXME implement */ - FILE *fd = NULL; - FILE *fd2 = NULL; - char line[MAX_LINE_LENGTH]; - char *dbname2 = NULL; - char *block = NULL; - char *name = NULL; - char *lib = NULL; - int name_len, lib_len; - PRBool skip = PR_FALSE; - PRBool found = PR_FALSE; - - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw); - } - - if (!rw) { - return SECFailure; - } - - dbname2 = strdup(dbname); - if (dbname2 == NULL) goto loser; - dbname2[strlen(dbname)-1]++; - - /* do we really want to use streams here */ - fd = fopen(dbname, "r"); - if (fd == NULL) goto loser; - fd2 = lfopen(dbname2, "w+", O_CREAT|O_RDWR|O_TRUNC); - if (fd2 == NULL) goto loser; - - name = sftk_argGetParamValue("name",args); - if (name) { - name_len = PORT_Strlen(name); - } - lib = sftk_argGetParamValue("library",args); - if (lib) { - lib_len = PORT_Strlen(lib); - } - - - /* - * the following loop takes line separated config files and colapses - * the lines to a single string, escaping and quoting as necessary. - */ - /* loop state variables */ - block = NULL; - skip = PR_FALSE; - while (fgets(line, sizeof(line), fd) != NULL) { - /* If we are processing a block (we haven't hit a blank line yet */ - if (*line != '\n') { - /* skip means we are in the middle of a block we are deleting */ - if (skip) { - continue; - } - /* if we haven't found the block yet, check to see if this block - * matches our requirements */ - if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && - (PORT_Strncmp(line+5,name,name_len) == 0)) || - (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && - (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { - - /* yup, we don't need to save any more data, */ - PORT_Free(block); - block=NULL; - /* we don't need to collect more of this block */ - skip = PR_TRUE; - /* we don't need to continue searching for the block */ - found =PR_TRUE; - continue; - } - /* not our match, continue to collect data in this block */ - block = sftkdb_DupCat(block,line); - continue; - } - /* we've collected a block of data that wasn't the module we were - * looking for, write it out */ - if (block) { - fwrite(block, PORT_Strlen(block), 1, fd2); - PORT_Free(block); - block = NULL; - } - /* If we didn't just delete the this block, keep the blank line */ - if (!skip) { - fputs(line,fd2); - } - /* we are definately not in a deleted block anymore */ - skip = PR_FALSE; - } - fclose(fd); - fclose(fd2); - /* rename dbname2 to dbname */ - if (found) { - PR_Delete(dbname); - PR_Rename(dbname2,dbname); - } - PORT_Free(dbname2); - return SECSuccess; - -loser: - if (fd != NULL) { - fclose(fd); - } - if (fd2 != NULL) { - fclose(fd2); - } - if (dbname2) { - PR_Delete(dbname2); - PORT_Free(dbname2); - } - return SECFailure; -} - -/* - * Add a module to the Data base - */ -SECStatus -sftkdb_AddSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *module, PRBool rw) -{ - FILE *fd = NULL; - char *block = NULL; - PRBool libFound = PR_FALSE; - - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_AddSecmodDB(appName, filename, dbname, module, rw); - } - - /* can't write to a read only module */ - if (!rw) { - return SECFailure; - } - - /* remove the previous version if it exists */ - (void) sftkdb_DeleteSecmodDB(dbType, appName, filename, dbname, module, rw); - - fd = lfopen(dbname, "a+", O_CREAT|O_RDWR|O_APPEND); - if (fd == NULL) { - return SECFailure; - } - module = sftk_argStrip(module); - while (*module) { - int count; - char *keyEnd = PORT_Strchr(module,'='); - char *value; - - if (PORT_Strncmp(module, "library=", 8) == 0) { - libFound=PR_TRUE; - } - if (keyEnd == NULL) { - block = sftkdb_DupCat(block, module); - break; - } - value = sftk_argFetchValue(&keyEnd[1], &count); - block = sftkdb_DupnCat(block, module, keyEnd-module+1); - if (block == NULL) { goto loser; } - if (value) { - block = sftkdb_DupCat(block, sftk_argStrip(value)); - PORT_Free(value); - } - if (block == NULL) { goto loser; } - block = sftkdb_DupnCat(block, "\n", 1); - module = keyEnd + 1 + count; - module = sftk_argStrip(module); - } - if (block) { - if (!libFound) { - fprintf(fd,"library=\n"); - } - fwrite(block, PORT_Strlen(block), 1, fd); - fprintf(fd,"\n"); - PORT_Free(block); - block = NULL; - } - fclose(fd); - return SECSuccess; - -loser: - PORT_Free(block); - fclose(fd); - return SECFailure; -} - - diff --git a/security/nss/lib/softoken/sftkpars.c b/security/nss/lib/softoken/sftkpars.c deleted file mode 100644 index 014514be2..000000000 --- a/security/nss/lib/softoken/sftkpars.c +++ /dev/null @@ -1,648 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following code handles the storage of PKCS 11 modules used by the - * NSS. This file is written to abstract away how the modules are - * stored so we can deside that later. - */ -#include "sftkpars.h" -#include "pkcs11i.h" -#include "sdb.h" -#include "prprf.h" -#include "prenv.h" - -/* - * this file contains routines for parsing PKCS #11 module spec - * strings. - */ - -#define SFTK_HANDLE_STRING_ARG(param,target,value,command) \ - if (PORT_Strncasecmp(param,value,sizeof(value)-1) == 0) { \ - param += sizeof(value)-1; \ - target = sftk_argFetchValue(param,&next); \ - param += next; \ - command ;\ - } else - -#define SFTK_HANDLE_FINAL_ARG(param) \ - { param = sftk_argSkipParameter(param); } param = sftk_argStrip(param); - -static PRBool sftk_argGetPair(char c) { - switch (c) { - case '\'': return c; - case '\"': return c; - case '<': return '>'; - case '{': return '}'; - case '[': return ']'; - case '(': return ')'; - default: break; - } - return ' '; -} - -static PRBool sftk_argIsBlank(char c) { - return isspace(c); -} - -static PRBool sftk_argIsEscape(char c) { - return c == '\\'; -} - -static PRBool sftk_argIsQuote(char c) { - switch (c) { - case '\'': - case '\"': - case '<': - case '{': /* } end curly to keep vi bracket matching working */ - case '(': /* ) */ - case '[': /* ] */ return PR_TRUE; - default: break; - } - return PR_FALSE; -} - -char *sftk_argStrip(char *c) { - while (*c && sftk_argIsBlank(*c)) c++; - return c; -} - -static char * -sftk_argFindEnd(char *string) { - char endChar = ' '; - PRBool lastEscape = PR_FALSE; - - if (sftk_argIsQuote(*string)) { - endChar = sftk_argGetPair(*string); - string++; - } - - for (;*string; string++) { - if (lastEscape) { - lastEscape = PR_FALSE; - continue; - } - if (sftk_argIsEscape(*string) && !lastEscape) { - lastEscape = PR_TRUE; - continue; - } - if ((endChar == ' ') && sftk_argIsBlank(*string)) break; - if (*string == endChar) { - break; - } - } - - return string; -} - -char * -sftk_argFetchValue(char *string, int *pcount) -{ - char *end = sftk_argFindEnd(string); - char *retString, *copyString; - PRBool lastEscape = PR_FALSE; - int len; - - len = end - string; - if (len == 0) { - *pcount = 0; - return NULL; - } - - copyString = retString = (char *)PORT_Alloc(len+1); - - if (*end) len++; - *pcount = len; - if (retString == NULL) return NULL; - - - if (sftk_argIsQuote(*string)) string++; - for (; string < end; string++) { - if (sftk_argIsEscape(*string) && !lastEscape) { - lastEscape = PR_TRUE; - continue; - } - lastEscape = PR_FALSE; - *copyString++ = *string; - } - *copyString = 0; - return retString; -} - -static char * -sftk_argSkipParameter(char *string) -{ - char *end; - /* look for the end of the <name>= */ - for (;*string; string++) { - if (*string == '=') { string++; break; } - if (sftk_argIsBlank(*string)) return(string); - } - - end = sftk_argFindEnd(string); - if (*end) end++; - return end; -} - -char * -sftk_argGetParamValue(char *paramName,char *parameters) -{ - char searchValue[256]; - int paramLen = strlen(paramName); - char *returnValue = NULL; - int next; - - if ((parameters == NULL) || (*parameters == 0)) return NULL; - - PORT_Assert(paramLen+2 < sizeof(searchValue)); - - PORT_Strcpy(searchValue,paramName); - PORT_Strcat(searchValue,"="); - while (*parameters) { - if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) { - parameters += paramLen+1; - returnValue = sftk_argFetchValue(parameters,&next); - break; - } else { - parameters = sftk_argSkipParameter(parameters); - } - parameters = sftk_argStrip(parameters); - } - return returnValue; -} - -static char * -sftk_argNextFlag(char *flags) -{ - for (; *flags ; flags++) { - if (*flags == ',') { - flags++; - break; - } - } - return flags; -} - -static PRBool -sftk_argHasFlag(char *label, char *flag, char *parameters) -{ - char *flags,*index; - int len = strlen(flag); - PRBool found = PR_FALSE; - - flags = sftk_argGetParamValue(label,parameters); - if (flags == NULL) return PR_FALSE; - - for (index=flags; *index; index=sftk_argNextFlag(index)) { - if (PORT_Strncasecmp(index,flag,len) == 0) { - found=PR_TRUE; - break; - } - } - PORT_Free(flags); - return found; -} - -/* - * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal - */ -static long -sftk_argDecodeNumber(char *num) -{ - int radix = 10; - unsigned long value = 0; - long retValue = 0; - int sign = 1; - int digit; - - if (num == NULL) return retValue; - - num = sftk_argStrip(num); - - if (*num == '-') { - sign = -1; - num++; - } - - if (*num == '0') { - radix = 8; - num++; - if ((*num == 'x') || (*num == 'X')) { - radix = 16; - num++; - } - } - - - for ( ;*num; num++ ) { - if (isdigit(*num)) { - digit = *num - '0'; - } else if ((*num >= 'a') && (*num <= 'f')) { - digit = *num - 'a' + 10; - } else if ((*num >= 'A') && (*num <= 'F')) { - digit = *num - 'A' + 10; - } else { - break; - } - if (digit >= radix) break; - value = value*radix + digit; - } - - retValue = ((int) value) * sign; - return retValue; -} - -static char * -sftk_argGetName(char *inString, int *next) -{ - char *name=NULL; - char *string; - int len; - - /* look for the end of the <name>= */ - for (string = inString;*string; string++) { - if (*string == '=') { break; } - if (sftk_argIsBlank(*string)) break; - } - - len = string - inString; - - *next = len; - if (*string == '=') (*next) += 1; - if (len > 0) { - name = PORT_Alloc(len+1); - PORT_Strncpy(name,inString,len); - name[len] = 0; - } - return name; -} - -#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; } - -static void -sftk_parseTokenFlags(char *tmp, sftk_token_parameters *parsed) { - parsed->readOnly = sftk_argHasFlag("flags","readOnly",tmp); - parsed->noCertDB = sftk_argHasFlag("flags","noCertDB",tmp); - parsed->noKeyDB = sftk_argHasFlag("flags","noKeyDB",tmp); - parsed->forceOpen = sftk_argHasFlag("flags","forceOpen",tmp); - parsed->pwRequired = sftk_argHasFlag("flags","passwordRequired",tmp); - parsed->optimizeSpace = sftk_argHasFlag("flags","optimizeSpace",tmp); - return; -} - -static void -sftk_parseFlags(char *tmp, sftk_parameters *parsed) { - parsed->noModDB = sftk_argHasFlag("flags","noModDB",tmp); - parsed->readOnly = sftk_argHasFlag("flags","readOnly",tmp); - /* keep legacy interface working */ - parsed->noCertDB = sftk_argHasFlag("flags","noCertDB",tmp); - parsed->forceOpen = sftk_argHasFlag("flags","forceOpen",tmp); - parsed->pwRequired = sftk_argHasFlag("flags","passwordRequired",tmp); - parsed->optimizeSpace = sftk_argHasFlag("flags","optimizeSpace",tmp); - return; -} - -static CK_RV -sftk_parseTokenParameters(char *param, sftk_token_parameters *parsed) -{ - int next; - char *tmp; - char *index; - index = sftk_argStrip(param); - - while (*index) { - SFTK_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->updCertPrefix,"updateCertPrefix=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->updKeyPrefix,"updateKeyPrefix=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->certPrefix,"certPrefix=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyPrefix=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->tokdes,"tokenDescription=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->updtokdes, - "updateTokenDescription=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->slotdes,"slotDescription=",;) - SFTK_HANDLE_STRING_ARG(index,tmp,"minPWLen=", - if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); }) - SFTK_HANDLE_STRING_ARG(index,tmp,"flags=", - if(tmp) { sftk_parseTokenFlags(param,parsed); PORT_Free(tmp); }) - SFTK_HANDLE_FINAL_ARG(index) - } - return CKR_OK; -} - -static void -sftk_parseTokens(char *tokenParams, sftk_parameters *parsed) -{ - char *tokenIndex; - sftk_token_parameters *tokens = NULL; - int i=0,count = 0,next; - - if ((tokenParams == NULL) || (*tokenParams == 0)) return; - - /* first count the number of slots */ - for (tokenIndex = sftk_argStrip(tokenParams); *tokenIndex; - tokenIndex = sftk_argStrip(sftk_argSkipParameter(tokenIndex))) { - count++; - } - - /* get the data structures */ - tokens = (sftk_token_parameters *) - PORT_ZAlloc(count*sizeof(sftk_token_parameters)); - if (tokens == NULL) return; - - for (tokenIndex = sftk_argStrip(tokenParams), i = 0; - *tokenIndex && i < count ; i++ ) { - char *name; - name = sftk_argGetName(tokenIndex,&next); - tokenIndex += next; - - tokens[i].slotID = sftk_argDecodeNumber(name); - tokens[i].readOnly = PR_FALSE; - tokens[i].noCertDB = PR_FALSE; - tokens[i].noKeyDB = PR_FALSE; - if (!sftk_argIsBlank(*tokenIndex)) { - char *args = sftk_argFetchValue(tokenIndex,&next); - tokenIndex += next; - if (args) { - sftk_parseTokenParameters(args,&tokens[i]); - PORT_Free(args); - } - } - if (name) PORT_Free(name); - tokenIndex = sftk_argStrip(tokenIndex); - } - parsed->token_count = i; - parsed->tokens = tokens; - return; -} - -CK_RV -sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS) -{ - int next; - char *tmp; - char *index; - char *certPrefix = NULL, *keyPrefix = NULL; - char *tokdes = NULL, *ptokdes = NULL, *pupdtokdes = NULL; - char *slotdes = NULL, *pslotdes = NULL; - char *fslotdes = NULL, *ftokdes = NULL; - char *minPW = NULL; - index = sftk_argStrip(param); - - PORT_Memset(parsed, 0, sizeof(sftk_parameters)); - - while (*index) { - SFTK_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->secmodName,"secmod=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->man,"manufacturerID=",;) - SFTK_HANDLE_STRING_ARG(index,parsed->libdes,"libraryDescription=",;) - /* constructed values, used so legacy interfaces still work */ - SFTK_HANDLE_STRING_ARG(index,certPrefix,"certPrefix=",;) - SFTK_HANDLE_STRING_ARG(index,keyPrefix,"keyPrefix=",;) - SFTK_HANDLE_STRING_ARG(index,tokdes,"cryptoTokenDescription=",;) - SFTK_HANDLE_STRING_ARG(index,ptokdes,"dbTokenDescription=",;) - SFTK_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;) - SFTK_HANDLE_STRING_ARG(index,pslotdes,"dbSlotDescription=",;) - SFTK_HANDLE_STRING_ARG(index,fslotdes,"FIPSSlotDescription=",;) - SFTK_HANDLE_STRING_ARG(index,ftokdes,"FIPSTokenDescription=",;) - SFTK_HANDLE_STRING_ARG(index,pupdtokdes, "updateTokenDescription=",;) - SFTK_HANDLE_STRING_ARG(index,minPW,"minPWLen=",;) - - SFTK_HANDLE_STRING_ARG(index,tmp,"flags=", - if(tmp) { sftk_parseFlags(param,parsed); PORT_Free(tmp); }) - SFTK_HANDLE_STRING_ARG(index,tmp,"tokens=", - if(tmp) { sftk_parseTokens(tmp,parsed); PORT_Free(tmp); }) - SFTK_HANDLE_FINAL_ARG(index) - } - if (parsed->tokens == NULL) { - int count = isFIPS ? 1 : 2; - int index = count-1; - sftk_token_parameters *tokens = NULL; - - tokens = (sftk_token_parameters *) - PORT_ZAlloc(count*sizeof(sftk_token_parameters)); - if (tokens == NULL) { - goto loser; - } - parsed->tokens = tokens; - parsed->token_count = count; - tokens[index].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID; - tokens[index].certPrefix = certPrefix; - tokens[index].keyPrefix = keyPrefix; - tokens[index].minPW = minPW ? atoi(minPW) : 0; - tokens[index].readOnly = parsed->readOnly; - tokens[index].noCertDB = parsed->noCertDB; - tokens[index].noKeyDB = parsed->noCertDB; - tokens[index].forceOpen = parsed->forceOpen; - tokens[index].pwRequired = parsed->pwRequired; - tokens[index].optimizeSpace = parsed->optimizeSpace; - tokens[0].optimizeSpace = parsed->optimizeSpace; - certPrefix = NULL; - keyPrefix = NULL; - if (isFIPS) { - tokens[index].tokdes = ftokdes; - tokens[index].updtokdes = pupdtokdes; - tokens[index].slotdes = fslotdes; - fslotdes = NULL; - ftokdes = NULL; - pupdtokdes = NULL; - } else { - tokens[index].tokdes = ptokdes; - tokens[index].updtokdes = pupdtokdes; - tokens[index].slotdes = pslotdes; - tokens[0].slotID = NETSCAPE_SLOT_ID; - tokens[0].tokdes = tokdes; - tokens[0].slotdes = slotdes; - tokens[0].noCertDB = PR_TRUE; - tokens[0].noKeyDB = PR_TRUE; - pupdtokdes = NULL; - ptokdes = NULL; - pslotdes = NULL; - tokdes = NULL; - slotdes = NULL; - } - } - -loser: - FREE_CLEAR(certPrefix); - FREE_CLEAR(keyPrefix); - FREE_CLEAR(tokdes); - FREE_CLEAR(ptokdes); - FREE_CLEAR(pupdtokdes); - FREE_CLEAR(slotdes); - FREE_CLEAR(pslotdes); - FREE_CLEAR(fslotdes); - FREE_CLEAR(ftokdes); - FREE_CLEAR(minPW); - return CKR_OK; -} - -void -sftk_freeParams(sftk_parameters *params) -{ - int i; - - for (i=0; i < params->token_count; i++) { - FREE_CLEAR(params->tokens[i].configdir); - FREE_CLEAR(params->tokens[i].certPrefix); - FREE_CLEAR(params->tokens[i].keyPrefix); - FREE_CLEAR(params->tokens[i].tokdes); - FREE_CLEAR(params->tokens[i].slotdes); - FREE_CLEAR(params->tokens[i].updatedir); - FREE_CLEAR(params->tokens[i].updCertPrefix); - FREE_CLEAR(params->tokens[i].updKeyPrefix); - FREE_CLEAR(params->tokens[i].updateID); - FREE_CLEAR(params->tokens[i].updtokdes); - } - - FREE_CLEAR(params->configdir); - FREE_CLEAR(params->secmodName); - FREE_CLEAR(params->man); - FREE_CLEAR(params->libdes); - FREE_CLEAR(params->tokens); - FREE_CLEAR(params->updatedir); - FREE_CLEAR(params->updateID); -} - -#define SQLDB "sql:" -#define EXTERNDB "extern:" -#define LEGACY "dbm:" -const char * -sftk_EvaluateConfigDir(const char *configdir, SDBType *dbType, char **appName) -{ - *appName = NULL; -#ifdef NSS_DISABLE_DBM - *dbType = SDB_SQL; -#else - *dbType = SDB_LEGACY; -#endif - if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) { - char *cdir; - *dbType = SDB_MULTIACCESS; - - *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1); - if (*appName == NULL) { - return configdir; - } - cdir = *appName; - while (*cdir && *cdir != ':') { - cdir++; - } - if (*cdir == ':') { - *cdir = 0; - cdir++; - } - configdir = cdir; - } else if (PORT_Strncmp(configdir, SQLDB, sizeof(SQLDB)-1) == 0) { - *dbType = SDB_SQL; - configdir = configdir + sizeof(SQLDB) -1; - } else if (PORT_Strncmp(configdir, EXTERNDB, sizeof(EXTERNDB)-1) == 0) { - *dbType = SDB_EXTERN; - configdir = configdir + sizeof(EXTERNDB) -1; - } else if (PORT_Strncmp(configdir, LEGACY, sizeof(LEGACY)-1) == 0) { - *dbType = SDB_LEGACY; - configdir = configdir + sizeof(LEGACY) -1; - } else { - /* look up the default from the environment */ - char *defaultType = PR_GetEnv("NSS_DEFAULT_DB_TYPE"); - if (defaultType == NULL) { - /* none specified, go with the legacy */ - return configdir; - } - if (PORT_Strncmp(defaultType, SQLDB, sizeof(SQLDB)-2) == 0) { - *dbType = SDB_SQL; - } else if (PORT_Strncmp(defaultType,EXTERNDB,sizeof(EXTERNDB)-2)==0) { - *dbType = SDB_EXTERN; - } else if (PORT_Strncmp(defaultType, LEGACY, sizeof(LEGACY)-2) == 0) { - *dbType = SDB_LEGACY; - } - } - return configdir; -} - -char * -sftk_getSecmodName(char *param, SDBType *dbType, char **appName, - char **filename, PRBool *rw) -{ - int next; - char *configdir = NULL; - char *secmodName = NULL; - char *value = NULL; - char *save_params = param; - const char *lconfigdir; - param = sftk_argStrip(param); - - - while (*param) { - SFTK_HANDLE_STRING_ARG(param,configdir,"configDir=",;) - SFTK_HANDLE_STRING_ARG(param,secmodName,"secmod=",;) - SFTK_HANDLE_FINAL_ARG(param) - } - - *rw = PR_TRUE; - if (sftk_argHasFlag("flags","readOnly",save_params)) { - *rw = PR_FALSE; - } - - if (!secmodName || *secmodName == '\0') { - if (secmodName) PORT_Free(secmodName); - secmodName = PORT_Strdup(SECMOD_DB); - } - - *filename = secmodName; - lconfigdir = sftk_EvaluateConfigDir(configdir, dbType, appName); - - if (sftk_argHasFlag("flags","noModDB",save_params)) { - /* there isn't a module db, don't load the legacy support */ - *dbType = SDB_SQL; - *rw = PR_FALSE; - } - - /* only use the renamed secmod for legacy databases */ - if ((*dbType != SDB_LEGACY) && (*dbType != SDB_MULTIACCESS)) { - secmodName="pkcs11.txt"; - } - - if (lconfigdir) { - value = PR_smprintf("%s" PATH_SEPARATOR "%s",lconfigdir,secmodName); - } else { - value = PR_smprintf("%s",secmodName); - } - if (configdir) PORT_Free(configdir); - return value; -} diff --git a/security/nss/lib/softoken/sftkpars.h b/security/nss/lib/softoken/sftkpars.h deleted file mode 100644 index 0086edfba..000000000 --- a/security/nss/lib/softoken/sftkpars.h +++ /dev/null @@ -1,49 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 - * Red Hat Inc. - * Portions created by the Initial Developer are Copyright (C) 2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -#include "pkcs11i.h" -#include "sftkdbt.h" - -/* parsing functions */ -char * sftk_argFetchValue(char *string, int *pcount); -char * sftk_getSecmodName(char *param, SDBType *dbType, char **appName, char **filename,PRBool *rw); -char *sftk_argStrip(char *c); -CK_RV sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS); -void sftk_freeParams(sftk_parameters *params); -const char *sftk_EvaluateConfigDir(const char *configdir, SDBType *dbType, char **app); -char * sftk_argGetParamValue(char *paramName,char *parameters); - - - diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c deleted file mode 100644 index 4e2c36178..000000000 --- a/security/nss/lib/softoken/sftkpwd.c +++ /dev/null @@ -1,1299 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following code handles the storage of PKCS 11 modules used by the - * NSS. For the rest of NSS, only one kind of database handle exists: - * - * SFTKDBHandle - * - * There is one SFTKDBHandle for the each key database and one for each cert - * database. These databases are opened as associated pairs, one pair per - * slot. SFTKDBHandles are reference counted objects. - * - * Each SFTKDBHandle points to a low level database handle (SDB). This handle - * represents the underlying physical database. These objects are not - * reference counted, an are 'owned' by their respective SFTKDBHandles. - * - * - */ -#include "sftkdb.h" -#include "sftkdbti.h" -#include "pkcs11t.h" -#include "pkcs11i.h" -#include "sdb.h" -#include "prprf.h" -#include "secmodt.h" -#include "sftkpars.h" -#include "pratom.h" -#include "blapi.h" -#include "secoid.h" -#include "sechash.h" -#include "lowpbe.h" -#include "secdert.h" -#include "prsystem.h" -#include "lgglue.h" -#include "secerr.h" -#include "softoken.h" - -/****************************************************************** - * - * Key DB password handling functions - * - * These functions manage the key db password (set, reset, initialize, use). - * - * The key is managed on 'this side' of the database. All private data is - * encrypted before it is sent to the database itself. Besides PBE's, the - * database management code can also mix in various fixed keys so the data - * in the database is no longer considered 'plain text'. - */ - - -/* take string password and turn it into a key. The key is dependent - * on a global salt entry acquired from the database. This salted - * value will be based to a pkcs5 pbe function before it is used - * in an actual encryption */ -static SECStatus -sftkdb_passwordToKey(SFTKDBHandle *keydb, SECItem *salt, - const char *pw, SECItem *key) -{ - SHA1Context *cx = NULL; - SECStatus rv = SECFailure; - - key->data = PORT_Alloc(SHA1_LENGTH); - if (key->data == NULL) { - goto loser; - } - key->len = SHA1_LENGTH; - - cx = SHA1_NewContext(); - if ( cx == NULL) { - goto loser; - } - SHA1_Begin(cx); - if (salt && salt->data ) { - SHA1_Update(cx, salt->data, salt->len); - } - SHA1_Update(cx, (unsigned char *)pw, PORT_Strlen(pw)); - SHA1_End(cx, key->data, &key->len, key->len); - rv = SECSuccess; - -loser: - if (cx) { - SHA1_DestroyContext(cx, PR_TRUE); - } - if (rv != SECSuccess) { - if (key->data != NULL) { - PORT_ZFree(key->data,key->len); - } - key->data = NULL; - } - return rv; -} - -/* - * Cipher text stored in the database contains 3 elements: - * 1) an identifier describing the encryption algorithm. - * 2) an entry specific salt value. - * 3) the encrypted value. - * - * The following data structure represents the encrypted data in a decoded - * (but still encrypted) form. - */ -typedef struct sftkCipherValueStr sftkCipherValue; -struct sftkCipherValueStr { - PLArenaPool *arena; - SECOidTag alg; - NSSPKCS5PBEParameter *param; - SECItem salt; - SECItem value; -}; - -#define SFTK_CIPHERTEXT_VERSION 3 - -struct SFTKDBEncryptedDataInfoStr { - SECAlgorithmID algorithm; - SECItem encryptedData; -}; -typedef struct SFTKDBEncryptedDataInfoStr SFTKDBEncryptedDataInfo; - -SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) - -const SEC_ASN1Template sftkdb_EncryptedDataInfoTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SFTKDBEncryptedDataInfo) }, - { SEC_ASN1_INLINE | SEC_ASN1_XTRN , - offsetof(SFTKDBEncryptedDataInfo,algorithm), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, - { SEC_ASN1_OCTET_STRING, - offsetof(SFTKDBEncryptedDataInfo,encryptedData) }, - { 0 } -}; - -/* - * This parses the cipherText into cipher value. NOTE: cipherValue will point - * to data in cipherText, if cipherText is freed, cipherValue will be invalid. - */ -static SECStatus -sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue) -{ - PLArenaPool *arena = NULL; - SFTKDBEncryptedDataInfo edi; - SECStatus rv; - - arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) { - return SECFailure; - } - cipherValue->arena = NULL; - cipherValue->param = NULL; - - rv = SEC_QuickDERDecodeItem(arena, &edi, sftkdb_EncryptedDataInfoTemplate, - cipherText); - if (rv != SECSuccess) { - goto loser; - } - cipherValue->alg = SECOID_GetAlgorithmTag(&edi.algorithm); - cipherValue->param = nsspkcs5_AlgidToParam(&edi.algorithm); - if (cipherValue->param == NULL) { - goto loser; - } - cipherValue->value = edi.encryptedData; - cipherValue->arena = arena; - - return SECSuccess; -loser: - if (cipherValue->param) { - nsspkcs5_DestroyPBEParameter(cipherValue->param); - cipherValue->param = NULL; - } - if (arena) { - PORT_FreeArena(arena,PR_FALSE); - } - return SECFailure; -} - - - -/* - * unlike decode, Encode actually allocates a SECItem the caller must free - * The caller can pass an optional arena to to indicate where to place - * the resultant cipherText. - */ -static SECStatus -sftkdb_encodeCipherText(PLArenaPool *arena, sftkCipherValue *cipherValue, - SECItem **cipherText) -{ - SFTKDBEncryptedDataInfo edi; - SECAlgorithmID *algid; - SECStatus rv; - PLArenaPool *localArena = NULL; - - - localArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (localArena == NULL) { - return SECFailure; - } - - algid = nsspkcs5_CreateAlgorithmID(localArena, cipherValue->alg, - cipherValue->param); - if (algid == NULL) { - rv = SECFailure; - goto loser; - } - rv = SECOID_CopyAlgorithmID(localArena, &edi.algorithm, algid); - SECOID_DestroyAlgorithmID(algid, PR_TRUE); - if (rv != SECSuccess) { - goto loser; - } - edi.encryptedData = cipherValue->value; - - *cipherText = SEC_ASN1EncodeItem(arena, NULL, &edi, - sftkdb_EncryptedDataInfoTemplate); - if (*cipherText == NULL) { - rv = SECFailure; - } - -loser: - if (localArena) { - PORT_FreeArena(localArena,PR_FALSE); - } - - return rv; -} - - -/* - * Use our key to decode a cipherText block from the database. - * - * plain text is allocated by nsspkcs5_CipherData and must be freed - * with SECITEM_FreeItem by the caller. - */ -SECStatus -sftkdb_DecryptAttribute(SECItem *passKey, SECItem *cipherText, SECItem **plain) -{ - SECStatus rv; - sftkCipherValue cipherValue; - - /* First get the cipher type */ - rv = sftkdb_decodeCipherText(cipherText, &cipherValue); - if (rv != SECSuccess) { - goto loser; - } - - *plain = nsspkcs5_CipherData(cipherValue.param, passKey, &cipherValue.value, - PR_FALSE, NULL); - if (*plain == NULL) { - rv = SECFailure; - goto loser; - } - -loser: - if (cipherValue.param) { - nsspkcs5_DestroyPBEParameter(cipherValue.param); - } - if (cipherValue.arena) { - PORT_FreeArena(cipherValue.arena,PR_FALSE); - } - return rv; -} - -/* - * encrypt a block. This function returned the encrypted ciphertext which - * the caller must free. If the caller provides an arena, cipherText will - * be allocated out of that arena. This also generated the per entry - * salt automatically. - */ -SECStatus -sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, - SECItem *plainText, SECItem **cipherText) -{ - SECStatus rv; - sftkCipherValue cipherValue; - SECItem *cipher = NULL; - NSSPKCS5PBEParameter *param = NULL; - unsigned char saltData[HASH_LENGTH_MAX]; - - cipherValue.alg = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC; - cipherValue.salt.len = SHA1_LENGTH; - cipherValue.salt.data = saltData; - RNG_GenerateGlobalRandomBytes(saltData,cipherValue.salt.len); - - param = nsspkcs5_NewParam(cipherValue.alg, &cipherValue.salt, 1); - if (param == NULL) { - rv = SECFailure; - goto loser; - } - cipher = nsspkcs5_CipherData(param, passKey, plainText, PR_TRUE, NULL); - if (cipher == NULL) { - rv = SECFailure; - goto loser; - } - cipherValue.value = *cipher; - cipherValue.param = param; - - rv = sftkdb_encodeCipherText(arena, &cipherValue, cipherText); - if (rv != SECSuccess) { - goto loser; - } - -loser: - if (cipher) { - SECITEM_FreeItem(cipher, PR_TRUE); - } - if (param) { - nsspkcs5_DestroyPBEParameter(param); - } - return rv; -} - -/* - * use the password and the pbe parameters to generate an HMAC for the - * given plain text data. This is used by sftkdb_VerifyAttribute and - * sftkdb_SignAttribute. Signature is returned in signData. The caller - * must preallocate the space in the secitem. - */ -static SECStatus -sftkdb_pbehash(SECOidTag sigOid, SECItem *passKey, - NSSPKCS5PBEParameter *param, - CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem *signData) -{ - SECStatus rv = SECFailure; - SECItem *key = NULL; - HMACContext *hashCx = NULL; - HASH_HashType hashType = HASH_AlgNULL; - const SECHashObject *hashObj; - unsigned char addressData[SDB_ULONG_SIZE]; - - hashType = HASH_FromHMACOid(param->encAlg); - if (hashType == HASH_AlgNULL) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - return SECFailure; - } - - hashObj = HASH_GetRawHashObject(hashType); - if (hashObj == NULL) { - goto loser; - } - - key = nsspkcs5_ComputeKeyAndIV(param, passKey, NULL, PR_FALSE); - if (!key) { - goto loser; - } - - hashCx = HMAC_Create(hashObj, key->data, key->len, PR_TRUE); - if (!hashCx) { - goto loser; - } - HMAC_Begin(hashCx); - /* Tie this value to a particular object. This is most important for - * the trust attributes, where and attacker could copy a value for - * 'validCA' from another cert in the database */ - sftk_ULong2SDBULong(addressData, objectID); - HMAC_Update(hashCx, addressData, SDB_ULONG_SIZE); - sftk_ULong2SDBULong(addressData, attrType); - HMAC_Update(hashCx, addressData, SDB_ULONG_SIZE); - - HMAC_Update(hashCx, plainText->data, plainText->len); - rv = HMAC_Finish(hashCx, signData->data, &signData->len, signData->len); - -loser: - if (hashCx) { - HMAC_Destroy(hashCx, PR_TRUE); - } - if (key) { - SECITEM_FreeItem(key,PR_TRUE); - } - return rv; -} - -/* - * Use our key to verify a signText block from the database matches - * the plainText from the database. The signText is a PKCS 5 v2 pbe. - * plainText is the plainText of the attribute. - */ -SECStatus -sftkdb_VerifyAttribute(SECItem *passKey, CK_OBJECT_HANDLE objectID, - CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem *signText) -{ - SECStatus rv; - sftkCipherValue signValue; - SECItem signature; - unsigned char signData[HASH_LENGTH_MAX]; - - - /* First get the cipher type */ - rv = sftkdb_decodeCipherText(signText, &signValue); - if (rv != SECSuccess) { - goto loser; - } - signature.data = signData; - signature.len = sizeof(signData); - - rv = sftkdb_pbehash(signValue.alg, passKey, signValue.param, - objectID, attrType, plainText, &signature); - if (rv != SECSuccess) { - goto loser; - } - if (SECITEM_CompareItem(&signValue.value,&signature) != 0) { - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); - rv = SECFailure; - } - -loser: - if (signValue.param) { - nsspkcs5_DestroyPBEParameter(signValue.param); - } - if (signValue.arena) { - PORT_FreeArena(signValue.arena,PR_FALSE); - } - return rv; -} - -/* - * Use our key to create a signText block the plain text of an - * attribute. The signText is a PKCS 5 v2 pbe. - */ -SECStatus -sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, - CK_OBJECT_HANDLE objectID, CK_ATTRIBUTE_TYPE attrType, - SECItem *plainText, SECItem **signature) -{ - SECStatus rv; - sftkCipherValue signValue; - NSSPKCS5PBEParameter *param = NULL; - unsigned char saltData[HASH_LENGTH_MAX]; - unsigned char signData[HASH_LENGTH_MAX]; - SECOidTag hmacAlg = SEC_OID_HMAC_SHA256; /* hash for authentication */ - SECOidTag prfAlg = SEC_OID_HMAC_SHA256; /* hash for pb key generation */ - HASH_HashType prfType; - unsigned int hmacLength; - unsigned int prfLength; - - /* this code allows us to fetch the lengths and hashes on the fly - * by simply changing the OID above */ - prfType = HASH_FromHMACOid(prfAlg); - PORT_Assert(prfType != HASH_AlgNULL); - prfLength = HASH_GetRawHashObject(prfType)->length; - PORT_Assert(prfLength <= HASH_LENGTH_MAX); - - hmacLength = HASH_GetRawHashObject(HASH_FromHMACOid(hmacAlg))->length; - PORT_Assert(hmacLength <= HASH_LENGTH_MAX); - - /* initialize our CipherValue structure */ - signValue.alg = SEC_OID_PKCS5_PBMAC1; - signValue.salt.len = prfLength; - signValue.salt.data = saltData; - signValue.value.data = signData; - signValue.value.len = hmacLength; - RNG_GenerateGlobalRandomBytes(saltData,prfLength); - - /* initialize our pkcs5 paramter */ - param = nsspkcs5_NewParam(signValue.alg, &signValue.salt, 1); - if (param == NULL) { - rv = SECFailure; - goto loser; - } - param->keyID = pbeBitGenIntegrityKey; - /* set the PKCS 5 v2 parameters, not extractable from the - * data passed into nsspkcs5_NewParam */ - param->encAlg = hmacAlg; - param->hashType = prfType; - param->keyLen = hmacLength; - rv = SECOID_SetAlgorithmID(param->poolp, ¶m->prfAlg, prfAlg, NULL); - if (rv != SECSuccess) { - goto loser; - } - - - /* calculate the mac */ - rv = sftkdb_pbehash(signValue.alg, passKey, param, objectID, attrType, - plainText, &signValue.value); - if (rv != SECSuccess) { - goto loser; - } - signValue.param = param; - - /* write it out */ - rv = sftkdb_encodeCipherText(arena, &signValue, signature); - if (rv != SECSuccess) { - goto loser; - } - -loser: - if (param) { - nsspkcs5_DestroyPBEParameter(param); - } - return rv; -} - -/* - * safely swith the passed in key for the one caches in the keydb handle - * - * A key attached to the handle tells us the the token is logged in. - * We can used the key attached to the handle in sftkdb_EncryptAttribute - * and sftkdb_DecryptAttribute calls. - */ -static void -sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey) -{ - unsigned char *data; - int len; - - if (keydb->passwordLock == NULL) { - PORT_Assert(keydb->type != SFTK_KEYDB_TYPE); - return; - } - - /* an atomic pointer set would be nice */ - SKIP_AFTER_FORK(PZ_Lock(keydb->passwordLock)); - data = keydb->passwordKey.data; - len = keydb->passwordKey.len; - keydb->passwordKey.data = passKey->data; - keydb->passwordKey.len = passKey->len; - passKey->data = data; - passKey->len = len; - SKIP_AFTER_FORK(PZ_Unlock(keydb->passwordLock)); -} - -/* - * returns true if we are in a middle of a merge style update. - */ -PRBool -sftkdb_InUpdateMerge(SFTKDBHandle *keydb) -{ - return keydb->updateID ? PR_TRUE : PR_FALSE; -} - -/* - * returns true if we are looking for the password for the user's old source - * database as part of a merge style update. - */ -PRBool -sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb) -{ - if (!sftkdb_InUpdateMerge(keydb)) { - return PR_FALSE; - } - if (keydb->updateDBIsInit && !keydb->updatePasswordKey) { - return PR_TRUE; - } - return PR_FALSE; -} - -/* - * fetch an update password key from a handle. - */ -SECItem * -sftkdb_GetUpdatePasswordKey(SFTKDBHandle *handle) -{ - SECItem *key = NULL; - - /* if we're a cert db, fetch it from our peer key db */ - if (handle->type == SFTK_CERTDB_TYPE) { - handle = handle->peerDB; - } - - /* don't have one */ - if (!handle) { - return NULL; - } - - PZ_Lock(handle->passwordLock); - if (handle->updatePasswordKey) { - key = SECITEM_DupItem(handle->updatePasswordKey); - } - PZ_Unlock(handle->passwordLock); - - return key; -} - -/* - * free the update password key from a handle. - */ -void -sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle) -{ - SECItem *key = NULL; - - /* if we're a cert db, we don't have one */ - if (handle->type == SFTK_CERTDB_TYPE) { - return; - } - - /* don't have one */ - if (!handle) { - return; - } - - PZ_Lock(handle->passwordLock); - if (handle->updatePasswordKey) { - key = handle->updatePasswordKey; - handle->updatePasswordKey = NULL; - } - PZ_Unlock(handle->passwordLock); - - if (key) { - SECITEM_ZfreeItem(key, PR_TRUE); - } - - return; -} - -/* - * what password db we use depends heavily on the update state machine - * - * 1) no update db, return the normal database. - * 2) update db and no merge return the update db. - * 3) update db and in merge: - * return the update db if we need the update db's password, - * otherwise return our normal datbase. - */ -static SDB * -sftk_getPWSDB(SFTKDBHandle *keydb) -{ - if (!keydb->update) { - return keydb->db; - } - if (!sftkdb_InUpdateMerge(keydb)) { - return keydb->update; - } - if (sftkdb_NeedUpdateDBPassword(keydb)) { - return keydb->update; - } - return keydb->db; -} - -/* - * return success if we have a valid password entry. - * This is will show up outside of PKCS #11 as CKF_USER_PIN_INIT - * in the token flags. - */ -SECStatus -sftkdb_HasPasswordSet(SFTKDBHandle *keydb) -{ - SECItem salt, value; - unsigned char saltData[SDB_MAX_META_DATA_LEN]; - unsigned char valueData[SDB_MAX_META_DATA_LEN]; - CK_RV crv; - SDB *db; - - if (keydb == NULL) { - return SECFailure; - } - - db = sftk_getPWSDB(keydb); - if (db == NULL) { - return SECFailure; - } - - salt.data = saltData; - salt.len = sizeof(saltData); - value.data = valueData; - value.len = sizeof(valueData); - crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value); - return (crv == CKR_OK) ? SECSuccess : SECFailure; -} - -#define SFTK_PW_CHECK_STRING "password-check" -#define SFTK_PW_CHECK_LEN 14 - -/* - * check if the supplied password is valid - */ -SECStatus -sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw, PRBool *tokenRemoved) -{ - SECStatus rv; - SECItem salt, value; - unsigned char saltData[SDB_MAX_META_DATA_LEN]; - unsigned char valueData[SDB_MAX_META_DATA_LEN]; - SECItem key; - SECItem *result = NULL; - SDB *db; - CK_RV crv; - - if (keydb == NULL) { - return SECFailure; - } - - db = sftk_getPWSDB(keydb); - if (db == NULL) { - return SECFailure; - } - - key.data = NULL; - key.len = 0; - - if (pw == NULL) pw=""; - - /* get the entry from the database */ - salt.data = saltData; - salt.len = sizeof(saltData); - value.data = valueData; - value.len = sizeof(valueData); - crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value); - if (crv != CKR_OK) { - rv = SECFailure; - goto done; - } - - /* get our intermediate key based on the entry salt value */ - rv = sftkdb_passwordToKey(keydb, &salt, pw, &key); - if (rv != SECSuccess) { - goto done; - } - - /* decrypt the entry value */ - rv = sftkdb_DecryptAttribute(&key, &value, &result); - if (rv != SECSuccess) { - goto done; - } - - /* if it's what we expect, update our key in the database handle and - * return Success */ - if ((result->len == SFTK_PW_CHECK_LEN) && - PORT_Memcmp(result->data, SFTK_PW_CHECK_STRING, SFTK_PW_CHECK_LEN) == 0){ - /* - * We have a password, now lets handle any potential update cases.. - * - * First, the normal case: no update. In this case we only need the - * the password for our only DB, which we now have, we switch - * the keys and fall through. - * Second regular (non-merge) update: The target DB does not yet have - * a password initialized, we now have the password for the source DB, - * so we can switch the keys and simply update the target database. - * Merge update case: This one is trickier. - * 1) If we need the source DB password, then we just got it here. - * We need to save that password, - * then we need to check to see if we need or have the target - * database password. - * If we have it (it's the same as the source), or don't need - * it (it's not set or is ""), we can start the update now. - * If we don't have it, we need the application to get it from - * the user. Clear our sessions out to simulate a token - * removal. C_GetTokenInfo will change the token description - * and the token will still appear to be logged out. - * 2) If we already have the source DB password, this password is - * for the target database. We can now move forward with the - * update, as we now have both required passwords. - * - */ - PZ_Lock(keydb->passwordLock); - if (sftkdb_NeedUpdateDBPassword(keydb)) { - /* Squirrel this special key away. - * This has the side effect of turning sftkdb_NeedLegacyPW off, - * as well as changing which database is returned from - * SFTK_GET_PW_DB (thus effecting both sftkdb_CheckPassword() - * and sftkdb_HasPasswordSet()) */ - keydb->updatePasswordKey = SECITEM_DupItem(&key); - PZ_Unlock(keydb->passwordLock); - if (keydb->updatePasswordKey == NULL) { - /* PORT_Error set by SECITEM_DupItem */ - rv = SECFailure; - goto done; - } - - /* Simulate a token removal -- we need to do this any - * any case at this point so the token name is correct. */ - *tokenRemoved = PR_TRUE; - - /* - * OK, we got the update DB password, see if we need a password - * for the target... - */ - if (sftkdb_HasPasswordSet(keydb) == SECSuccess) { - /* We have a password, do we know what the password is? - * check 1) for the password the user supplied for the - * update DB, - * and 2) for the null password. - * - * RECURSION NOTE: we are calling ourselves here. This means - * any updates, switchKeys, etc will have been completed - * if these functions return successfully, in those cases - * just exit returning Success. We don't recurse infinitely - * because we are making this call from a NeedUpdateDBPassword - * block and we've already set that update password at this - * point. */ - rv = sftkdb_CheckPassword(keydb, pw, tokenRemoved); - if (rv == SECSuccess) { - /* source and target databases have the same password, we - * are good to go */ - goto done; - } - sftkdb_CheckPassword(keydb, "", tokenRemoved); - - /* - * Important 'NULL' code here. At this point either we - * succeeded in logging in with "" or we didn't. - * - * If we did succeed at login, our machine state will be set - * to logged in appropriately. The application will find that - * it's logged in as soon as it opens a new session. We have - * also completed the update. Life is good. - * - * If we did not succeed, well the user still successfully - * logged into the update database, since we faked the token - * removal it's just like the user logged into his smart card - * then removed it. the actual login work, so we report that - * success back to the user, but we won't actually be - * logged in. The application will find this out when it - * checks it's login state, thus triggering another password - * prompt so we can get the real target DB password. - * - * summary, we exit from here with SECSuccess no matter what. - */ - rv = SECSuccess; - goto done; - } else { - /* there is no password, just fall through to update. - * update will write the source DB's password record - * into the target DB just like it would in a non-merge - * update case. */ - } - } else { - PZ_Unlock(keydb->passwordLock); - } - /* load the keys, so the keydb can parse it's key set */ - sftkdb_switchKeys(keydb, &key); - - /* we need to update, do it now */ - if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update) { - /* update the peer certdb if it exists */ - if (keydb->peerDB) { - sftkdb_Update(keydb->peerDB, &key); - } - sftkdb_Update(keydb, &key); - } - } else { - rv = SECFailure; - /*PORT_SetError( bad password); */ - } - -done: - if (key.data) { - PORT_ZFree(key.data,key.len); - } - if (result) { - SECITEM_FreeItem(result,PR_TRUE); - } - return rv; -} - -/* - * return Success if the there is a cached password key. - */ -SECStatus -sftkdb_PWCached(SFTKDBHandle *keydb) -{ - return keydb->passwordKey.data ? SECSuccess : SECFailure; -} - - -static CK_RV -sftk_updateMacs(PLArenaPool *arena, SFTKDBHandle *handle, - CK_OBJECT_HANDLE id, SECItem *newKey) -{ - CK_RV crv = CKR_OK; - CK_RV crv2; - CK_ATTRIBUTE authAttrs[] = { - {CKA_MODULUS, NULL, 0}, - {CKA_PUBLIC_EXPONENT, NULL, 0}, - {CKA_CERT_SHA1_HASH, NULL, 0}, - {CKA_CERT_MD5_HASH, NULL, 0}, - {CKA_TRUST_SERVER_AUTH, NULL, 0}, - {CKA_TRUST_CLIENT_AUTH, NULL, 0}, - {CKA_TRUST_EMAIL_PROTECTION, NULL, 0}, - {CKA_TRUST_CODE_SIGNING, NULL, 0}, - {CKA_TRUST_STEP_UP_APPROVED, NULL, 0}, - {CKA_NSS_OVERRIDE_EXTENSIONS, NULL, 0}, - }; - CK_ULONG authAttrCount = sizeof(authAttrs)/sizeof(CK_ATTRIBUTE); - int i, count; - SFTKDBHandle *keyHandle = handle; - SDB *keyTarget = NULL; - - id &= SFTK_OBJ_ID_MASK; - - if (handle->type != SFTK_KEYDB_TYPE) { - keyHandle = handle->peerDB; - } - - if (keyHandle == NULL) { - return CKR_OK; - } - - /* old DB's don't have meta data, finished with MACs */ - keyTarget = SFTK_GET_SDB(keyHandle); - if ((keyTarget->sdb_flags &SDB_HAS_META) == 0) { - return CKR_OK; - } - - /* - * STEP 1: find the MACed attributes of this object - */ - crv2 = sftkdb_GetAttributeValue(handle, id, authAttrs, authAttrCount); - count = 0; - /* allocate space for the attributes */ - for (i=0; i < authAttrCount; i++) { - if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)){ - continue; - } - count++; - authAttrs[i].pValue = PORT_ArenaAlloc(arena,authAttrs[i].ulValueLen); - if (authAttrs[i].pValue == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - } - - /* if count was zero, none were found, finished with MACs */ - if (count == 0) { - return CKR_OK; - } - - crv = sftkdb_GetAttributeValue(handle, id, authAttrs, authAttrCount); - /* ignore error code, we expect some possible errors */ - - /* GetAttributeValue just verified the old macs, safe to write - * them out then... */ - for (i=0; i < authAttrCount; i++) { - SECItem *signText; - SECItem plainText; - SECStatus rv; - - if ((authAttrs[i].ulValueLen == -1) || (authAttrs[i].ulValueLen == 0)){ - continue; - } - - plainText.data = authAttrs[i].pValue; - plainText.len = authAttrs[i].ulValueLen; - rv = sftkdb_SignAttribute(arena, newKey, id, - authAttrs[i].type, &plainText, &signText); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - rv = sftkdb_PutAttributeSignature(handle, keyTarget, id, - authAttrs[i].type, signText); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - } - - return CKR_OK; -} - -static CK_RV -sftk_updateEncrypted(PLArenaPool *arena, SFTKDBHandle *keydb, - CK_OBJECT_HANDLE id, SECItem *newKey) -{ - CK_RV crv = CKR_OK; - CK_RV crv2; - CK_ATTRIBUTE *first, *last; - CK_ATTRIBUTE privAttrs[] = { - {CKA_VALUE, NULL, 0}, - {CKA_PRIVATE_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_ULONG privAttrCount = sizeof(privAttrs)/sizeof(CK_ATTRIBUTE); - int i, count; - - /* - * STEP 1. Read the old attributes in the clear. - */ - - /* Get the attribute sizes. - * ignore the error code, we will have unknown attributes here */ - crv2 = sftkdb_GetAttributeValue(keydb, id, privAttrs, privAttrCount); - - /* - * find the valid block of attributes and fill allocate space for - * their data */ - first = last = NULL; - for (i=0; i < privAttrCount; i++) { - /* find the block of attributes that are appropriate for this - * objects. There should only be once contiguous block, if not - * there's an error. - * - * find the first and last good entry. - */ - if ((privAttrs[i].ulValueLen == -1) || (privAttrs[i].ulValueLen == 0)){ - if (!first) continue; - if (!last) { - /* previous entry was last good entry */ - last= &privAttrs[i-1]; - } - continue; - } - if (!first) { - first = &privAttrs[i]; - } - if (last) { - /* OOPS, we've found another good entry beyond the end of the - * last good entry, we need to fail here. */ - crv = CKR_GENERAL_ERROR; - break; - } - privAttrs[i].pValue = PORT_ArenaAlloc(arena,privAttrs[i].ulValueLen); - if (privAttrs[i].pValue == NULL) { - crv = CKR_HOST_MEMORY; - break; - } - } - if (first == NULL) { - /* no valid entries found, return error based on crv2 */ - return crv2; - } - if (last == NULL) { - last = &privAttrs[privAttrCount-1]; - } - if (crv != CKR_OK) { - return crv; - } - /* read the attributes */ - count = (last-first)+1; - crv = sftkdb_GetAttributeValue(keydb, id, first, count); - if (crv != CKR_OK) { - return crv; - } - - /* - * STEP 2: read the encrypt the attributes with the new key. - */ - for (i=0; i < count; i++) { - SECItem plainText; - SECItem *result; - SECStatus rv; - - plainText.data = first[i].pValue; - plainText.len = first[i].ulValueLen; - rv = sftkdb_EncryptAttribute(arena, newKey, &plainText, &result); - if (rv != SECSuccess) { - return CKR_GENERAL_ERROR; - } - first[i].pValue = result->data; - first[i].ulValueLen = result->len; - /* clear our sensitive data out */ - PORT_Memset(plainText.data, 0, plainText.len); - } - - - /* - * STEP 3: write the newly encrypted attributes out directly - */ - id &= SFTK_OBJ_ID_MASK; - keydb->newKey = newKey; - crv = (*keydb->db->sdb_SetAttributeValue)(keydb->db, id, first, count); - keydb->newKey = NULL; - - return crv; -} - -static CK_RV -sftk_convertAttributes(SFTKDBHandle *handle, - CK_OBJECT_HANDLE id, SECItem *newKey) -{ - CK_RV crv = CKR_OK; - PLArenaPool *arena = NULL; - - /* get a new arena to simplify cleanup */ - arena = PORT_NewArena(1024); - if (!arena) { - return CKR_HOST_MEMORY; - } - - /* - * first handle the MACS - */ - crv = sftk_updateMacs(arena, handle, id, newKey); - if (crv != CKR_OK) { - goto loser; - } - - if (handle->type == SFTK_KEYDB_TYPE) { - crv = sftk_updateEncrypted(arena, handle, id, newKey); - if (crv != CKR_OK) { - goto loser; - } - } - - /* free up our mess */ - /* NOTE: at this point we know we've cleared out any unencrypted data */ - PORT_FreeArena(arena, PR_FALSE); - return CKR_OK; - -loser: - /* there may be unencrypted data, clear it out down */ - PORT_FreeArena(arena, PR_TRUE); - return crv; -} - - -/* - * must be called with the old key active. - */ -CK_RV -sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template, - CK_ULONG count, SECItem *newKey) -{ - SDBFind *find = NULL; - CK_ULONG idCount = SFTK_MAX_IDS; - CK_OBJECT_HANDLE ids[SFTK_MAX_IDS]; - CK_RV crv, crv2; - int i; - - crv = sftkdb_FindObjectsInit(handle, template, count, &find); - - if (crv != CKR_OK) { - return crv; - } - while ((crv == CKR_OK) && (idCount == SFTK_MAX_IDS)) { - crv = sftkdb_FindObjects(handle, find, ids, SFTK_MAX_IDS, &idCount); - for (i=0; (crv == CKR_OK) && (i < idCount); i++) { - crv = sftk_convertAttributes(handle, ids[i], newKey); - } - } - crv2 = sftkdb_FindObjectsFinal(handle, find); - if (crv == CKR_OK) crv = crv2; - - return crv; -} - - -/* - * change the database password. - */ -SECStatus -sftkdb_ChangePassword(SFTKDBHandle *keydb, - char *oldPin, char *newPin, PRBool *tokenRemoved) -{ - SECStatus rv = SECSuccess; - SECItem plainText; - SECItem newKey; - SECItem *result = NULL; - SECItem salt, value; - SFTKDBHandle *certdb; - unsigned char saltData[SDB_MAX_META_DATA_LEN]; - unsigned char valueData[SDB_MAX_META_DATA_LEN]; - CK_RV crv; - SDB *db; - - if (keydb == NULL) { - return SECFailure; - } - - db = SFTK_GET_SDB(keydb); - if (db == NULL) { - return SECFailure; - } - - newKey.data = NULL; - - /* make sure we have a valid old pin */ - crv = (*keydb->db->sdb_Begin)(keydb->db); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - salt.data = saltData; - salt.len = sizeof(saltData); - value.data = valueData; - value.len = sizeof(valueData); - crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value); - if (crv == CKR_OK) { - rv = sftkdb_CheckPassword(keydb, oldPin, tokenRemoved); - if (rv == SECFailure) { - goto loser; - } - } else { - salt.len = SHA1_LENGTH; - RNG_GenerateGlobalRandomBytes(salt.data,salt.len); - } - - rv = sftkdb_passwordToKey(keydb, &salt, newPin, &newKey); - if (rv != SECSuccess) { - goto loser; - } - - - /* - * convert encrypted entries here. - */ - crv = sftkdb_convertObjects(keydb, NULL, 0, &newKey); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - /* fix up certdb macs */ - certdb = keydb->peerDB; - if (certdb) { - CK_ATTRIBUTE objectType = { CKA_CLASS, 0, sizeof(CK_OBJECT_CLASS) }; - CK_OBJECT_CLASS myClass = CKO_NETSCAPE_TRUST; - - objectType.pValue = &myClass; - crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - myClass = CKO_PUBLIC_KEY; - crv = sftkdb_convertObjects(certdb, &objectType, 1, &newKey); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - } - - - plainText.data = (unsigned char *)SFTK_PW_CHECK_STRING; - plainText.len = SFTK_PW_CHECK_LEN; - - rv = sftkdb_EncryptAttribute(NULL, &newKey, &plainText, &result); - if (rv != SECSuccess) { - goto loser; - } - value.data = result->data; - value.len = result->len; - crv = (*keydb->db->sdb_PutMetaData)(keydb->db, "password", &salt, &value); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - crv = (*keydb->db->sdb_Commit)(keydb->db); - if (crv != CKR_OK) { - rv = SECFailure; - goto loser; - } - - keydb->newKey = NULL; - - sftkdb_switchKeys(keydb, &newKey); - -loser: - if (newKey.data) { - PORT_ZFree(newKey.data,newKey.len); - } - if (result) { - SECITEM_FreeItem(result, PR_FALSE); - } - if (rv != SECSuccess) { - (*keydb->db->sdb_Abort)(keydb->db); - } - - return rv; -} - -/* - * lose our cached password - */ -SECStatus -sftkdb_ClearPassword(SFTKDBHandle *keydb) -{ - SECItem oldKey; - oldKey.data = NULL; - oldKey.len = 0; - sftkdb_switchKeys(keydb, &oldKey); - if (oldKey.data) { - PORT_ZFree(oldKey.data, oldKey.len); - } - return SECSuccess; -} - - diff --git a/security/nss/lib/softoken/softkver.c b/security/nss/lib/softoken/softkver.c deleted file mode 100644 index 931d620e1..000000000 --- a/security/nss/lib/softoken/softkver.c +++ /dev/null @@ -1,56 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* Library identity and versioning */ - -#include "softkver.h" - -#if defined(DEBUG) -#define _DEBUG_STRING " (debug)" -#else -#define _DEBUG_STRING "" -#endif - -/* - * Version information for the 'ident' and 'what commands - * - * NOTE: the first component of the concatenated rcsid string - * must not end in a '$' to prevent rcs keyword substitution. - */ -const char __nss_softokn_rcsid[] = "$Header: NSS " SOFTOKEN_VERSION _DEBUG_STRING - " " __DATE__ " " __TIME__ " $"; -const char __nss_softokn_sccsid[] = "@(#)NSS " SOFTOKEN_VERSION _DEBUG_STRING - " " __DATE__ " " __TIME__; diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h deleted file mode 100644 index 41222fc66..000000000 --- a/security/nss/lib/softoken/softkver.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Softoken version numbers - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _SOFTKVER_H_ -#define _SOFTKVER_H_ - -#ifdef NSS_ENABLE_ECC -#ifdef NSS_ECC_MORE_THAN_SUITE_B -#define SOFTOKEN_ECC_STRING " Extended ECC" -#else -#define SOFTOKEN_ECC_STRING " Basic ECC" -#endif -#else -#define SOFTOKEN_ECC_STRING "" -#endif - -/* - * Softoken's major version, minor version, patch level, and whether - * this is a beta release. - * - * The format of the version string should be - * "<major version>.<minor version>[.<patch level>][ <ECC>][ <Beta>]" - */ -#define SOFTOKEN_VERSION "3.12.3" SOFTOKEN_ECC_STRING -#define SOFTOKEN_VMAJOR 3 -#define SOFTOKEN_VMINOR 12 -#define SOFTOKEN_VPATCH 3 -#define SOFTOKEN_BETA PR_FALSE - -#endif /* _SOFTKVER_H_ */ diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h deleted file mode 100644 index 6ef10b500..000000000 --- a/security/nss/lib/softoken/softoken.h +++ /dev/null @@ -1,385 +0,0 @@ -/* - * softoken.h - private data structures and prototypes for the softoken lib - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#ifndef _SOFTOKEN_H_ -#define _SOFTOKEN_H_ - -#include "blapi.h" -#include "lowkeyti.h" -#include "softoknt.h" -#include "secoidt.h" - -#include "pkcs11t.h" /* CK_RV Required for sftk_fipsPowerUpSelfTest(). */ - -SEC_BEGIN_PROTOS - -/* -** RSA encryption/decryption. When encrypting/decrypting the output -** buffer must be at least the size of the public key modulus. -*/ - -/* -** Format some data into a PKCS#1 encryption block, preparing the -** data for RSA encryption. -** "result" where the formatted block is stored (memory is allocated) -** "modulusLen" the size of the formatted block -** "blockType" what block type to use (SEC_RSABlock*) -** "data" the data to format -*/ -extern SECStatus RSA_FormatBlock(SECItem *result, - unsigned int modulusLen, - RSA_BlockType blockType, - SECItem *data); -/* -** Similar, but just returns a pointer to the allocated memory, *and* -** will *only* format one block, even if we (in the future) modify -** RSA_FormatBlock() to loop over multiples of modulusLen. -*/ -extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen, - RSA_BlockType blockType, - SECItem *data); - - - -/* - * convenience wrappers for doing single RSA operations. They create the - * RSA context internally and take care of the formatting - * requirements. Blinding happens automagically within RSA_Sign and - * RSA_DecryptBlock. - */ -extern -SECStatus RSA_Sign(NSSLOWKEYPrivateKey *key, unsigned char *output, - unsigned int *outputLen, unsigned int maxOutputLen, - unsigned char *input, unsigned int inputLen); -extern -SECStatus RSA_HashSign(SECOidTag hashOid, - NSSLOWKEYPrivateKey *key, unsigned char *sig, - unsigned int *sigLen, unsigned int maxLen, - unsigned char *hash, unsigned int hashLen); -extern -SECStatus RSA_CheckSign(NSSLOWKEYPublicKey *key, unsigned char *sign, - unsigned int signLength, unsigned char *hash, - unsigned int hashLength); -extern -SECStatus RSA_HashCheckSign(SECOidTag hashOid, - NSSLOWKEYPublicKey *key, unsigned char *sig, - unsigned int sigLen, unsigned char *digest, - unsigned int digestLen); -extern -SECStatus RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data, - unsigned int *data_len,unsigned int max_output_len, - unsigned char *sign, unsigned int sign_len); -extern -SECStatus RSA_EncryptBlock(NSSLOWKEYPublicKey *key, unsigned char *output, - unsigned int *outputLen, unsigned int maxOutputLen, - unsigned char *input, unsigned int inputLen); -extern -SECStatus RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, unsigned char *output, - unsigned int *outputLen, unsigned int maxOutputLen, - unsigned char *input, unsigned int inputLen); - -/* - * added to make pkcs #11 happy - * RAW is RSA_X_509 - */ -extern -SECStatus RSA_SignRaw( NSSLOWKEYPrivateKey *key, unsigned char *output, - unsigned int *output_len, unsigned int maxOutputLen, - unsigned char *input, unsigned int input_len); -extern -SECStatus RSA_CheckSignRaw( NSSLOWKEYPublicKey *key, unsigned char *sign, - unsigned int sign_len, unsigned char *hash, - unsigned int hash_len); -extern -SECStatus RSA_CheckSignRecoverRaw( NSSLOWKEYPublicKey *key, unsigned char *data, - unsigned int *data_len, unsigned int max_output_len, - unsigned char *sign, unsigned int sign_len); -extern -SECStatus RSA_EncryptRaw( NSSLOWKEYPublicKey *key, unsigned char *output, - unsigned int *output_len, - unsigned int max_output_len, - unsigned char *input, unsigned int input_len); -extern -SECStatus RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, - unsigned int *output_len, - unsigned int max_output_len, - unsigned char *input, unsigned int input_len); -#ifdef NSS_ENABLE_ECC -/* -** pepare an ECParam structure from DEREncoded params - */ -extern SECStatus EC_FillParams(PRArenaPool *arena, - const SECItem *encodedParams, ECParams *params); -extern SECStatus EC_DecodeParams(const SECItem *encodedParams, - ECParams **ecparams); -extern SECStatus EC_CopyParams(PRArenaPool *arena, ECParams *dstParams, - const ECParams *srcParams); -#endif - - -/* -** Prepare a buffer for padded CBC encryption, growing to the appropriate -** boundary, filling with the appropriate padding. -** -** blockSize must be a power of 2. -** -** We add from 1 to blockSize bytes -- we *always* grow. -** The extra bytes contain the value of the length of the padding: -** if we have 2 bytes of padding, then the padding is "0x02, 0x02". -** -** NOTE: If arena is non-NULL, we re-allocate from there, otherwise -** we assume (and use) PR memory (re)allocation. -*/ -extern unsigned char * CBC_PadBuffer(PRArenaPool *arena, unsigned char *inbuf, - unsigned int inlen, unsigned int *outlen, - int blockSize); - - -/****************************************/ -/* -** Power-Up selftests required for FIPS and invoked only -** under PKCS #11 FIPS mode. -*/ -extern CK_RV sftk_fipsPowerUpSelfTest( void ); - -/* -** make known fixed PKCS #11 key types to their sizes in bytes -*/ -unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType); - -/* -** FIPS 140-2 auditing -*/ -extern PRBool sftk_audit_enabled; - -extern void sftk_LogAuditMessage(NSSAuditSeverity severity, - NSSAuditType, const char *msg); - -extern void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phObject, CK_RV rv); - -extern void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv); - -extern void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_RV rv); - -extern void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, - CK_RV rv); - -extern void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, CK_RV rv); - -extern void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, - CK_ULONG ulCount, CK_RV rv); - -extern void sftk_AuditCryptInit(const char *opName, - CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hKey, CK_RV rv); - -extern void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); - -extern void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_ATTRIBUTE_PTR pPublicKeyTemplate, - CK_ULONG ulPublicKeyAttributeCount, - CK_ATTRIBUTE_PTR pPrivateKeyTemplate, - CK_ULONG ulPrivateKeyAttributeCount, - CK_OBJECT_HANDLE_PTR phPublicKey, - CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv); - -extern void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, - CK_BYTE_PTR pWrappedKey, - CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv); - -extern void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hUnwrappingKey, - CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); - -extern void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession, - CK_MECHANISM_PTR pMechanism, - CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, - CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); - -extern void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hKey, CK_RV rv); - -/* -** FIPS 140-2 Error state -*/ -extern PRBool sftk_fatalError; - -/* -** macros to check for forked child process after C_Initialize -*/ -#if defined(XP_UNIX) && !defined(NO_CHECK_FORK) - -#ifdef DEBUG - -#define FORK_ASSERT() \ - { \ - char* forkAssert = getenv("NSS_STRICT_NOFORK"); \ - if ( (!forkAssert) || (0 == strcmp(forkAssert, "1")) ) { \ - PORT_Assert(0); \ - } \ - } - -#else - -#define FORK_ASSERT() - -#endif - -/* we have 3 methods of implementing the fork checks : - * - Solaris "mixed" method - * - pthread_atfork method - * - getpid method - */ - -#if !defined (CHECK_FORK_MIXED) && !defined(CHECK_FORK_PTHREAD) && \ - !defined (CHECK_FORK_GETPID) - -/* Choose fork check method automatically unless specified - * This section should be updated as more platforms get pthread fixes - * to unregister fork handlers in dlclose. - */ - -#ifdef SOLARIS - -/* Solaris 8, s9 use PID checks, s10 uses pthread_atfork */ - -#define CHECK_FORK_MIXED - -#elif defined(LINUX) - -#define CHECK_FORK_PTHREAD - -#else - -/* Other Unix platforms use only PID checks. Even if pthread_atfork is - * available, the behavior of dlclose isn't guaranteed by POSIX to - * unregister the fork handler. */ - -#define CHECK_FORK_GETPID - -#endif - -#endif - -#if defined(CHECK_FORK_MIXED) - -extern PRBool usePthread_atfork; -#include <unistd.h> -extern pid_t myPid; -extern PRBool forked; - -#define PARENT_FORKED() (usePthread_atfork ? forked : (myPid && myPid != getpid())) - -#elif defined(CHECK_FORK_PTHREAD) - -extern PRBool forked; - -#define PARENT_FORKED() forked - -#elif defined(CHECK_FORK_GETPID) - -#include <unistd.h> -extern pid_t myPid; - -#define PARENT_FORKED() (myPid && myPid != getpid()) - -#endif - -extern PRBool parentForkedAfterC_Initialize; -extern PRBool sftkForkCheckDisabled; - -#define CHECK_FORK() \ - do { \ - if (!sftkForkCheckDisabled && PARENT_FORKED()) { \ - FORK_ASSERT(); \ - return CKR_DEVICE_ERROR; \ - } \ - } while (0) - -#define SKIP_AFTER_FORK(x) if (!parentForkedAfterC_Initialize) x - -#define ENABLE_FORK_CHECK() \ - { \ - char* doForkCheck = getenv("NSS_STRICT_NOFORK"); \ - if ( doForkCheck && !strcmp(doForkCheck, "DISABLED") ) { \ - sftkForkCheckDisabled = PR_TRUE; \ - } \ - } - - -#else - -/* non-Unix platforms, or fork check disabled */ - -#define CHECK_FORK() -#define SKIP_AFTER_FORK(x) x -#define ENABLE_FORK_CHECK() - -#ifndef NO_FORK_CHECK -#define NO_FORK_CHECK -#endif - -#endif - - -SEC_END_PROTOS - -#endif /* _SOFTOKEN_H_ */ diff --git a/security/nss/lib/softoken/softokn.def b/security/nss/lib/softoken/softokn.def deleted file mode 100644 index 2544d1b92..000000000 --- a/security/nss/lib/softoken/softokn.def +++ /dev/null @@ -1,61 +0,0 @@ -;+# -;+# ***** BEGIN LICENSE BLOCK ***** -;+# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -;+# -;+# 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 the Initial Developer are Copyright (C) 2000 -;+# the Initial Developer. 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 -;+# either the GNU General Public License Version 2 or later (the "GPL"), or -;+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -;+# in which case the provisions of the GPL or the LGPL are applicable instead -;+# of those above. If you wish to allow use of your version of this file only -;+# under the terms of either the GPL or the LGPL, and not to allow others to -;+# use your version of this file under the terms of the MPL, indicate your -;+# decision by deleting the provisions above and replace them with the notice -;+# and other provisions required by the GPL or the LGPL. If you do not delete -;+# the provisions above, a recipient may use your version of this file under -;+# the terms of any one of the MPL, the GPL or the LGPL. -;+# -;+# ***** END LICENSE BLOCK ***** -;+# -;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS -;+# 1. For all unix platforms, the string ";-" means "remove this line" -;+# 2. For all unix platforms, the string " DATA " will be removed from any -;+# line on which it occurs. -;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. -;+# On AIX, lines containing ";+" will be removed. -;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed. -;+# 5. For all unix platforms, after the above processing has taken place, -;+# all characters after the first ";" on the line will be removed. -;+# And for AIX, the first ";" will also be removed. -;+# This file is passed directly to windows. Since ';' is a comment, all UNIX -;+# directives are hidden behind ";", ";+", and ";-" -;+NSS_3.4 { # NSS 3.4 release -;+ global: -LIBRARY softokn3 ;- -EXPORTS ;- -C_GetFunctionList; Make this function like a real PKCS #11 module as well -FC_GetFunctionList; -NSC_GetFunctionList; -NSC_ModuleDBFunc; -;+ local: -;+ *; -;+}; diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc deleted file mode 100644 index 860155318..000000000 --- a/security/nss/lib/softoken/softokn.rc +++ /dev/null @@ -1,100 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "softkver.h" -#include <winver.h> - -#define MY_LIBNAME "softokn" -#define MY_FILEDESCRIPTION "NSS PKCS #11 Library" - -#define STRINGIZE(x) #x -#define STRINGIZE2(x) STRINGIZE(x) -#define SOFTOKEN_VMAJOR_STR STRINGIZE2(SOFTOKEN_VMAJOR) - -#ifdef _DEBUG -#define MY_DEBUG_STR " (debug)" -#define MY_FILEFLAGS_1 VS_FF_DEBUG -#else -#define MY_DEBUG_STR "" -#define MY_FILEFLAGS_1 0x0L -#endif -#if SOFTOKEN_BETA -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE -#else -#define MY_FILEFLAGS_2 MY_FILEFLAGS_1 -#endif - -#ifdef WINNT -#define MY_FILEOS VOS_NT_WINDOWS32 -#else -#define MY_FILEOS VOS__WINDOWS32 -#endif - -#define MY_INTERNAL_NAME MY_LIBNAME SOFTOKEN_VMAJOR_STR - -///////////////////////////////////////////////////////////////////////////// -// -// Version-information resource -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,0 - PRODUCTVERSION SOFTOKEN_VMAJOR,SOFTOKEN_VMINOR,SOFTOKEN_VPATCH,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK - FILEFLAGS MY_FILEFLAGS_2 - FILEOS MY_FILEOS - FILETYPE VFT_DLL - FILESUBTYPE 0x0L // not used - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904B0" // Lang=US English, CharSet=Unicode - BEGIN - VALUE "CompanyName", "Mozilla Foundation\0" - VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" - VALUE "FileVersion", SOFTOKEN_VERSION "\0" - VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" - VALUE "ProductName", "Network Security Services\0" - VALUE "ProductVersion", SOFTOKEN_VERSION "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h deleted file mode 100644 index bd5a4b529..000000000 --- a/security/nss/lib/softoken/softoknt.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * softoknt.h - public data structures for the software token library - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#ifndef _SOFTOKNT_H_ -#define _SOFTOKNT_H_ - -/* - * RSA block types - * - * The actual values are important -- they are fixed, *not* arbitrary. - * The explicit value assignments are not needed (because C would give - * us those same values anyway) but are included as a reminder... - */ -typedef enum { - RSA_BlockPrivate0 = 0, /* unused, really */ - RSA_BlockPrivate = 1, /* pad for a private-key operation */ - RSA_BlockPublic = 2, /* pad for a public-key operation */ - RSA_BlockOAEP = 3, /* use OAEP padding */ - /* XXX is this only for a public-key - operation? If so, add "Public" */ - RSA_BlockRaw = 4, /* simply justify the block appropriately */ - RSA_BlockTotal -} RSA_BlockType; - -#define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048 - -/* - * FIPS 140-2 auditing - */ -typedef enum { - NSS_AUDIT_ERROR = 3, /* errors */ - NSS_AUDIT_WARNING = 2, /* warning messages */ - NSS_AUDIT_INFO = 1 /* informational messages */ -} NSSAuditSeverity; - -typedef enum { - NSS_AUDIT_ACCESS_KEY = 0, - NSS_AUDIT_CHANGE_KEY, - NSS_AUDIT_COPY_KEY, - NSS_AUDIT_CRYPT, - NSS_AUDIT_DERIVE_KEY, - NSS_AUDIT_DESTROY_KEY, - NSS_AUDIT_DIGEST_KEY, - NSS_AUDIT_FIPS_STATE, - NSS_AUDIT_GENERATE_KEY, - NSS_AUDIT_INIT_PIN, - NSS_AUDIT_INIT_TOKEN, - NSS_AUDIT_LOAD_KEY, - NSS_AUDIT_LOGIN, - NSS_AUDIT_LOGOUT, - NSS_AUDIT_SELF_TEST, - NSS_AUDIT_SET_PIN, - NSS_AUDIT_UNWRAP_KEY, - NSS_AUDIT_WRAP_KEY, -} NSSAuditType; - -#endif /* _SOFTOKNT_H_ */ diff --git a/security/nss/lib/softoken/tlsprf.c b/security/nss/lib/softoken/tlsprf.c deleted file mode 100644 index 23e996d5f..000000000 --- a/security/nss/lib/softoken/tlsprf.c +++ /dev/null @@ -1,215 +0,0 @@ -/* tlsprf.c - TLS Pseudo Random Function (PRF) implementation - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * 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 the Initial Developer are Copyright (C) 1994-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* $Id$ */ - -#include "pkcs11i.h" -#include "blapi.h" - -#define SFTK_OFFSETOF(str, memb) ((PRPtrdiff)(&(((str *)0)->memb))) - -static void sftk_TLSPRFNull(void *data, PRBool freeit) -{ - return; -} - -typedef struct { - PRUint32 cxSize; /* size of allocated block, in bytes. */ - PRUint32 cxBufSize; /* sizeof buffer at cxBufPtr. */ - unsigned char *cxBufPtr; /* points to real buffer, may be cxBuf. */ - PRUint32 cxKeyLen; /* bytes of cxBufPtr containing key. */ - PRUint32 cxDataLen; /* bytes of cxBufPtr containing data. */ - SECStatus cxRv; /* records failure of void functions. */ - PRBool cxIsFIPS; /* true if conforming to FIPS 198. */ - unsigned char cxBuf[512]; /* actual size may be larger than 512. */ -} TLSPRFContext; - -static void -sftk_TLSPRFHashUpdate(TLSPRFContext *cx, const unsigned char *data, - unsigned int data_len) -{ - PRUint32 bytesUsed = cx->cxKeyLen + cx->cxDataLen; - - if (cx->cxRv != SECSuccess) /* function has previously failed. */ - return; - if (bytesUsed + data_len > cx->cxBufSize) { - /* We don't use realloc here because - ** (a) realloc doesn't zero out the old block, and - ** (b) if realloc fails, we lose the old block. - */ - PRUint32 newBufSize = bytesUsed + data_len + 512; - unsigned char * newBuf = (unsigned char *)PORT_Alloc(newBufSize); - if (!newBuf) { - cx->cxRv = SECFailure; - return; - } - PORT_Memcpy(newBuf, cx->cxBufPtr, bytesUsed); - if (cx->cxBufPtr != cx->cxBuf) { - PORT_ZFree(cx->cxBufPtr, bytesUsed); - } - cx->cxBufPtr = newBuf; - cx->cxBufSize = newBufSize; - } - PORT_Memcpy(cx->cxBufPtr + bytesUsed, data, data_len); - cx->cxDataLen += data_len; -} - -static void -sftk_TLSPRFEnd(TLSPRFContext *ctx, unsigned char *hashout, - unsigned int *pDigestLen, unsigned int maxDigestLen) -{ - *pDigestLen = 0; /* tells Verify that no data has been input yet. */ -} - -/* Compute the PRF values from the data previously input. */ -static SECStatus -sftk_TLSPRFUpdate(TLSPRFContext *cx, - unsigned char *sig, /* output goes here. */ - unsigned int * sigLen, /* how much output. */ - unsigned int maxLen, /* output buffer size */ - unsigned char *hash, /* unused. */ - unsigned int hashLen) /* unused. */ -{ - SECStatus rv; - SECItem sigItem; - SECItem seedItem; - SECItem secretItem; - - if (cx->cxRv != SECSuccess) - return cx->cxRv; - - secretItem.data = cx->cxBufPtr; - secretItem.len = cx->cxKeyLen; - - seedItem.data = cx->cxBufPtr + cx->cxKeyLen; - seedItem.len = cx->cxDataLen; - - sigItem.data = sig; - sigItem.len = maxLen; - - rv = TLS_PRF(&secretItem, NULL, &seedItem, &sigItem, cx->cxIsFIPS); - if (rv == SECSuccess && sigLen != NULL) - *sigLen = sigItem.len; - return rv; - -} - -static SECStatus -sftk_TLSPRFVerify(TLSPRFContext *cx, - unsigned char *sig, /* input, for comparison. */ - unsigned int sigLen, /* length of sig. */ - unsigned char *hash, /* data to be verified. */ - unsigned int hashLen) /* size of hash data. */ -{ - unsigned char * tmp = (unsigned char *)PORT_Alloc(sigLen); - unsigned int tmpLen = sigLen; - SECStatus rv; - - if (!tmp) - return SECFailure; - if (hashLen) { - /* hashLen is non-zero when the user does a one-step verify. - ** In this case, none of the data has been input yet. - */ - sftk_TLSPRFHashUpdate(cx, hash, hashLen); - } - rv = sftk_TLSPRFUpdate(cx, tmp, &tmpLen, sigLen, NULL, 0); - if (rv == SECSuccess) { - rv = (SECStatus)(1 - !PORT_Memcmp(tmp, sig, sigLen)); - } - PORT_ZFree(tmp, sigLen); - return rv; -} - -static void -sftk_TLSPRFHashDestroy(TLSPRFContext *cx, PRBool freeit) -{ - if (freeit) { - if (cx->cxBufPtr != cx->cxBuf) - PORT_ZFree(cx->cxBufPtr, cx->cxBufSize); - PORT_ZFree(cx, cx->cxSize); - } -} - -CK_RV -sftk_TLSPRFInit(SFTKSessionContext *context, - SFTKObject * key, - CK_KEY_TYPE key_type) -{ - SFTKAttribute * keyVal; - TLSPRFContext * prf_cx; - CK_RV crv = CKR_HOST_MEMORY; - PRUint32 keySize; - PRUint32 blockSize; - - if (key_type != CKK_GENERIC_SECRET) - return CKR_KEY_TYPE_INCONSISTENT; /* CKR_KEY_FUNCTION_NOT_PERMITTED */ - - context->multi = PR_TRUE; - - keyVal = sftk_FindAttribute(key, CKA_VALUE); - keySize = (!keyVal) ? 0 : keyVal->attrib.ulValueLen; - blockSize = keySize + sizeof(TLSPRFContext); - prf_cx = (TLSPRFContext *)PORT_Alloc(blockSize); - if (!prf_cx) - goto done; - prf_cx->cxSize = blockSize; - prf_cx->cxKeyLen = keySize; - prf_cx->cxDataLen = 0; - prf_cx->cxBufSize = blockSize - SFTK_OFFSETOF(TLSPRFContext, cxBuf); - prf_cx->cxRv = SECSuccess; - prf_cx->cxIsFIPS = (key->slot->slotID == FIPS_SLOT_ID); - prf_cx->cxBufPtr = prf_cx->cxBuf; - if (keySize) - PORT_Memcpy(prf_cx->cxBufPtr, keyVal->attrib.pValue, keySize); - - context->hashInfo = (void *) prf_cx; - context->cipherInfo = (void *) prf_cx; - context->hashUpdate = (SFTKHash) sftk_TLSPRFHashUpdate; - context->end = (SFTKEnd) sftk_TLSPRFEnd; - context->update = (SFTKCipher) sftk_TLSPRFUpdate; - context->verify = (SFTKVerify) sftk_TLSPRFVerify; - context->destroy = (SFTKDestroy) sftk_TLSPRFNull; - context->hashdestroy = (SFTKDestroy) sftk_TLSPRFHashDestroy; - crv = CKR_OK; - -done: - if (keyVal) - sftk_FreeAttribute(keyVal); - return crv; -} - |