diff options
author | wtchang%redhat.com <devnull@localhost> | 2006-11-21 01:55:51 +0000 |
---|---|---|
committer | wtchang%redhat.com <devnull@localhost> | 2006-11-21 01:55:51 +0000 |
commit | 6dfe7ba7c0edc7f594ad3f3e416011266324b796 (patch) | |
tree | a29c831d164adc6c39fea9353613386568d56ec9 | |
parent | b9432c7455b3523c82e9cbd6de4b0fe3f9962dc5 (diff) | |
download | nss-hg-6dfe7ba7c0edc7f594ad3f3e416011266324b796.tar.gz |
Bugzilla Bug 357333: upgraded to NSS 3.11.4.SUNBIRD_0_5_RC3
approved for 1.8 branch, a=dveditz for drivers
36 files changed, 819 insertions, 316 deletions
diff --git a/security/coreconf/WIN32.mk b/security/coreconf/WIN32.mk index e2c851201..3cc45aa7a 100644 --- a/security/coreconf/WIN32.mk +++ b/security/coreconf/WIN32.mk @@ -61,6 +61,7 @@ else RANLIB = echo BSDECHO = echo RC = rc.exe + MT = mt.exe endif ifdef BUILD_TREE diff --git a/security/coreconf/rules.mk b/security/coreconf/rules.mk index fd1a4bb6a..250da080e 100644 --- a/security/coreconf/rules.mk +++ b/security/coreconf/rules.mk @@ -275,6 +275,12 @@ $(PROGRAM): $(OBJS) $(EXTRA_LIBS) @$(MAKE_OBJDIR) ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(MKPROG) $(subst /,\\,$(OBJS)) -Fe$@ -link $(LDFLAGS) $(subst /,\\,$(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)) +ifdef MT + if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool else ifdef XP_OS2_VACPP $(MKPROG) -Fe$@ $(CFLAGS) $(OBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) @@ -329,6 +335,12 @@ ifdef NS_USE_GCC $(LINK_DLL) $(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES) else $(LINK_DLL) -MAP $(DLLBASE) $(subst /,\\,$(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES)) +ifdef MT + if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool endif else ifdef XP_OS2_VACPP @@ -367,6 +379,12 @@ $(OBJDIR)/$(PROG_PREFIX)%$(PROG_SUFFIX): $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX) ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(MKPROG) $< -Fe$@ -link \ $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) +ifdef MT + if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool else $(MKPROG) -o $@ $(CFLAGS) $< \ $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk index 8deb8a40d..be588f440 100644 --- a/security/nss/cmd/platlibs.mk +++ b/security/nss/cmd/platlibs.mk @@ -35,6 +35,43 @@ # # ***** END LICENSE BLOCK ***** +# set RPATH-type linker instructions here so they can be used in the shared +# version and in the mixed (static nss libs/shared NSPR libs) version. + +ifeq ($(OS_ARCH), SunOS) +ifeq ($(BUILD_SUN_PKG), 1) +ifeq ($(USE_64), 1) +EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1/64:/usr/lib/mps/64' +else +EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1:/usr/lib/mps' +endif +else +EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib' +endif +endif + +ifeq ($(OS_ARCH), Linux) +ifeq ($(USE_64), 1) +EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib64:$$ORIGIN/../lib' +else +EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib' +endif +endif + +ifeq ($(OS_ARCH), HP-UX) +ifeq ($(OS_TEST), ia64) +EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib' +else +# pa-risc +ifeq ($(USE_64), 1) +EXTRA_SHARED_LIBS += \ +-Wl,+b,'$$ORIGIN/../../lib/pa20_64:$$ORIGIN/../../lib/64:$$ORIGIN/../lib' +else +EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib' +endif +endif +endif + ifdef USE_STATIC_LIBS @@ -188,40 +225,6 @@ endif endif endif -ifeq ($(OS_ARCH), SunOS) -ifeq ($(BUILD_SUN_PKG), 1) -ifeq ($(USE_64), 1) -EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1/64:/usr/lib/mps/64' -else -EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1:/usr/lib/mps' -endif -else -EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib' -endif -endif - -ifeq ($(OS_ARCH), Linux) -ifeq ($(USE_64), 1) -EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib64:$$ORIGIN/../lib' -else -EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib' -endif -endif - -ifeq ($(OS_ARCH), HP-UX) -ifeq ($(OS_TEST), ia64) -EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib' -else -# pa-risc -ifeq ($(USE_64), 1) -EXTRA_SHARED_LIBS += \ --Wl,+b,'$$ORIGIN/../../lib/pa20_64:$$ORIGIN/../../lib/64:$$ORIGIN/../lib' -else -EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib' -endif -endif -endif - ifeq ($(OS_ARCH), Darwin) EXTRA_SHARED_LIBS += -dylib_file @executable_path/libsoftokn3.dylib:$(DIST)/lib/libsoftokn3.dylib endif diff --git a/security/nss/cmd/vfyserv/vfyserv.c b/security/nss/cmd/vfyserv/vfyserv.c index 3de3ea2e7..b55db11c5 100644 --- a/security/nss/cmd/vfyserv/vfyserv.c +++ b/security/nss/cmd/vfyserv/vfyserv.c @@ -86,7 +86,8 @@ static void Usage(const char *progName) { fprintf(stderr, - "Usage: %s [-p port] [-c connections] [-C cipher(s)] hostname\n", +"Usage: %s [-p port] [-c connections] [-d dbdir] [-w password]\n" +"\t\t[-C cipher(s)] hostname\n", progName); exit(1); } diff --git a/security/nss/cmd/vfyserv/vfyutil.c b/security/nss/cmd/vfyserv/vfyutil.c index 4741a22ad..038f0194a 100644 --- a/security/nss/cmd/vfyserv/vfyutil.c +++ b/security/nss/cmd/vfyserv/vfyutil.c @@ -291,10 +291,10 @@ myGetClientAuthData(void *arg, break; } secStatus = SECFailure; - break; } - CERT_FreeNicknames(names); + CERT_DestroyCertificate(cert); } /* for loop */ + CERT_FreeNicknames(names); } } diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index 933456e9a..e3bc50309 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -570,9 +570,13 @@ CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl, loser: if (options & CRL_DECODE_KEEP_BAD_CRL) { - extended->decodingError = PR_TRUE; - crl->referenceCount = 1; - return(crl); + if (extended) { + extended->decodingError = PR_TRUE; + } + if (crl) { + crl->referenceCount = 1; + return(crl); + } } if ((narena == NULL) && arena ) { diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index 3f9bcb80d..b57720d68 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -1212,30 +1212,21 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, } valid = SECSuccess ; /* start off assuming cert is valid */ -#ifdef notdef - /* check if this cert is in the Evil list */ - rv = CERT_CheckForEvilCert(cert); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - LOG_ERROR(log,cert,0,0); - return SECFailure; - } -#endif - /* make sure that the cert is valid at time t */ allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) || (requiredUsages & certificateUsageSSLServerWithStepUp)); validity = CERT_CheckCertValidTimes(cert, t, allowOverride); if ( validity != secCertTimeValid ) { - LOG_ERROR(log,cert,0,validity); - return SECFailure; + valid = SECFailure; + LOG_ERROR_OR_EXIT(log,cert,0,validity); } /* check key usage and netscape cert type */ cert_GetCertType(cert); certType = cert->nsCertType; - for (i=1;i<=certificateUsageHighest && !(SECFailure == valid && !returnedUsages) ;) { + for (i=1; i<=certificateUsageHighest && + (SECSuccess == valid || returnedUsages || log) ; ) { PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { NEXT_USAGE(); @@ -1416,6 +1407,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, NEXT_USAGE(); } +loser: return(valid); } diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c index 145751b65..fd7c6dce9 100644 --- a/security/nss/lib/certhigh/ocsp.c +++ b/security/nss/lib/certhigh/ocsp.c @@ -2806,7 +2806,6 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle, CERTOCSPCertID *certID1, CERTOCSPCertID *certID2) { PRBool match = PR_FALSE; - SECItem *foundHash = NULL; SECOidTag hashAlg; SECItem *keyHash = NULL; SECItem *nameHash = NULL; @@ -2851,17 +2850,10 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle, keyHash = &certID1->issuerMD2KeyHash; nameHash = &certID1->issuerMD2NameHash; break; - default: - foundHash = NULL; - break; - } - - if (foundHash == NULL) { - goto done; } - PORT_Assert(keyHash && nameHash); - if ((SECITEM_CompareItem(nameHash, &certID2->issuerNameHash) == SECEqual) + if ((keyHash != NULL) + && (SECITEM_CompareItem(nameHash, &certID2->issuerNameHash) == SECEqual) && (SECITEM_CompareItem(keyHash, &certID2->issuerKeyHash) == SECEqual)) { match = PR_TRUE; } diff --git a/security/nss/lib/crmf/crmfpop.c b/security/nss/lib/crmf/crmfpop.c index f728e9894..06d5f467f 100644 --- a/security/nss/lib/crmf/crmfpop.c +++ b/security/nss/lib/crmf/crmfpop.c @@ -470,6 +470,47 @@ crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey, } static SECStatus +crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac, + CRMFPOPChoice inChoice) +{ + PRArenaPool *poolp; + void *mark; + CRMFPOPOPrivKey *popoPrivKey; + CRMFProofOfPossession *pop; + SECStatus rv; + + PORT_Assert(inCertReqMsg != NULL && dhmac != NULL); + poolp = inCertReqMsg->poolp; + mark = PORT_ArenaMark(poolp); + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); + if (pop == NULL) { + goto loser; + } + pop->popUsed = inChoice; + popoPrivKey = &pop->popChoice.keyAgreement; + + rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC), + dhmac); + if (rv != SECSuccess) { + goto loser; + } + popoPrivKey->message.dhMAC.len <<= 3; + popoPrivKey->messageChoice = crmfDHMAC; + inCertReqMsg->pop = pop; + rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, + crmf_get_template_for_privkey(inChoice)); + if (rv != SECSuccess) { + goto loser; + } + PORT_ArenaUnmark(poolp, mark); + return SECSuccess; + + loser: + PORT_ArenaRelease(poolp, mark); + return SECFailure; +} + +static SECStatus crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg, CRMFSubseqMessOptions subsequentMessage, CRMFPOPChoice inChoice) @@ -578,7 +619,11 @@ CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg, crmfKeyAgreement); break; case crmfDHMAC: - /* This case should be added in the future. */ + /* In this case encPrivKey should be the calculated dhMac + * as specified in RFC 2511 */ + rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey, + crmfKeyAgreement); + break; default: rv = SECFailure; } diff --git a/security/nss/lib/crmf/crmftmpl.c b/security/nss/lib/crmf/crmftmpl.c index 594feea3e..296975c96 100644 --- a/security/nss/lib/crmf/crmftmpl.c +++ b/security/nss/lib/crmf/crmftmpl.c @@ -229,7 +229,7 @@ const SEC_ASN1Template CRMFSubsequentMessageTemplate[] = { }; const SEC_ASN1Template CRMFDHMACTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, + { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, 0, SEC_ASN1_SUB(SEC_BitStringTemplate) }, { 0 } diff --git a/security/nss/lib/crmf/respcmn.c b/security/nss/lib/crmf/respcmn.c index 54fbb3faf..14de15db8 100644 --- a/security/nss/lib/crmf/respcmn.c +++ b/security/nss/lib/crmf/respcmn.c @@ -267,14 +267,14 @@ CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair) PORT_Assert(inCertKeyPair != NULL); if (inCertKeyPair != NULL) { cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE); + if (inCertKeyPair->privateKey) { + crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); + } + if (inCertKeyPair->derPublicationInfo.data) { + PORT_Free(inCertKeyPair->derPublicationInfo.data); + } + PORT_Free(inCertKeyPair); } - if (inCertKeyPair->privateKey) { - crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); - } - if (inCertKeyPair->derPublicationInfo.data) { - PORT_Free(inCertKeyPair->derPublicationInfo.data); - } - PORT_Free(inCertKeyPair); return SECSuccess; } diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h index 5e9c3dcd1..06e3ef2ab 100644 --- a/security/nss/lib/freebl/blapi.h +++ b/security/nss/lib/freebl/blapi.h @@ -1087,6 +1087,8 @@ extern SECStatus PQG_VerifyParams(const PQGParams *params, */ extern void BL_Cleanup(void); +/* unload freebl shared library from memory */ +extern void BL_Unload(void); /************************************************************************** * Verify a given Shared library signature * diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h index 36651dada..3a01dc835 100644 --- a/security/nss/lib/freebl/ecl/ecl-curve.h +++ b/security/nss/lib/freebl/ecl/ecl-curve.h @@ -42,6 +42,10 @@ #ifndef __ecl_curve_h_ #define __ecl_curve_h_ +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#error This source file is for Basic ECC only . +#endif + static const ECCurveParams ecCurve_NIST_P256 = { "NIST-P256", ECField_GFp, 256, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c index 0aae0e6ac..2bce3bea2 100644 --- a/security/nss/lib/freebl/loader.c +++ b/security/nss/lib/freebl/loader.c @@ -187,9 +187,7 @@ static char* bl_GetOriginalPathname(const char* link) const char* softoken=SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX; -typedef struct { - PRLibrary *dlh; -} BLLibrary; +static PRLibrary* blLib; /* * Load the freebl library with the file name 'name' residing in the same @@ -224,20 +222,14 @@ bl_LoadFreeblLibInSoftokenDir(const char *softokenPath, const char *name) return dlh; } -static BLLibrary * +static PRLibrary * bl_LoadLibrary(const char *name) { - BLLibrary *lib = NULL; + PRLibrary *lib = NULL; PRFuncPtr fn_addr; char* softokenPath = NULL; PRLibSpec libSpec; - lib = PR_NEWZAP(BLLibrary); - if (NULL == lib) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - /* Get the pathname for the loaded libsoftokn, i.e. /usr/lib/libsoftokn3.so * PR_GetLibraryFilePathname works with either the base library name or a * function pointer, depending on the platform. We can't query an exported @@ -249,9 +241,9 @@ bl_LoadLibrary(const char *name) softokenPath = PR_GetLibraryFilePathname(softoken, fn_addr); if (softokenPath) { - lib->dlh = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); + lib = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); #ifdef XP_UNIX - if (!lib->dlh) { + if (!lib) { /* * If softokenPath is a symbolic link, resolve the symbolic * link and try again. @@ -260,49 +252,28 @@ bl_LoadLibrary(const char *name) if (originalSoftokenPath) { PR_Free(softokenPath); softokenPath = originalSoftokenPath; - lib->dlh = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); + lib = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); } } #endif PR_Free(softokenPath); } - if (!lib->dlh) { + if (!lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", name); #endif libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = name; - lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); + lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); } - if (NULL == lib->dlh) { + if (NULL == lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", name); #endif - PR_Free(lib); - lib = NULL; } return lib; } -static void * -bl_FindSymbol(BLLibrary *lib, const char *name) -{ - void *f; - - f = PR_FindSymbol(lib->dlh, name); - return f; -} - -static PRStatus -bl_UnloadLibrary(BLLibrary *lib) -{ - if (PR_SUCCESS != PR_UnloadLibrary(lib->dlh)) { - return PR_FAILURE; - } - PR_Free(lib); - return PR_SUCCESS; -} - #define LSB(x) ((x)&0xff) #define MSB(x) ((x)>>8) @@ -314,7 +285,7 @@ static const char *libraryName = NULL; static PRStatus freebl_LoadDSO( void ) { - BLLibrary * handle; + PRLibrary * handle; const char * name = getLibName(); if (!name) { @@ -324,7 +295,8 @@ freebl_LoadDSO( void ) handle = bl_LoadLibrary(name); if (handle) { - void * address = bl_FindSymbol(handle, "FREEBL_GetVector"); + PRFuncPtr address = PR_FindFunctionSymbol(handle, "FREEBL_GetVector"); + PRStatus status; if (address) { FREEBLGetVectorFn * getVector = (FREEBLGetVectorFn *)address; const FREEBLVector * dsoVector = getVector(); @@ -336,22 +308,26 @@ freebl_LoadDSO( void ) dsoVector->length >= sizeof(FREEBLVector)) { vector = dsoVector; libraryName = name; + blLib = handle; return PR_SUCCESS; } } } - bl_UnloadLibrary(handle); + status = PR_UnloadLibrary(handle); + PORT_Assert(PR_SUCCESS == status); } return PR_FAILURE; } +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType loadFreeBLOnce; + static PRStatus freebl_RunLoaderOnce( void ) { PRStatus status; - static PRCallOnceType once; - status = PR_CallOnce(&once, &freebl_LoadDSO); + status = PR_CallOnce(&loadFreeBLOnce, &freebl_LoadDSO); return status; } @@ -1004,6 +980,25 @@ BL_Cleanup(void) (vector->p_BL_Cleanup)(); } +void +BL_Unload(void) +{ + /* This function is not thread-safe, but doesn't need to be, because it is + * only called from functions that are also defined as not thread-safe, + * namely C_Finalize in softoken, and the SSL bypass shutdown callback called + * from NSS_Shutdown. */ + vector = NULL; + /* If an SSL socket is configured with SSL_BYPASS_PKCS11, but the application + * never does a handshake on it, BL_Unload will be called even though freebl + * was never loaded. So, don't assert blLib. */ + if (blLib) { + PRStatus status = PR_UnloadLibrary(blLib); + PORT_Assert(PR_SUCCESS == status); + blLib = NULL; + } + loadFreeBLOnce = pristineCallOnce; +} + /* ============== New for 3.003 =============================== */ SECStatus diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn index 00dac226d..8e172c426 100644 --- a/security/nss/lib/freebl/manifest.mn +++ b/security/nss/lib/freebl/manifest.mn @@ -160,6 +160,7 @@ ALL_HDRS = \ secmpi.h \ sha.h \ sha_fast.h \ + sha256.h \ shsign.h \ vis_proto.h \ $(NULL) diff --git a/security/nss/lib/freebl/os2_rand.c b/security/nss/lib/freebl/os2_rand.c index 8138d30ae..467774b8b 100644 --- a/security/nss/lib/freebl/os2_rand.c +++ b/security/nss/lib/freebl/os2_rand.c @@ -37,7 +37,8 @@ #define INCL_DOS #define INCL_DOSERRORS #include <os2.h> -#include <secrng.h> +#include "secrng.h" +#include "prerror.h" #include <stdlib.h> #include <time.h> #include <stdio.h> @@ -331,3 +332,9 @@ void RNG_FileForRNG(const char *filename) nBytes = RNG_GetNoise(buffer, 20); RNG_RandomUpdate(buffer, nBytes); } + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return 0; +} diff --git a/security/nss/lib/freebl/prng_fips1861.c b/security/nss/lib/freebl/prng_fips1861.c index c21df3ab0..50c29692e 100644 --- a/security/nss/lib/freebl/prng_fips1861.c +++ b/security/nss/lib/freebl/prng_fips1861.c @@ -46,6 +46,7 @@ #include "nssilock.h" #include "secitem.h" #include "sha_fast.h" +#include "sha256.h" #include "secrng.h" /* for RNG_GetNoise() */ #include "secmpi.h" @@ -74,8 +75,10 @@ * SHA-256, or SHA-512). */ #define FIPS_B 256 -#define B_HASH_BUF SHA256_HashBuf #define BSIZE (FIPS_B / PR_BITS_PER_BYTE) +#if BSIZE != SHA256_LENGTH +#error "this file requires that BSIZE and SHA256_LENGTH be equal" +#endif /* Output size of the G function */ #define FIPS_G 160 @@ -169,15 +172,26 @@ struct RNGContextStr { }; typedef struct RNGContextStr RNGContext; static RNGContext *globalrng = NULL; +static RNGContext theGlobalRng; /* - * Free the global RNG context + * Clean up the global RNG context */ static void freeRNGContext() { + unsigned char inputhash[BSIZE]; + SECStatus rv; + + /* destroy context lock */ PZ_DestroyLock(globalrng->lock); - PORT_ZFree(globalrng, sizeof *globalrng); + + /* zero global RNG context except for XKEY to preserve entropy */ + rv = SHA256_HashBuf(inputhash, globalrng->XKEY, BSIZE); + PORT_Assert(SECSuccess == rv); + memset(globalrng, 0, sizeof(*globalrng)); + memcpy(globalrng->XKEY, inputhash, BSIZE); + globalrng = NULL; } @@ -332,22 +346,19 @@ done: /* Use NSPR to prevent RNG_RNGInit from being called from separate * threads, creating a race condition. */ -static PRCallOnceType coRNGInit = { 0, 0, 0 }; +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType coRNGInit; static PRStatus rng_init(void) { - unsigned char bytes[120]; + unsigned char bytes[SYSTEM_RNG_SEED_COUNT]; unsigned int numBytes; if (globalrng == NULL) { /* create a new global RNG context */ - globalrng = (RNGContext *)PORT_ZAlloc(sizeof(RNGContext)); - if (globalrng == NULL) { - PORT_SetError(PR_OUT_OF_MEMORY_ERROR); - return PR_FAILURE; - } + globalrng = &theGlobalRng; + PORT_Assert(NULL == globalrng->lock); /* create a lock for it */ globalrng->lock = PZ_NewLock(nssILockOther); if (globalrng->lock == NULL) { - PORT_Free(globalrng); globalrng = NULL; PORT_SetError(PR_OUT_OF_MEMORY_ERROR); return PR_FAILURE; @@ -355,6 +366,18 @@ static PRStatus rng_init(void) /* the RNG is in a valid state */ globalrng->isValid = PR_TRUE; /* Try to get some seed data for the RNG */ + numBytes = RNG_SystemRNG(bytes, sizeof bytes); + PORT_Assert(numBytes == 0 || numBytes == sizeof bytes); + if (numBytes != 0) { + RNG_RandomUpdate(bytes, numBytes); + memset(bytes, 0, numBytes); + } else if (PORT_GetError() != PR_NOT_IMPLEMENTED_ERROR) { + PZ_DestroyLock(globalrng->lock); + globalrng->lock = NULL; + globalrng->isValid = PR_FALSE; + globalrng = NULL; + return PR_FAILURE; + } numBytes = RNG_GetNoise(bytes, sizeof bytes); RNG_RandomUpdate(bytes, numBytes); } @@ -387,7 +410,6 @@ static SECStatus prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) { SECStatus rv = SECSuccess; - unsigned char inputhash[BSIZE]; /* check for a valid global RNG context */ PORT_Assert(rng != NULL); if (rng == NULL) { @@ -397,17 +419,6 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) /* RNG_SystemInfoForRNG() sometimes does this, not really an error */ if (bytes == 0) return SECSuccess; - /* If received 20 bytes of input, use it, else hash the input before - * locking. - */ - if (bytes == BSIZE) - memcpy(inputhash, data, BSIZE); - else - rv = B_HASH_BUF(inputhash, data, bytes); - if (rv != SECSuccess) { - /* B_HASH_BUF set error */ - return SECFailure; - } /* --- LOCKED --- */ PZ_Lock(rng->lock); /* @@ -417,20 +428,17 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) * Algorithm 1 of FIPS 186-2 Change Notice 1, step 1 specifies that * a secret value for the seed-key must be chosen before the * generator can begin. The size of XKEY is b bits, so fill it - * with the first b bits sent to RNG_RandomUpdate(). + * with the b-bit hash of the input to the first RNG_RandomUpdate() + * call. */ if (rng->seedCount == 0) { /* This is the first call to RandomUpdate(). Use a hash - * of the input to set the seed, XKEY. + * of the input to set the seed-key, XKEY. * - * <Step 1> copy seed bytes into context's XKEY - */ - memcpy(rng->XKEY, inputhash, BSIZE); - /* - * Now continue with algorithm. Since the input was used to - * initialize XKEY, the "optional user input" at this stage - * will be a pad of zeros, XSEEDj = 0. + * <Step 1> copy hash of seed bytes into context's XKEY */ + SHA256_HashBuf(rng->XKEY, data, bytes); + /* Now continue with algorithm. */ rv = alg_fips186_2_cn_1(rng, NULL); /* As per FIPS 140-2 continuous RNG test requirement, the first * iteration of output is discarded. So here there is really @@ -438,17 +446,28 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) * before any bytes can be extracted from the generator. */ rng->avail = 0; + } else if (bytes == BSIZE && memcmp(rng->XKEY, data, BSIZE) == 0) { + /* Should we add the error code SEC_ERROR_BAD_RNG_SEED? */ + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; } else { - /* Execute the algorithm from FIPS 186-2 Change Notice 1 */ - rv = alg_fips186_2_cn_1(rng, inputhash); + /* + * FIPS 186-2 does not specify how to reseed the RNG. We retrofit + * our RNG with a reseed function from NIST SP 800-90. + * + * Use a hash of the seed-key and the input to reseed the RNG. + */ + SHA256Context ctx; + SHA256_Begin(&ctx); + SHA256_Update(&ctx, rng->XKEY, BSIZE); + SHA256_Update(&ctx, data, bytes); + SHA256_End(&ctx, rng->XKEY, NULL, BSIZE); } /* If got this far, have added bytes of seed data. */ if (rv == SECSuccess) rng->seedCount += bytes; PZ_Unlock(rng->lock); /* --- UNLOCKED --- */ - /* housekeeping */ - memset(inputhash, 0, BSIZE); return rv; } @@ -466,7 +485,7 @@ RNG_RandomUpdate(const void *data, size_t bytes) ** Generate some random bytes, using the global random number generator ** object. */ -SECStatus +static SECStatus prng_GenerateGlobalRandomBytes(RNGContext *rng, void *dest, size_t len) { @@ -538,8 +557,8 @@ RNG_RNGShutdown(void) } /* clear */ freeRNGContext(); - /* zero the callonce struct to allow a new call to RNG_RNGInit() */ - memset(&coRNGInit, 0, sizeof coRNGInit); + /* reset the callonce struct to allow a new call to RNG_RNGInit() */ + coRNGInit = pristineCallOnce; } /* diff --git a/security/nss/lib/freebl/secrng.h b/security/nss/lib/freebl/secrng.h index d3e97c927..036a3f71a 100644 --- a/security/nss/lib/freebl/secrng.h +++ b/security/nss/lib/freebl/secrng.h @@ -51,11 +51,14 @@ #include "blapi.h" +/* the number of bytes to read from the system random number generator */ +#define SYSTEM_RNG_SEED_COUNT 1024 + SEC_BEGIN_PROTOS /* -** The following 3 functions are provided by the security library -** but are differently implemented for the UNIX, Mac and Win +** The following functions are provided by the security library +** but are differently implemented for the UNIX, Win, and OS/2 ** versions */ @@ -80,6 +83,17 @@ extern void RNG_SystemInfoForRNG(void); */ extern void RNG_FileForRNG(const char *filename); +/* +** Get maxbytes bytes of random data from the system random number +** generator. +** Returns the number of bytes copied into buf -- maxbytes if success +** or zero if error. +** Errors: +** PR_NOT_IMPLEMENTED_ERROR There is no system RNG on the platform. +** SEC_ERROR_NEED_RANDOM The system RNG failed. +*/ +extern size_t RNG_SystemRNG(void *buf, size_t maxbytes); + SEC_END_PROTOS #endif /* _SECRNG_H_ */ diff --git a/security/nss/lib/freebl/sha512.c b/security/nss/lib/freebl/sha512.c index 672aa9a0f..a25b83d6d 100644 --- a/security/nss/lib/freebl/sha512.c +++ b/security/nss/lib/freebl/sha512.c @@ -45,6 +45,7 @@ #include "prtypes.h" /* for PRUintXX */ #include "secport.h" /* for PORT_XXX */ #include "blapi.h" +#include "sha256.h" /* for struct SHA256ContextStr */ /* ============= Common constants and defines ======================= */ @@ -92,15 +93,6 @@ static const PRUint32 H256[8] = { 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; -struct SHA256ContextStr { - union { - PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */ - PRUint8 b[256]; - } u; - PRUint32 h[8]; /* 8 state variables */ - PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */ -}; - #if defined(_MSC_VER) && defined(_X86_) #ifndef FORCEINLINE #if (MSC_VER >= 1200) diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c index a3afe5da9..13617b1e7 100644 --- a/security/nss/lib/freebl/unix_rand.c +++ b/security/nss/lib/freebl/unix_rand.c @@ -43,8 +43,9 @@ #include <sys/time.h> #include <sys/wait.h> #include <sys/stat.h> -#include <assert.h> #include "secrng.h" +#include "secerr.h" +#include "prerror.h" size_t RNG_FileUpdate(const char *fileName, size_t limit); @@ -379,7 +380,7 @@ GiveSystemInfo(void) #endif /* IBM R2 */ #if defined(LINUX) -#include <linux/kernel.h> +#include <sys/sysinfo.h> static size_t GetHighResClock(void *buf, size_t maxbytes) @@ -390,14 +391,10 @@ GetHighResClock(void *buf, size_t maxbytes) static void GiveSystemInfo(void) { - /* XXX sysinfo() does not seem be implemented anywhwere */ -#if 0 struct sysinfo si; - char hn[2000]; if (sysinfo(&si) == 0) { RNG_RandomUpdate(&si, sizeof(si)); } -#endif } #endif /* LINUX */ @@ -949,13 +946,13 @@ for the small amount of entropy it provides. } /* Give in system information */ - if (gethostname(buf, sizeof(buf)) > 0) { + if (gethostname(buf, sizeof(buf)) == 0) { RNG_RandomUpdate(buf, strlen(buf)); } GiveSystemInfo(); /* grab some data from system's PRNG before any other files. */ - bytes = RNG_FileUpdate("/dev/urandom", 1024); + bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT); /* If the user points us to a random file, pass it through the rng */ randfile = getenv("NSRANDFILE"); @@ -1130,3 +1127,31 @@ void RNG_FileForRNG(const char *fileName) { RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); } + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + FILE *file; + size_t bytes; + size_t fileBytes = 0; + unsigned char *buffer = dest; + + file = fopen("/dev/urandom", "r"); + if (file == NULL) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return fileBytes; + } + while (maxLen > fileBytes) { + bytes = maxLen - fileBytes; + bytes = fread(buffer, 1, bytes, file); + if (bytes == 0) + break; + fileBytes += bytes; + buffer += bytes; + } + fclose(file); + if (fileBytes != maxLen) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + fileBytes = 0; + } + return fileBytes; +} diff --git a/security/nss/lib/freebl/win_rand.c b/security/nss/lib/freebl/win_rand.c index 20218b967..286ad3522 100644 --- a/security/nss/lib/freebl/win_rand.c +++ b/security/nss/lib/freebl/win_rand.c @@ -35,6 +35,7 @@ * ***** END LICENSE BLOCK ***** */ #include "secrng.h" +#include "secerr.h" #ifdef XP_WIN #include <windows.h> @@ -56,6 +57,7 @@ #endif #include "prio.h" +#include "prerror.h" static PRInt32 filesToRead; static DWORD totalFileBytes; @@ -545,4 +547,96 @@ void RNG_FileForRNG(const char *filename) } #endif /* not WinCE */ + +/* + * CryptoAPI requires Windows NT 4.0 or Windows 95 OSR2 and later. + * Until we drop support for Windows 95, we need to emulate some + * definitions and declarations in <wincrypt.h> and look up the + * functions in advapi32.dll at run time. + */ + +typedef unsigned long HCRYPTPROV; + +#define CRYPT_VERIFYCONTEXT 0xF0000000 + +#define PROV_RSA_FULL 1 + +typedef BOOL +(WINAPI *CryptAcquireContextAFn)( + HCRYPTPROV *phProv, + LPCSTR pszContainer, + LPCSTR pszProvider, + DWORD dwProvType, + DWORD dwFlags); + +typedef BOOL +(WINAPI *CryptReleaseContextFn)( + HCRYPTPROV hProv, + DWORD dwFlags); + +typedef BOOL +(WINAPI *CryptGenRandomFn)( + HCRYPTPROV hProv, + DWORD dwLen, + BYTE *pbBuffer); + +/* + * Windows XP and Windows Server 2003 and later have RtlGenRandom, + * which must be looked up by the name SystemFunction036. + */ +typedef BOOLEAN +(APIENTRY *RtlGenRandomFn)( + PVOID RandomBuffer, + ULONG RandomBufferLength); + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + HMODULE hModule; + RtlGenRandomFn pRtlGenRandom; + CryptAcquireContextAFn pCryptAcquireContextA; + CryptReleaseContextFn pCryptReleaseContext; + CryptGenRandomFn pCryptGenRandom; + HCRYPTPROV hCryptProv; + size_t bytes = 0; + + hModule = LoadLibrary("advapi32.dll"); + if (hModule == NULL) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return 0; + } + pRtlGenRandom = (RtlGenRandomFn) + GetProcAddress(hModule, "SystemFunction036"); + if (pRtlGenRandom) { + if (pRtlGenRandom(dest, maxLen)) { + bytes = maxLen; + } else { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + } + goto done; + } + pCryptAcquireContextA = (CryptAcquireContextAFn) + GetProcAddress(hModule, "CryptAcquireContextA"); + pCryptReleaseContext = (CryptReleaseContextFn) + GetProcAddress(hModule, "CryptReleaseContext"); + pCryptGenRandom = (CryptGenRandomFn) + GetProcAddress(hModule, "CryptGenRandom"); + if (!pCryptAcquireContextA || !pCryptReleaseContext || !pCryptGenRandom) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + goto done; + } + if (pCryptAcquireContextA(&hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + if (pCryptGenRandom(hCryptProv, maxLen, dest)) { + bytes = maxLen; + } + pCryptReleaseContext(hCryptProv, 0); + } + if (bytes == 0) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + } +done: + FreeLibrary(hModule); + return bytes; +} + #endif /* is XP_WIN */ diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk index 5cdb444e5..9ba5ce176 100644 --- a/security/nss/lib/nss/config.mk +++ b/security/nss/lib/nss/config.mk @@ -122,6 +122,14 @@ MKSHLIB += -R '$$ORIGIN' endif endif +ifeq ($(OS_ARCH), HP-UX) +ifneq ($(OS_TEST), ia64) +# pa-risc +ifeq ($(USE_64), 1) +MKSHLIB += +b '$$ORIGIN' +endif +endif +endif ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET))) ifndef NS_USE_GCC diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index f0f7cc7e1..300748f41 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -54,16 +54,16 @@ SEC_BEGIN_PROTOS */ #ifdef NSS_ENABLE_ECC #ifdef NSS_ECC_MORE_THAN_SUITE_B -#define NSS_VERSION "3.11.3 Extended ECC" +#define NSS_VERSION "3.11.4 Extended ECC" #else -#define NSS_VERSION "3.11.3 Basic ECC" +#define NSS_VERSION "3.11.4 Basic ECC" #endif #else -#define NSS_VERSION "3.11.3" +#define NSS_VERSION "3.11.4" #endif #define NSS_VMAJOR 3 #define NSS_VMINOR 11 -#define NSS_VPATCH 3 +#define NSS_VPATCH 4 #define NSS_BETA PR_FALSE /* diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c index da58c2e57..fc36e78e1 100644 --- a/security/nss/lib/nss/nssinit.c +++ b/security/nss/lib/nss/nssinit.c @@ -683,8 +683,9 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData) nssShutdownList.funcs = funcs; nssShutdownList.maxFuncs += NSS_SHUTDOWN_STEP; } - nssShutdownList.funcs[nssShutdownList.numFuncs++].func = sFunc; - nssShutdownList.funcs[nssShutdownList.numFuncs++].appData = appData; + nssShutdownList.funcs[nssShutdownList.numFuncs].func = sFunc; + nssShutdownList.funcs[nssShutdownList.numFuncs].appData = appData; + nssShutdownList.numFuncs++; PZ_Unlock(nssShutdownList.lock); return SECSuccess; } diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index 64bb4295e..559d7c5bd 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -706,8 +706,13 @@ STAN_GetCERTCertificateNameForInstance ( char * STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c) { + char * result; nssCryptokiInstance *instance = get_cert_instance(c); - return STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance); + /* It's OK to call this function, even if instance is NULL */ + result = STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance); + if (instance) + nssCryptokiObject_Destroy(instance); + return result; } static void diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c index 2b7f81a73..d1f7fd303 100644 --- a/security/nss/lib/softoken/dbinit.c +++ b/security/nss/lib/softoken/dbinit.c @@ -291,6 +291,7 @@ sftk_freeCertDB(NSSLOWCERTCertDBHandle *certHandle) PRInt32 ref = PR_AtomicDecrement(&certHandle->ref); if (ref == 0) { nsslowcert_ClosePermCertDB(certHandle); + PORT_Free(certHandle); } } diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c index 325bb2073..942bd4034 100644 --- a/security/nss/lib/softoken/fipstest.c +++ b/security/nss/lib/softoken/fipstest.c @@ -111,14 +111,14 @@ EC_CopyParams(PRArenaPool *arena, ECParams *dstParams, /* 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 64 /* 512-bits */ -#define FIPS_DSA_BASE_LENGTH 64 /* 512-bits */ +#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 /* 512-bits */ +#define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */ static CK_RV sftk_fips_RC2_PowerUpSelfTest( void ) @@ -1496,31 +1496,20 @@ rsa_loser: } #ifdef NSS_ENABLE_ECC + static CK_RV -sftk_fips_ECDSA_PowerUpSelfTest() { +sftk_fips_ECDSA_Test(const PRUint8 *encodedParams, + unsigned int encodedParamsLen, + const PRUint8 *knownSignature, + unsigned int knownSignatureLen) { - /* ECDSA Known Seed info for curve nistp256 */ + /* 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}; - /* ECDSA Known curve nistp256 params */ - static const PRUint8 knownEncodedParams[] = { - 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}; - static const PRUint8 msg[] = { "Firefox and ThunderBird are awesome!"}; @@ -1535,8 +1524,8 @@ sftk_fips_ECDSA_PowerUpSelfTest() { /* construct the ECDSA private/public key pair */ encodedparams.type = siBuffer; - encodedparams.data = (unsigned char *) knownEncodedParams; - encodedparams.len = sizeof knownEncodedParams; + encodedparams.data = (unsigned char *) encodedParams; + encodedparams.len = encodedParamsLen; if (EC_DecodeParams(&encodedparams, &ecparams) != SECSuccess) { return( CKR_DEVICE_ERROR ); @@ -1603,9 +1592,9 @@ sftk_fips_ECDSA_PowerUpSelfTest() { goto loser; } - if( ( signature.len != sizeof ecdsa_known_P256_signature ) || - ( PORT_Memcmp( signature.data, ecdsa_known_P256_signature, - sizeof ecdsa_known_P256_signature ) != 0 ) ) { + if( ( signature.len != knownSignatureLen ) || + ( PORT_Memcmp( signature.data, knownSignature, + knownSignatureLen ) != 0 ) ) { ecdsaStatus = SECFailure; goto loser; } @@ -1628,34 +1617,113 @@ loser: } 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 (512-bits), Q (160-bits), and G (512-bits) Values. */ + /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */ static const PRUint8 dsa_P[] = { - 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa, - 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb, - 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, - 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5, - 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf, - 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac, - 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2, - 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91}; + 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[] = { - 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee, - 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e, - 0xda,0xce,0x91,0x5f}; + 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[] = { - 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13, - 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00, - 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb, - 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e, - 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf, - 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c, - 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c, - 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02}; + 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). */ @@ -1669,11 +1737,11 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* DSA Known Signature (320-bits). */ static const PRUint8 dsa_known_signature[] = { - 0x39,0x0d,0x84,0xb1,0xf7,0x52,0x89,0xba, - 0xec,0x1e,0xa8,0xe2,0x00,0x8e,0x37,0x8f, - 0xc2,0xf5,0xf8,0x70,0x11,0xa8,0xc7,0x02, - 0x0e,0x75,0xcf,0x6b,0x54,0x4a,0x52,0xe8, - 0xd8,0x6d,0x4a,0xe8,0xee,0x56,0x8e,0x59}; + 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; @@ -1692,12 +1760,11 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /*******************************************/ /* 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 ); + return( CKR_HOST_MEMORY ); /* construct public key from private key. */ dsa_public_key.params = dsa_private_key->params; @@ -1716,8 +1783,8 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* Perform DSA signature process. */ dsa_status = DSA_SignDigestWithSeed( dsa_private_key, &dsa_signature_item, - &dsa_digest_item, - dsa_known_random_signature_block ); + &dsa_digest_item, + dsa_known_random_signature_block ); if( ( dsa_status != SECSuccess ) || ( dsa_signature_item.len != FIPS_DSA_SIGNATURE_LENGTH ) || @@ -1733,7 +1800,7 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* Perform DSA verification process. */ dsa_status = DSA_VerifyDigest( &dsa_public_key, &dsa_signature_item, - &dsa_digest_item); + &dsa_digest_item); } PORT_FreeArena(dsa_private_key->params.arena, PR_TRUE); diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c index 3c2e54f44..6cfcfcb05 100644 --- a/security/nss/lib/softoken/fipstokn.c +++ b/security/nss/lib/softoken/fipstokn.c @@ -108,6 +108,15 @@ libaudit_init(void) 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 */ @@ -286,20 +295,29 @@ static CK_FUNCTION_LIST sftk_fipsTable = { #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 -fips_login_if_key_object(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) +sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass) { CK_RV rv; - CK_OBJECT_CLASS objClass; CK_ATTRIBUTE class; class.type = CKA_CLASS; - class.pValue = &objClass; - class.ulValueLen = sizeof(objClass); + class.pValue = pObjClass; + class.ulValueLen = sizeof(*pObjClass); rv = NSC_GetAttributeValue(hSession, hObject, &class, 1); - if (rv == CKR_OK) { - if ((objClass == CKO_PRIVATE_KEY) || (objClass == CKO_SECRET_KEY)) { - rv = sftk_fipsCheck(); - } + if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) { + rv = sftk_fipsCheck(); } return rv; } @@ -498,7 +516,8 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV crv; crv = NSC_GetTokenInfo(slotID,pInfo); - pInfo->flags |= CKF_LOGIN_REQUIRED; + if (crv == CKR_OK) + pInfo->flags |= CKF_LOGIN_REQUIRED; return crv; } @@ -559,7 +578,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; PR_snprintf(msg,sizeof msg, - "C_InitPIN(hSession=%lu)=0x%08lX", + "C_InitPIN(hSession=0x%08lX)=0x%08lX", (PRUint32)hSession,(PRUint32)rv); sftk_LogAuditMessage(severity, msg); } @@ -581,7 +600,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; PR_snprintf(msg,sizeof msg, - "C_SetPIN(hSession=%lu)=0x%08lX", + "C_SetPIN(hSession=0x%08lX)=0x%08lX", (PRUint32)hSession,(PRUint32)rv); sftk_LogAuditMessage(severity, msg); } @@ -641,7 +660,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { NSSAuditSeverity severity; severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; PR_snprintf(msg,sizeof msg, - "C_Login(hSession=%lu, userType=%lu)=0x%08lX", + "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX", (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv); sftk_LogAuditMessage(severity, msg); } @@ -660,7 +679,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { NSSAuditSeverity severity = (rv == CKR_OK) ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; PR_snprintf(msg,sizeof msg, - "C_Logout(hSession=%lu)=0x%08lX", + "C_Logout(hSession=0x%08lX)=0x%08lX", (PRUint32)hSession,(PRUint32)rv); sftk_LogAuditMessage(severity, msg); } @@ -678,10 +697,15 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE; /* FIPS can't create keys from raw key material */ - if ((*classptr == CKO_SECRET_KEY) || (*classptr == CKO_PRIVATE_KEY)) { - return CKR_ATTRIBUTE_VALUE_INVALID; + if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) { + rv = CKR_ATTRIBUTE_VALUE_INVALID; + } else { + rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject); } - return NSC_CreateObject(hSession,pTemplate,ulCount,phObject); + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) { + sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv); + } + return rv; } @@ -690,15 +714,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* 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 usCount, + 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; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + 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 NSC_CopyObject(hSession,hObject,pTemplate,usCount,phNewObject); + return rv; } @@ -706,51 +735,67 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_DestroyObject(hSession,hObject); } - return 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 pusSize) { + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_GetObjectSize(hSession, hObject, pulSize); } - return NSC_GetObjectSize(hSession, hObject, pusSize); + 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 usCount) { + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + 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 NSC_GetAttributeValue(hSession,hObject,pTemplate,usCount); + 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 usCount) { + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount); } - return NSC_SetAttributeValue(hSession,hObject,pTemplate,usCount); + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); + } + return rv; } @@ -810,7 +855,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_EncryptInit(hSession,pMechanism,hKey); + 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. */ @@ -851,7 +900,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_DecryptInit(hSession,pMechanism,hKey); + 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. */ @@ -929,7 +982,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_SignInit(hSession,pMechanism,hKey); + rv = NSC_SignInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -971,7 +1028,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_SignRecoverInit(hSession,pMechanism,hKey); + rv = NSC_SignRecoverInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -994,7 +1055,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_VerifyInit(hSession,pMechanism,hKey); + rv = NSC_VerifyInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -1037,7 +1102,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_VerifyRecoverInit(hSession,pMechanism,hKey); + rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -1073,7 +1142,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { } } - return NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); + rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); + if (sftk_audit_enabled) { + sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv); + } + return rv; } @@ -1105,6 +1178,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* 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; } @@ -1113,18 +1191,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { 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 pusWrappedKeyLen) { + CK_ULONG_PTR pulWrappedKeyLen) { SFTK_FIPSCHECK(); - return NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, - pusWrappedKeyLen); + 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 usWrappedKeyLen, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_BBOOL *boolptr; @@ -1133,21 +1216,26 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* all secret keys must be sensitive, if the upper level code tries to say * otherwise, reject it. */ boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - usAttributeCount, CKA_SENSITIVE); + ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID; } } - return NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, - usWrappedKeyLen,pTemplate,usAttributeCount,phKey); + 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 usAttributeCount, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_BBOOL *boolptr; @@ -1156,14 +1244,19 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* all secret keys must be sensitive, if the upper level code tries to say * otherwise, reject it. */ boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - usAttributeCount, CKA_SENSITIVE); + ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID; } } - return NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, - usAttributeCount, phKey); + rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, + ulAttributeCount, phKey); + if (sftk_audit_enabled) { + sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate, + ulAttributeCount,phKey,rv); + } + return rv; } /* @@ -1197,7 +1290,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { if (sftk_audit_enabled) { char msg[128]; PR_snprintf(msg,sizeof msg, - "C_GenerateRandom(hSession=%lu, pRandomData=%p, " + "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, " "ulRandomLen=%lu)=0x%08lX " "self-test: continuous RNG test failed", (PRUint32)hSession,pRandomData, @@ -1306,7 +1399,11 @@ CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, */ CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_DigestKey(hSession,hKey); + rv = NSC_DigestKey(hSession,hKey); + if (sftk_audit_enabled) { + sftk_AuditDigestKey(hSession,hKey,rv); + } + return rv; } diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn index 294bd0b49..983d66887 100644 --- a/security/nss/lib/softoken/manifest.mn +++ b/security/nss/lib/softoken/manifest.mn @@ -70,6 +70,7 @@ CSRCS = \ dbinit.c \ dbmshim.c \ ecdecode.c \ + fipsaudt.c \ fipstest.c \ fipstokn.c \ keydb.c \ diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 80f9c5f71..f913735a4 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -2419,6 +2419,8 @@ 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' */ @@ -3115,21 +3117,13 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS) nsslowcert_DestroyFreeLists(); nsslowcert_DestroyGlobalLocks(); -#ifdef LEAK_TEST - /* - * do we really want to throw away all our hard earned entropy here!!? - * No we don't! Not calling RNG_RNGShutdown only 'leaks' data on the - * initial call to RNG_Init(). So the only reason to call this is to clean - * up leak detection warnings on shutdown. In many cases we *don't* want - * to free up the global RNG context because the application has Finalized - * simply to swap profiles. We don't want to loose the entropy we've - * already collected. - */ + /* This function does not discard all our previously aquired entropy. */ RNG_RNGShutdown(); -#endif /* tell freeBL to clean up after itself */ BL_Cleanup(); + /* unload freeBL shared library from memory */ + BL_Unload(); /* clean up the default OID table */ SECOID_Shutdown(); nsc_init = PR_FALSE; @@ -3244,9 +3238,11 @@ sftk_checkNeedLogin(SFTKSlot *slot, NSSLOWKEYDBHandle *keyHandle) * the system. */ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) { - SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); + SFTKSlot *slot; NSSLOWKEYDBHandle *handle; + 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); diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index dc1dc67f4..b722d3d4c 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -3813,7 +3813,7 @@ ecgn_done: if (sftk_audit_enabled) { char msg[128]; PR_snprintf(msg,sizeof msg, - "C_GenerateKeyPair(hSession=%lu, " + "C_GenerateKeyPair(hSession=0x%08lX, " "pMechanism->mechanism=0x%08lX)=0x%08lX " "self-test: pair-wise consistency test failed", (PRUint32)hSession,(PRUint32)pMechanism->mechanism, diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h index 27b25e892..ed9108dcc 100644 --- a/security/nss/lib/softoken/softoken.h +++ b/security/nss/lib/softoken/softoken.h @@ -184,6 +184,71 @@ extern PRBool sftk_audit_enabled; extern void sftk_LogAuditMessage(NSSAuditSeverity severity, 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 */ diff --git a/security/nss/lib/ssl/ssl.def b/security/nss/lib/ssl/ssl.def index 745934e92..ae12b2bf5 100644 --- a/security/nss/lib/ssl/ssl.def +++ b/security/nss/lib/ssl/ssl.def @@ -126,3 +126,10 @@ SSL_ShutdownServerSessionIDCache; ;+ local: ;+*; ;+}; +;+NSS_3.11.4 { # NSS 3.11.4 release +;+ global: +SSL_ForceHandshakeWithTimeout; +SSL_ReHandshakeWithTimeout; +;+ local: +;+*; +;+}; diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c index 70b270ae4..48935671d 100644 --- a/security/nss/lib/ssl/sslcon.c +++ b/security/nss/lib/ssl/sslcon.c @@ -3123,6 +3123,11 @@ ssl2_BeginClientHandshake(sslSocket *ss) #if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B) /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */ ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ + if (ss->cipherSpecs != NULL) { + PORT_Free(ss->cipherSpecs); + ss->cipherSpecs = NULL; + ss->sizeCipherSpecs = 0; + } #endif if (!ss->cipherSpecs) { diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 4ee3a3df8..924d993d0 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -49,6 +49,8 @@ #include "sslproto.h" #include "nspr.h" #include "private/pprio.h" +#include "blapi.h" +#include "nss.h" #define SET_ERROR_CODE /* reminder */ @@ -501,6 +503,29 @@ SSL_Enable(PRFileDesc *fd, int which, PRBool on) return SSL_OptionSet(fd, which, on); } +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType setupBypassOnce; + +static SECStatus SSL_BypassShutdown(void* appData, void* nssData) +{ + /* unload freeBL shared library from memory */ + BL_Unload(); + setupBypassOnce = pristineCallOnce; + return SECSuccess; +} + +static PRStatus SSL_BypassRegisterShutdown(void) +{ + SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL); + PORT_Assert(SECSuccess == rv); + return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE; +} + +static PRStatus SSL_BypassSetup(void) +{ + return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown); +} + SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) { @@ -625,7 +650,15 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) PORT_SetError(PR_INVALID_STATE_ERROR); rv = SECFailure; } else { - ss->opt.bypassPKCS11 = on; + if (PR_FALSE != on) { + if (PR_SUCCESS == SSL_BypassSetup() ) { + ss->opt.bypassPKCS11 = on; + } else { + rv = SECFailure; + } + } else { + ss->opt.bypassPKCS11 = PR_FALSE; + } } break; @@ -846,7 +879,15 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) break; case SSL_BYPASS_PKCS11: - ssl_defaults.bypassPKCS11 = on; + if (PR_FALSE != on) { + if (PR_SUCCESS == SSL_BypassSetup()) { + ssl_defaults.bypassPKCS11 = on; + } else { + return SECFailure; + } + } else { + ssl_defaults.bypassPKCS11 = PR_FALSE; + } break; case SSL_NO_LOCKS: diff --git a/security/nss/manifest.mn b/security/nss/manifest.mn index 918b66951..caed79aee 100644 --- a/security/nss/manifest.mn +++ b/security/nss/manifest.mn @@ -37,7 +37,7 @@ CORE_DEPTH = .. DEPTH = .. -IMPORTS = nspr20/v4.6.3 \ +IMPORTS = nspr20/v4.6.4 \ $(NULL) RELEASE = nss |