diff options
author | wtc%netscape.com <devnull@localhost> | 2002-03-08 22:19:06 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2002-03-08 22:19:06 +0000 |
commit | 0571f3a4e6c9b235182df6d42ebb67755e492292 (patch) | |
tree | 639a6e4de8619df6da0d1445e29080fc9b163bb4 | |
parent | 06397416eb9f6a4ca72e814474989b98ce32b3bf (diff) | |
download | nss-hg-0571f3a4e6c9b235182df6d42ebb67755e492292.tar.gz |
Bug 129597: Merged the tip of NSS (very close to NSS 3.4 release candidate)MOZILLA_0_9_9_RELEASE
onto MOZILLA_0_9_9_BRANCH. a=asa on behalf of drivers@mozilla.org.
71 files changed, 2610 insertions, 1622 deletions
diff --git a/security/coreconf/Darwin.mk b/security/coreconf/Darwin.mk index f0cfc7d27..6c2b93c9d 100644 --- a/security/coreconf/Darwin.mk +++ b/security/coreconf/Darwin.mk @@ -59,6 +59,10 @@ endif OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wmost -fpascal-strings -traditional-cpp -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK +ifdef BUILD_OPT +OPTIMIZER = -O2 +endif + ARCH = darwin # May override this with -bundle to create a loadable module. diff --git a/security/coreconf/FreeBSD.mk b/security/coreconf/FreeBSD.mk index 5c23d86c4..c07df1a6c 100644 --- a/security/coreconf/FreeBSD.mk +++ b/security/coreconf/FreeBSD.mk @@ -43,19 +43,21 @@ RANLIB = ranlib ifeq ($(OS_TEST),alpha) CPU_ARCH = alpha else -OS_REL_CFLAGS = -Di386 CPU_ARCH = x86 endif -OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -pipe $(THREAD_FLAG) -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK +OS_CFLAGS = $(DSO_CFLAGS) -ansi -Wall -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK + +DSO_CFLAGS = -fPIC +DSO_LDOPTS = -shared -Wl,-soname -Wl,$(notdir $@) # # The default implementation strategy for FreeBSD is pthreads. # ifndef CLASSIC_NSPR USE_PTHREADS = 1 -DEFINES += -D_THREAD_SAFE -THREAD_FLAG = -pthread +DEFINES += -D_THREAD_SAFE -D_REENTRANT +DSO_LDOPTS += -pthread endif ARCH = freebsd @@ -68,11 +70,7 @@ else DLL_SUFFIX = so.1.0 endif -DSO_CFLAGS = -fPIC -DSO_LDOPTS = -Bshareable -DSO_LDFLAGS = - -MKSHLIB = $(LD) $(DSO_LDOPTS) +MKSHLIB = $(CC) $(DSO_LDOPTS) ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c index 47d963bf4..d876a9207 100644 --- a/security/nss/cmd/certutil/certutil.c +++ b/security/nss/cmd/certutil/certutil.c @@ -952,7 +952,7 @@ secu_PrintKeyFromCert(CERTCertificate *cert, void *data) cbdata = (struct secuCBData *)data; out = cbdata->file; - key = PK11_FindPrivateKeyFromCert(PK11_GetInternalKeySlot(), cert, cbdata->wincx); + key = PK11_FindPrivateKeyFromCert(cert->slot, cert, cbdata->wincx); if (!key) { fprintf(out, "XXX could not extract key for %s.\n", cert->nickname); return SECFailure; diff --git a/security/nss/cmd/makepqg/makepqg.c b/security/nss/cmd/makepqg/makepqg.c index ead4698ad..9a9e79106 100644 --- a/security/nss/cmd/makepqg/makepqg.c +++ b/security/nss/cmd/makepqg/makepqg.c @@ -52,6 +52,16 @@ char *progName; +const SEC_ASN1Template seckey_PQGParamsTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPQGParams) }, + { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,prime) }, + { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,subPrime) }, + { SEC_ASN1_INTEGER, offsetof(SECKEYPQGParams,base) }, + { 0, } +}; + + + void Usage(void) { @@ -83,15 +93,15 @@ outputPQGParams(PQGParams * pqgParams, PRBool output_binary, PRBool output_raw, if (output_raw) { SECItem item; - PQG_GetPrimeFromParams(pqgParams, &item); + PK11_PQG_GetPrimeFromParams(pqgParams, &item); SECU_PrintInteger(outFile, &item, "Prime", 1); SECITEM_FreeItem(&item, PR_FALSE); - PQG_GetSubPrimeFromParams(pqgParams, &item); + PK11_PQG_GetSubPrimeFromParams(pqgParams, &item); SECU_PrintInteger(outFile, &item, "Subprime", 1); SECITEM_FreeItem(&item, PR_FALSE); - PQG_GetBaseFromParams(pqgParams, &item); + PK11_PQG_GetBaseFromParams(pqgParams, &item); SECU_PrintInteger(outFile, &item, "Base", 1); SECITEM_FreeItem(&item, PR_FALSE); @@ -103,7 +113,7 @@ outputPQGParams(PQGParams * pqgParams, PRBool output_binary, PRBool output_raw, encodedParams.len = 0; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); SEC_ASN1EncodeItem(arena, &encodedParams, pqgParams, - SECKEY_PQGParamsTemplate); + seckey_PQGParamsTemplate); if (output_binary) { fwrite(encodedParams.data, encodedParams.len, sizeof(char), outFile); printf("\n"); @@ -126,16 +136,16 @@ outputPQGVerify(PQGVerify * pqgVerify, PRBool output_binary, PRBool output_raw, SECItem item; unsigned int counter; - PQG_GetHFromVerify(pqgVerify, &item); + PK11_PQG_GetHFromVerify(pqgVerify, &item); SECU_PrintInteger(outFile, &item, "h", 1); SECITEM_FreeItem(&item, PR_FALSE); - PQG_GetSeedFromVerify(pqgVerify, &item); + PK11_PQG_GetSeedFromVerify(pqgVerify, &item); SECU_PrintInteger(outFile, &item, "SEED", 1); fprintf(outFile, " g: %d\n", item.len * BPB); SECITEM_FreeItem(&item, PR_FALSE); - counter = PQG_GetCounterFromVerify(pqgVerify); + counter = PK11_PQG_GetCounterFromVerify(pqgVerify); fprintf(outFile, " counter: %d\n", counter); fprintf(outFile, "\n"); return 0; @@ -238,13 +248,14 @@ main(int argc, char **argv) outFile = stdout; } - RNG_RNGInit(); - RNG_SystemInfoForRNG(); + + NSS_NoDB_Init(NULL); + if (g) - rv = PQG_ParamGenSeedLen((unsigned)j, (unsigned)(g/8), + rv = PK11_PQG_ParamGenSeedLen((unsigned)j, (unsigned)(g/8), &pqgParams, &pqgVerify); else - rv = PQG_ParamGen((unsigned)j, &pqgParams, &pqgVerify); + rv = PK11_PQG_ParamGen((unsigned)j, &pqgParams, &pqgVerify); if (rv != SECSuccess || pqgParams == NULL) { fprintf(stderr, "%s: PQG parameter generation failed.\n", progName); @@ -255,7 +266,7 @@ main(int argc, char **argv) o = outputPQGParams(pqgParams, output_binary, output_raw, outFile); o = outputPQGVerify(pqgVerify, output_binary, output_raw, outFile); - rv = PQG_VerifyParams(pqgParams, pqgVerify, &passed); + rv = PK11_PQG_VerifyParams(pqgParams, pqgVerify, &passed); if (rv != SECSuccess) { fprintf(stderr, "%s: PQG parameter verification aborted.\n", progName); goto loser; @@ -266,12 +277,12 @@ main(int argc, char **argv) } fprintf(stderr, "%s: PQG parameters passed verification.\n", progName); - PQG_DestroyParams(pqgParams); - PQG_DestroyVerify(pqgVerify); + PK11_PQG_DestroyParams(pqgParams); + PK11_PQG_DestroyVerify(pqgVerify); return 0; loser: - PQG_DestroyParams(pqgParams); - PQG_DestroyVerify(pqgVerify); + PK11_PQG_DestroyParams(pqgParams); + PK11_PQG_DestroyVerify(pqgVerify); return 1; } diff --git a/security/nss/cmd/makepqg/manifest.mn b/security/nss/cmd/makepqg/manifest.mn index 1bf4337c1..6053caeae 100644 --- a/security/nss/cmd/makepqg/manifest.mn +++ b/security/nss/cmd/makepqg/manifest.mn @@ -43,5 +43,5 @@ CSRCS = makepqg.c PROGRAM = makepqg -USE_STATIC_LIBS = 1 +#USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c index b3505f7fc..bba34e69e 100644 --- a/security/nss/cmd/modutil/modutil.c +++ b/security/nss/cmd/modutil/modutil.c @@ -108,6 +108,7 @@ typedef enum { TEMPDIR_ARG, SECMOD_ARG, NOCERTDB_ARG, + STRING_ARG, NUM_ARGS /* must be last */ } Arg; @@ -139,7 +140,8 @@ static char *optionStrings[] = { "-installdir", "-tempdir", "-secmod", - "-nocertdb" + "-nocertdb", + "-string", }; /* Increment i if doing so would have i still be less than j. If you @@ -161,6 +163,7 @@ static char* tokenName = NULL; static char* libFile = NULL; static char* dbdir = NULL; static char* dbprefix = ""; +static char* secmodString = NULL; static char* mechanisms = NULL; static char* ciphers = NULL; static char* fipsArg = NULL; @@ -470,6 +473,17 @@ parse_args(int argc, char *argv[]) } secmodName = argv[i]; break; + case STRING_ARG: + if(secmodString != NULL) { + PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg); + return DUPLICATE_OPTION_ERR; + } + if(TRY_INC(i, argc)) { + PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg); + return OPTION_NEEDS_ARG_ERR; + } + secmodString = argv[i]; + break; } } return SUCCESS; @@ -709,6 +723,7 @@ usage() " [-ciphers CIPHER_LIST] Enable the given ciphers on this module\n" " [-mechanisms MECHANISM_LIST] Make the module a default provider of the\n" " given mechanisms\n" +" [-string CONFIG_STRING] Pass a configuration string to this module\n" "-changepw TOKEN Change the password on the named token\n" " [-pwfile FILE] The old password is in this file\n" " [-newpwfile FILE] The new password is in this file\n" @@ -853,7 +868,7 @@ main(int argc, char *argv[]) /* Execute the command */ switch(command) { case ADD_COMMAND: - errcode = AddModule(moduleName, libFile, ciphers, mechanisms); + errcode = AddModule(moduleName, libFile, ciphers, mechanisms, secmodString); break; case CHANGEPW_COMMAND: errcode = ChangePW(tokenName, pwFile, newpwFile); diff --git a/security/nss/cmd/modutil/modutil.h b/security/nss/cmd/modutil/modutil.h index 16c58fb49..89b8a204a 100644 --- a/security/nss/cmd/modutil/modutil.h +++ b/security/nss/cmd/modutil/modutil.h @@ -51,7 +51,7 @@ Error FipsMode(char *arg); Error AddModule(char *moduleName, char *libFile, char *ciphers, - char *mechanisms); + char *mechanisms, char* modparms); Error DeleteModule(char *moduleName); Error ListModule(char *moduleName); Error ListModules(); diff --git a/security/nss/cmd/modutil/pk11.c b/security/nss/cmd/modutil/pk11.c index 5831dde48..07c4d44a5 100644 --- a/security/nss/cmd/modutil/pk11.c +++ b/security/nss/cmd/modutil/pk11.c @@ -221,7 +221,7 @@ getStringFromFlags(unsigned long flags, MaskString array[], int elements) */ Error AddModule(char *moduleName, char *libFile, char *cipherString, - char *mechanismString) + char *mechanismString, char* modparms) { unsigned long ciphers; unsigned long mechanisms; @@ -234,9 +234,10 @@ AddModule(char *moduleName, char *libFile, char *cipherString, getFlagsFromString(cipherString, cipherStrings, numCipherStrings); status = - SECMOD_AddNewModule(moduleName, libFile, + SECMOD_AddNewModuleEx(moduleName, libFile, SECMOD_PubMechFlagstoInternal(mechanisms), - SECMOD_PubCipherFlagstoInternal(ciphers) ); + SECMOD_PubCipherFlagstoInternal(ciphers), + modparms, NULL ); if(status != SECSuccess) { char* errtxt=NULL; diff --git a/security/nss/cmd/p7content/manifest.mn b/security/nss/cmd/p7content/manifest.mn index 442e51f0c..ff7d7565d 100644 --- a/security/nss/cmd/p7content/manifest.mn +++ b/security/nss/cmd/p7content/manifest.mn @@ -37,10 +37,7 @@ MODULE = security CSRCS = p7content.c -REQUIRES = seccmd dbm +REQUIRES = seccmd PROGRAM = p7content -# PROGRAM = ./$(OBJDIR)/p7content.exe - -USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/p7env/manifest.mn b/security/nss/cmd/p7env/manifest.mn index 8b558b6c6..511c541b0 100644 --- a/security/nss/cmd/p7env/manifest.mn +++ b/security/nss/cmd/p7env/manifest.mn @@ -37,10 +37,7 @@ MODULE = security CSRCS = p7env.c -REQUIRES = seccmd dbm +REQUIRES = seccmd PROGRAM = p7env -# PROGRAM = ./$(OBJDIR)/p7env.exe - -USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/p7sign/manifest.mn b/security/nss/cmd/p7sign/manifest.mn index 5665dbc7b..7a190276b 100644 --- a/security/nss/cmd/p7sign/manifest.mn +++ b/security/nss/cmd/p7sign/manifest.mn @@ -37,10 +37,7 @@ MODULE = security CSRCS = p7sign.c -REQUIRES = seccmd dbm +REQUIRES = seccmd PROGRAM = p7sign -# PROGRAM = ./$(OBJDIR)/p7sign.exe - -USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/p7sign/p7sign.c b/security/nss/cmd/p7sign/p7sign.c index 97a69974b..0bff6c1da 100644 --- a/security/nss/cmd/p7sign/p7sign.c +++ b/security/nss/cmd/p7sign/p7sign.c @@ -46,6 +46,7 @@ #include "certdb.h" #include "sechash.h" /* for HASH_GetHashObject() */ #include "nss.h" +#include "pk11func.h" #if defined(XP_UNIX) #include <unistd.h> @@ -60,6 +61,20 @@ extern int fwrite(char *, size_t, size_t, FILE*); extern int fprintf(FILE *, char *, ...); #endif +char* KeyDbPassword = 0; + + +char* MyPK11PasswordFunc (PK11SlotInfo *slot, PRBool retry, void* arg) +{ + char *ret=0; + + if (retry == PR_TRUE) + return NULL; + ret = PL_strdup (KeyDbPassword); + return ret; +} + + static void Usage(char *progName) { @@ -76,6 +91,7 @@ Usage(char *progName) "-o output"); fprintf(stderr, "%-20s Encapsulate content in signature message\n", "-e"); + fprintf(stderr, "%-20s Password to the key databse\n", "-p"); exit(-1); } @@ -84,7 +100,7 @@ SignOut(void *arg, const char *buf, unsigned long len) { FILE *out; - out = arg; + out = (FILE*) arg; fwrite (buf, len, 1, out); } @@ -190,7 +206,7 @@ main(int argc, char **argv) /* * Parse command line arguments */ - optstate = PL_CreateOptState(argc, argv, "ed:k:i:o:"); + optstate = PL_CreateOptState(argc, argv, "ed:k:i:o:p:"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case '?': @@ -227,6 +243,9 @@ main(int argc, char **argv) return -1; } break; + case 'p': + KeyDbPassword = strdup (optstate->value); + break; } } @@ -243,6 +262,8 @@ main(int argc, char **argv) return -1; } + PK11_SetPasswordFunc (MyPK11PasswordFunc); + /* open cert database */ certHandle = CERT_GetDefaultCertDB(); if (certHandle == NULL) { diff --git a/security/nss/cmd/p7verify/manifest.mn b/security/nss/cmd/p7verify/manifest.mn index 51fd7091d..5ac9e8a3f 100644 --- a/security/nss/cmd/p7verify/manifest.mn +++ b/security/nss/cmd/p7verify/manifest.mn @@ -37,10 +37,7 @@ MODULE = security CSRCS = p7verify.c -REQUIRES = seccmd dbm +REQUIRES = seccmd PROGRAM = p7verify -# PROGRAM = ./$(OBJDIR)/p7verify.exe - -USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index 58dc1e51b..622be2969 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -190,7 +190,7 @@ Usage(const char *progName) "-t threads -- specify the number of threads to use for connections.\n" "-i pid_file file to write the process id of selfserve\n" "-c ciphers Letter(s) chosen from the following list\n" -"-l means use local threads instead of global threads" +"-l means use local threads instead of global threads\n" "A SSL2 RC4 128 WITH MD5\n" "B SSL2 RC4 128 EXPORT40 WITH MD5\n" "C SSL2 RC2 128 CBC WITH MD5\n" diff --git a/security/nss/lib/base/base.h b/security/nss/lib/base/base.h index 4442eac30..492da7259 100644 --- a/security/nss/lib/base/base.h +++ b/security/nss/lib/base/base.h @@ -949,6 +949,12 @@ nssList_CreateIterator nssList *list ); +NSS_EXTERN nssList * +nssList_Clone +( + nssList *list +); + /* * nssListIterator_Destroy */ diff --git a/security/nss/lib/base/list.c b/security/nss/lib/base/list.c index 89aadf283..ae7375a91 100644 --- a/security/nss/lib/base/list.c +++ b/security/nss/lib/base/list.c @@ -189,6 +189,7 @@ nssList_Clear(nssList *list, nssListElementDestructorFunc destructor) nssListElement *node, *tmp; NSSLIST_LOCK_IF(list); node = list->head; + list->head = NULL; while (node && list->count > 0) { if (destructor) (*destructor)(node->data); link = &node->link; diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index b1f939b3d..4d6751a78 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -398,12 +398,13 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type) CERTSignedCrl *crl = NULL; SECItem *derCrl; CK_OBJECT_HANDLE crlHandle; + char *url = NULL; if (slot) { PK11_ReferenceSlot(slot); } - derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey,type); + derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey, type, &url); if (derCrl == NULL) { goto loser; } @@ -413,6 +414,10 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type) crl->slot = slot; slot = NULL; /* adopt it */ } + if (url) { + crl->url = PORT_ArenaStrdup(crl->arena,url); + PORT_Free(url); + } loser: if (slot) { @@ -485,6 +490,9 @@ crl_storeCRL (PK11SlotInfo *slot,char *url, crl = newCrl; crl->slot = PK11_ReferenceSlot(slot); crl->pkcs11ID = crlHandle; + if (url) { + crl->url = PORT_ArenaStrdup(crl->arena,url); + } } done: diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index d4d91aae1..20d9ffa73 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -136,6 +136,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, CERTCertTrust *trust) { PRStatus nssrv; + NSSUTF8 *stanNick; PK11SlotInfo *slot; NSSToken *internal; NSSCryptoContext *context; @@ -144,13 +145,14 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, if (!context) { return PR_FAILURE; /* wasn't a temp cert */ } - if (c->nickname && strcmp(nickname, c->nickname) != 0) { - nss_ZFreeIf(c->nickname); + stanNick = NSSCertificate_GetNickname(c, NULL); + if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { + /* take the new nickname */ PORT_Free(cert->nickname); - c->nickname = NULL; + stanNick = NULL; } - if (!c->nickname) { - c->nickname = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena); + if (!stanNick && nickname) { + stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena); cert->nickname = PORT_Strdup(nickname); } /* Delete the temp instance */ @@ -161,7 +163,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); internal = PK11Slot_GetNSSToken(slot); - nssrv = nssToken_ImportCertificate(internal, NULL, c, PR_TRUE); + nssrv = nssToken_ImportCertificate(internal, NULL, c, stanNick, PR_TRUE); if (nssrv != PR_SUCCESS) { return SECFailure; } @@ -240,10 +242,10 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, PORT_Free(derSerial.data); } if (nickname) { - c->nickname = nssUTF8_Create(arena, - nssStringType_UTF8String, - (NSSUTF8 *)nickname, - PORT_Strlen(nickname)); + c->object.tempName = nssUTF8_Create(arena, + nssStringType_UTF8String, + (NSSUTF8 *)nickname, + PORT_Strlen(nickname)); } if (cc->emailAddr) { c->email = nssUTF8_Create(arena, @@ -335,8 +337,14 @@ CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name) cp = NSSTrustDomain_FindBestCertificateBySubject(handle, &subject, NULL, &usage, NULL); c = get_best_temp_or_perm(ct, cp); - if (ct) NSSCertificate_Destroy(ct); - if (cp) NSSCertificate_Destroy(cp); + if (ct) { + CERTCertificate *cert = STAN_GetCERTCertificate(ct); + CERT_DestroyCertificate(cert); + } + if (cp) { + CERTCertificate *cert = STAN_GetCERTCertificate(cp); + CERT_DestroyCertificate(cert); + } if (c) { return STAN_GetCERTCertificate(c); } else { @@ -379,7 +387,10 @@ CERT_FindCertByNickname(CERTCertDBHandle *handle, char *nickname) if (cert) { c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); CERT_DestroyCertificate(cert); - if (ct) NSSCertificate_Destroy(ct); + if (ct) { + CERTCertificate *cert2 = STAN_GetCERTCertificate(ct); + CERT_DestroyCertificate(cert2); + } } else { c = ct; } @@ -426,7 +437,10 @@ CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, char *name) if (cert) { c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); CERT_DestroyCertificate(cert); - if (ct) NSSCertificate_Destroy(ct); + if (ct) { + CERTCertificate *cert2 = STAN_GetCERTCertificate(ct); + CERT_DestroyCertificate(cert2); + } } else { c = ct; } @@ -536,8 +550,6 @@ CERT_DestroyCertificate(CERTCertificate *cert) } #else if (tmp) { - /* delete the NSSCertificate */ - PK11SlotInfo *slot = cert->slot; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); refCount = (int)tmp->object.refCount; /* This is a hack. For 3.4, there are persistent references @@ -559,8 +571,8 @@ CERT_DestroyCertificate(CERTCertificate *cert) } else { nssTrustDomain_RemoveCertFromCache(td, tmp); } - refCount = (int)tmp->object.refCount; } + /* delete the NSSCertificate */ NSSCertificate_Destroy(tmp); } #endif @@ -685,17 +697,17 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, SECStatus rv = SECFailure; PRBool saveit; char *emailAddr; - SECItem oldprof; + SECItem oldprof, oldproftime; SECItem *oldProfile = NULL; SECItem *oldProfileTime = NULL; PK11SlotInfo *slot = NULL; NSSCertificate *c; NSSCryptoContext *cc; nssSMIMEProfile *stanProfile = NULL; + PRBool freeOldProfile = PR_FALSE; emailAddr = cert->emailAddr; - PORT_Assert(emailAddr); if ( emailAddr == NULL ) { goto loser; } @@ -706,12 +718,16 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, if (cc != NULL) { stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); if (stanProfile) { + PORT_Assert(stanProfile->profileData); SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData); oldProfile = &oldprof; + SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime); + oldProfileTime = &oldproftime; } } else { oldProfile = PK11_FindSMimeProfile(&slot, emailAddr, &cert->derSubject, &oldProfileTime); + freeOldProfile = PR_TRUE; } saveit = PR_FALSE; @@ -757,12 +773,19 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, if (saveit) { if (cc) { if (stanProfile) { - /* well, it's hashed and in an arena, might as well just - * overwrite the buffer + /* stanProfile is already stored in the crypto context, + * overwrite the data */ - NSSITEM_FROM_SECITEM(stanProfile->profileTime, profileTime); - NSSITEM_FROM_SECITEM(stanProfile->profileData, emailProfile); - } else { + NSSArena *arena = stanProfile->object.arena; + stanProfile->profileTime = nssItem_Create(arena, + NULL, + profileTime->len, + profileTime->data); + stanProfile->profileData = nssItem_Create(arena, + NULL, + emailProfile->len, + emailProfile->data); + } else if (profileTime && emailProfile) { PRStatus nssrv; NSSDER subject; NSSItem profTime, profData; @@ -794,12 +817,15 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, } loser: - if (oldProfile) { + if (oldProfile && freeOldProfile) { SECITEM_FreeItem(oldProfile,PR_TRUE); } - if (oldProfileTime) { + if (oldProfileTime && freeOldProfile) { SECITEM_FreeItem(oldProfileTime,PR_TRUE); } + if (stanProfile) { + nssSMIMEProfile_Destroy(stanProfile); + } return(rv); } @@ -823,7 +849,7 @@ CERT_FindSMimeProfile(CERTCertificate *cert) if (rvItem) { rvItem->data = stanProfile->profileData->data; } - nssPKIObject_Destroy(&stanProfile->object); + nssSMIMEProfile_Destroy(stanProfile); } return rvItem; } diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c index 261ac9755..06cccb43b 100644 --- a/security/nss/lib/certhigh/certhigh.c +++ b/security/nss/lib/certhigh/certhigh.c @@ -48,6 +48,10 @@ #include "pkitm.h" #include "pki3hack.h" + +CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url, + CERTSignedCrl *newCrl, SECItem *derCrl, int type); + PRBool CERT_MatchNickname(char *name1, char *name2) { char *nickname1= NULL; @@ -737,6 +741,7 @@ CERTSignedCrl * CERT_ImportCRL CERTCertificate *caCert; CERTSignedCrl *newCrl, *crl; SECStatus rv; + PK11SlotInfo *slot; newCrl = crl = NULL; @@ -779,16 +784,15 @@ CERTSignedCrl * CERT_ImportCRL break; } -#ifdef FIXME - /* Do CRL validation and add to the dbase if this crl is more present then the one - in the dbase, if one exists. - */ - crl = cert_DBInsertCRL (handle, url, newCrl, derCRL, type); -#endif + slot = PK11_GetInternalKeySlot(); + crl = crl_storeCRL(slot, url, newCrl, derCRL, type); + PK11_FreeSlot(slot); } while (0); - SEC_DestroyCrl (newCrl); + if (crl == NULL) { + SEC_DestroyCrl (newCrl); + } return (crl); } diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index 42d6d86ee..1ae7237de 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -270,7 +270,6 @@ SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, CERTSignedCrl *crl = NULL; SECStatus rv = SECSuccess; CERTCrlEntry **crlEntry; - SECCertTimeValidity validity; /* first look up the CRL */ crl = SEC_FindCrlByName(handle,&caCert->derSubject, SEC_CRL_TYPE); @@ -287,16 +286,6 @@ SEC_CheckCRL(CERTCertDBHandle *handle,CERTCertificate *cert, goto done; } - /* Verify the date validity of the KRL */ - validity = SEC_CheckCrlTimes(&crl->crl,t); - if (validity == secCertTimeExpired) { - PORT_SetError(SEC_ERROR_CRL_EXPIRED); - rv = SECWouldBlock; /* Soft error, ask the user */ - } else if (validity == secCertTimeNotValidYet) { - PORT_SetError(SEC_ERROR_CRL_NOT_YET_VALID); - rv = SECWouldBlock; /* Soft error, ask the user */ - } - /* now make sure the key is not on the revocation list */ for (crlEntry = crl->crl.entries; crlEntry && *crlEntry; crlEntry++) { if (SECITEM_CompareItem(&(*crlEntry)->serialNumber,&cert->serialNumber) == SECEqual) { diff --git a/security/nss/lib/ckfw/builtins/certdata.c b/security/nss/lib/ckfw/builtins/certdata.c index a6abc5fa4..d835994fe 100644 --- a/security/nss/lib/ckfw/builtins/certdata.c +++ b/security/nss/lib/ckfw/builtins/certdata.c @@ -39,15 +39,16 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$""; @(#) $R #include "builtins.h" #endif /* BUILTINS_H */ -static const CK_OBJECT_CLASS cko_netscape_trust = CKO_NETSCAPE_TRUST; +static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE; +static const CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509; +static const CK_BBOOL ck_false = CK_FALSE; static const CK_TRUST ckt_netscape_valid = CKT_NETSCAPE_VALID; -static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST; static const CK_TRUST ckt_netscape_trusted_delegator = CKT_NETSCAPE_TRUSTED_DELEGATOR; -static const CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509; static const CK_OBJECT_CLASS cko_data = CKO_DATA; -static const CK_BBOOL ck_false = CK_FALSE; static const CK_BBOOL ck_true = CK_TRUE; -static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE; +static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST; +static const CK_OBJECT_CLASS cko_netscape_trust = CKO_NETSCAPE_TRUST; +static const CK_TRUST ckt_netscape_valid_delegator = CKT_NETSCAPE_VALID_DELEGATOR; #ifdef DEBUG static const CK_ATTRIBUTE_TYPE nss_builtins_types_0 [] = { CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_APPLICATION, CKA_VALUE @@ -9557,9 +9558,9 @@ static const NSSItem nss_builtins_items_153 [] = { , (PRUint32)104 }, { (void *)"\047\205" , (PRUint32)2 }, - { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, - { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, - { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) } + { (void *)&ckt_netscape_valid_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_valid_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_valid_delegator, (PRUint32)sizeof(CK_TRUST) } }; static const NSSItem nss_builtins_items_154 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt index b10389a60..3bbea9857 100644 --- a/security/nss/lib/ckfw/builtins/certdata.txt +++ b/security/nss/lib/ckfw/builtins/certdata.txt @@ -9800,9 +9800,9 @@ END CKA_SERIAL_NUMBER MULTILINE_OCTAL \047\205 END -CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_VALID -CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_VALID -CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_VALID +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_VALID_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_VALID_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_VALID_DELEGATOR # # Certificate "AddTrust Non-Validated Services Root" diff --git a/security/nss/lib/ckfw/instance.c b/security/nss/lib/ckfw/instance.c index 02a73e224..42b8b11ab 100644 --- a/security/nss/lib/ckfw/instance.c +++ b/security/nss/lib/ckfw/instance.c @@ -58,6 +58,7 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; * NSSCKFWInstance_MayCreatePthreads * NSSCKFWInstance_CreateMutex * NSSCKFWInstance_GetConfigurationData + * NSSCKFWInstance_GetInitArgs * * -- implement public accessors -- * nssCKFWInstance_GetMDInstance @@ -65,6 +66,7 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; * nssCKFWInstance_MayCreatePthreads * nssCKFWInstance_CreateMutex * nssCKFWInstance_GetConfigurationData + * nssCKFWInstance_GetInitArgs * * -- private accessors -- * nssCKFWInstance_CreateSessionHandle @@ -521,6 +523,25 @@ nssCKFWInstance_GetConfigurationData } /* + * nssCKFWInstance_GetInitArgs + * + */ +CK_C_INITIALIZE_ARGS_PTR +nssCKFWInstance_GetInitArgs +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef NSSDEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (CK_C_INITIALIZE_ARGS_PTR)NULL; + } +#endif /* NSSDEBUG */ + + return fwInstance->pInitArgs; +} + +/* * nssCKFWInstance_CreateSessionHandle * */ @@ -1304,3 +1325,23 @@ NSSCKFWInstance_GetConfigurationData return nssCKFWInstance_GetConfigurationData(fwInstance); } + +/* + * NSSCKFWInstance_GetInitArgs + * + */ +NSS_IMPLEMENT CK_C_INITIALIZE_ARGS_PTR +NSSCKFWInstance_GetInitArgs +( + NSSCKFWInstance *fwInstance +) +{ +#ifdef DEBUG + if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) { + return (CK_C_INITIALIZE_ARGS_PTR)NULL; + } +#endif /* DEBUG */ + + return nssCKFWInstance_GetInitArgs(fwInstance); +} + diff --git a/security/nss/lib/ckfw/nssckfw.h b/security/nss/lib/ckfw/nssckfw.h index ce16f2b7b..769427ab6 100644 --- a/security/nss/lib/ckfw/nssckfw.h +++ b/security/nss/lib/ckfw/nssckfw.h @@ -126,6 +126,17 @@ NSSCKFWInstance_GetConfigurationData ); /* + * NSSCKFWInstance_GetInitArgs + * + */ + +NSS_EXTERN CK_C_INITIALIZE_ARGS_PTR +NSSCKFWInstance_GetInitArgs +( + NSSCKFWInstance *fwInstance +); + +/* * NSSCKFWSlot * * NSSCKFWSlot_GetMDSlot diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h index 3102817eb..65dee8d63 100644 --- a/security/nss/lib/dev/dev.h +++ b/security/nss/lib/dev/dev.h @@ -268,6 +268,7 @@ nssToken_ImportCertificate NSSToken *tok, nssSession *sessionOpt, NSSCertificate *cert, + NSSUTF8 *nickname, PRBool asTokenObject ); @@ -280,6 +281,30 @@ nssToken_ImportTrust PRBool asTokenObject ); +NSS_EXTERN PRStatus +nssToken_SetTrustCache +( + NSSToken *tok +); + +NSS_EXTERN PRStatus +nssToken_SetCrlCache +( + NSSToken *tok +); + +NSS_EXTERN PRBool +nssToken_HasCrls +( + NSSToken *tok +); + +NSS_EXTERN PRStatus +nssToken_SetHasCrls +( + NSSToken *tok +); + NSS_EXTERN NSSPublicKey * nssToken_GenerateKeyPair ( @@ -450,6 +475,18 @@ NSSAlgorithmAndParameters_CreateMD5Digest NSSArena *arenaOpt ); +#ifdef NSS_3_4_CODE +/* exposing this for the smart card cache code */ +NSS_EXTERN nssCryptokiInstance * +nssCryptokiInstance_Create +( + NSSArena *arena, + NSSToken *t, + CK_OBJECT_HANDLE h, + PRBool isTokenObject +); +#endif + PR_END_EXTERN_C #endif /* DEV_H */ diff --git a/security/nss/lib/dev/devobject.c b/security/nss/lib/dev/devobject.c index 46c40120e..06150df50 100644 --- a/security/nss/lib/dev/devobject.c +++ b/security/nss/lib/dev/devobject.c @@ -291,7 +291,15 @@ create_cryptoki_instance PRBool isTokenObject ) { + PRStatus nssrv; nssCryptokiInstance *instance; + CK_ATTRIBUTE cert_template = { CKA_LABEL, NULL, 0 }; + nssrv = nssCKObject_GetAttributes(h, &cert_template, 1, + arena, t->defaultSession, t->slot); + if (nssrv != PR_SUCCESS) { + /* a failure here indicates a device error */ + return NULL; + } instance = nss_ZNEW(arena, nssCryptokiInstance); if (!instance) { return NULL; @@ -299,9 +307,25 @@ create_cryptoki_instance instance->handle = h; instance->token = t; instance->isTokenObject = isTokenObject; + NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template, instance->label); return instance; } +#ifdef NSS_3_4_CODE +/* exposing this for the smart card cache code */ +NSS_IMPLEMENT nssCryptokiInstance * +nssCryptokiInstance_Create +( + NSSArena *arena, + NSSToken *t, + CK_OBJECT_HANDLE h, + PRBool isTokenObject +) +{ + return create_cryptoki_instance(arena, t, h, isTokenObject); +} +#endif + static NSSCertificateType nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) { @@ -340,7 +364,6 @@ get_token_cert { CKA_VALUE, NULL, 0 }, { CKA_ISSUER, NULL, 0 }, { CKA_SERIAL_NUMBER, NULL, 0 }, - { CKA_LABEL, NULL, 0 }, { CKA_SUBJECT, NULL, 0 }, { CKA_NETSCAPE_EMAIL, NULL, 0 } }; @@ -371,9 +394,8 @@ get_token_cert NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding); NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[3], &rvCert->issuer); NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->serial); - NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[5], rvCert->nickname); - NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->subject); - NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[7], rvCert->email); + NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[5], &rvCert->subject); + NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[6], rvCert->email); /* XXX this would be better accomplished by dividing attributes to * retrieve into "required" and "optional" */ @@ -429,6 +451,7 @@ nssToken_ImportCertificate NSSToken *tok, nssSession *sessionOpt, NSSCertificate *cert, + NSSUTF8 *nickname, PRBool asTokenObject ) { @@ -447,7 +470,7 @@ nssToken_ImportCertificate NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, &cert->id); - NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, cert->nickname); + NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, &cert->encoding); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, &cert->issuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, &cert->subject); @@ -893,11 +916,66 @@ nssToken_ImportTrust /* XXX Fix this! */ nssListIterator_Destroy(trust->object.instances); trust->object.instances = nssList_CreateIterator(trust->object.instanceList); + tok->hasNoTrust = PR_FALSE; return PR_SUCCESS; } return PR_FAILURE; } +NSS_IMPLEMENT PRStatus +nssToken_SetTrustCache +( + NSSToken *token +) +{ + CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST; + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE tobj_template[2]; + CK_ULONG tobj_size; + CK_OBJECT_HANDLE obj; + nssSession *session = token->defaultSession; + + NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); + NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); + + obj = find_object_by_template(token, session, + tobj_template, tobj_size); + token->hasNoTrust = PR_FALSE; + if (obj == CK_INVALID_HANDLE) { + token->hasNoTrust = PR_TRUE; + } + return PR_SUCCESS; +} + +NSS_IMPLEMENT PRStatus +nssToken_SetCrlCache +( + NSSToken *token +) +{ + CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_CRL; + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE tobj_template[2]; + CK_ULONG tobj_size; + CK_OBJECT_HANDLE obj; + nssSession *session = token->defaultSession; + + NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); + NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); + + obj = find_object_by_template(token, session, + tobj_template, tobj_size); + token->hasNoCrls = PR_TRUE; + if (obj == CK_INVALID_HANDLE) { + token->hasNoCrls = PR_TRUE; + } + return PR_SUCCESS; +} + static CK_OBJECT_HANDLE get_cert_trust_handle ( @@ -913,6 +991,10 @@ get_cert_trust_handle CK_ULONG tobj_size; PRUint8 sha1[20]; /* this is cheating... */ NSSItem sha1_result; + + if (token->hasNoTrust) { + return CK_INVALID_HANDLE; + } sha1_result.data = sha1; sha1_result.size = sizeof sha1; sha1_hash(&c->encoding, &sha1_result); NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h index 148ad7683..ef031524b 100644 --- a/security/nss/lib/dev/devt.h +++ b/security/nss/lib/dev/devt.h @@ -132,9 +132,12 @@ struct NSSTokenStr nssSession *defaultSession; NSSTrustDomain *trustDomain; PRIntervalTime lastTime; + PRBool hasNoTrust; + PRBool hasNoCrls; #ifdef NSS_3_4_CODE PK11SlotInfo *pk11slot; nssList *certList; /* local cache of certs for slow tokens */ + PRBool loggedIn; #endif }; @@ -170,6 +173,7 @@ struct nssCryptokiInstanceStr CK_OBJECT_HANDLE handle; NSSToken *token; PRBool isTokenObject; + NSSUTF8 *label; }; typedef struct nssTokenCertSearchStr nssTokenCertSearch; diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c index cdd0fc9ac..b3b168a5f 100644 --- a/security/nss/lib/dev/devtoken.c +++ b/security/nss/lib/dev/devtoken.c @@ -134,6 +134,8 @@ nssToken_Create rvToken->name = tokenName; rvToken->ckFlags = tokenInfo.flags; rvToken->defaultSession = session; + rvToken->hasNoTrust = PR_FALSE; + rvToken->hasNoCrls = PR_FALSE; if (mark) { nssrv = nssArena_Unmark(arena, mark); if (nssrv != PR_SUCCESS) { @@ -167,12 +169,14 @@ nssToken_Destroy if (tok->defaultSession) { nssSession_Destroy(tok->defaultSession); } -#endif if (tok->arena) { return NSSArena_Destroy(tok->arena); } else { nss_ZFreeIf(tok); } +#else + nss_ZFreeIf(tok); +#endif } return PR_SUCCESS; } @@ -193,6 +197,9 @@ nssToken_GetName NSSToken *tok ) { + if (tok->name[0] == 0) { + (void) nssToken_IsPresent(tok); + } return tok->name; } @@ -231,6 +238,7 @@ nssToken_IsPresent ckrv = CKAPI(slot)->C_GetSlotInfo(slot->slotID, &slotInfo); if (ckrv != CKR_OK) { nssSession_ExitMonitor(session); + token->name[0] = 0; return PR_FALSE; } slot->ckFlags = slotInfo.flags; @@ -243,6 +251,7 @@ nssToken_IsPresent session->handle = CK_INVALID_SESSION; } nssSession_ExitMonitor(session); + token->name[0] = 0; return PR_FALSE; } /* token is present, use the session info to determine if the card @@ -265,12 +274,32 @@ nssToken_IsPresent /* token has been removed, need to refresh with new session */ nssrv = nssSlot_Refresh(slot); if (nssrv != PR_SUCCESS) { + token->name[0] = 0; return PR_FALSE; } return PR_TRUE; } } +NSS_IMPLEMENT PRBool +nssToken_HasCrls +( + NSSToken *tok +) +{ + return !tok->hasNoCrls; +} + +NSS_IMPLEMENT PRStatus +nssToken_SetHasCrls +( + NSSToken *tok +) +{ + tok->hasNoCrls = PR_FALSE; + return PR_SUCCESS; +} + NSS_IMPLEMENT NSSItem * nssToken_Digest ( diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk index 4878c39e6..c18b1c6ae 100644 --- a/security/nss/lib/nss/config.mk +++ b/security/nss/lib/nss/config.mk @@ -91,3 +91,9 @@ SHARED_LIBRARY_DIRS = \ ../base \ $(NULL) + +ifeq ($(OS_TARGET),SunOS) +# The -R '$ORIGIN' linker option instructs libnss3.so to search for its +# dependencies (libsoftokn3.so) in the same directory where it resides. +MKSHLIB += -R '$$ORIGIN' +endif diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index 2f5221385..e3201fe54 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -560,11 +560,12 @@ PK11_DestroyPBEParams; ;+}; ;+NSS_3.4 { # NSS 3.4 release ;+ global: -SECMOD_LoadModule; -SECMOD_GetModuleSpecList; +SECMOD_AddNewModuleEx; +SECMOD_DeleteModule; SECMOD_FreeModuleSpecList; +SECMOD_GetModuleSpecList; +SECMOD_LoadModule; SECMOD_UpdateModule; -SECMOD_DeleteModule; ;+# for PKCS #12 PK11_RawPBEKeyGen; ;+# for PSM @@ -587,8 +588,8 @@ CERT_FindUserCertsByUsage; CERT_GetCertChainFromCert; CERT_GetOCSPAuthorityInfoAccessLocation; CERT_KeyFromDERCrl; -CERT_NicknameStringsFromCertList; CERT_MakeCANickname; +CERT_NicknameStringsFromCertList; CERT_VerifySignedData; DER_Encode; HASH_Begin; @@ -631,24 +632,25 @@ NSS_Get_SEC_NullTemplate; NSS_Get_SEC_SignedCertificateTemplate; NSS_Get_SEC_UTF8StringTemplate; ;+# for JSS -PK11_ImportDERPrivateKeyInfoAndReturnKey; -PK11_ImportPublicKey; -PK11_ImportPrivateKeyInfoAndReturnKey; -PK11_ImportSymKeyWithFlags; -PK11_ListPublicKeysInSlot; -PK11_ListPrivKeysInSlot; -PK11_ListFixedKeysInSlot; PK11_DeleteTokenPrivateKey; PK11_DeleteTokenPublicKey; PK11_DeleteTokenSymKey; PK11_GetNextSymKey; PK11_GetPQGParamsFromPrivateKey; -PK11_GetPublicKeyNickname; PK11_GetPrivateKeyNickname; +PK11_GetPublicKeyNickname; PK11_GetSymKeyNickname; -PK11_SetSymKeyNickname; -PK11_SetPublicKeyNickname; +PK11_ImportDERPrivateKeyInfoAndReturnKey; +PK11_ImportPrivateKeyInfoAndReturnKey; +PK11_ImportPublicKey; +PK11_ImportSymKeyWithFlags; +PK11_ListFixedKeysInSlot; +PK11_ListPrivKeysInSlot; +PK11_ListPublicKeysInSlot; +PK11_ProtectedAuthenticationPath; PK11_SetPrivateKeyNickname; +PK11_SetPublicKeyNickname; +PK11_SetSymKeyNickname; SECKEY_DecodeDERSubjectPublicKeyInfo; SECKEY_DestroyPublicKeyList; ;+# for debugging diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c index c069119f7..f85cb78b7 100644 --- a/security/nss/lib/nss/nssinit.c +++ b/security/nss/lib/nss/nssinit.c @@ -261,6 +261,8 @@ static const char *dllname = "nssckbi.dll"; #elif defined(HPUX) "libnssckbi.sl"; +#elif defined(DARWIN) + "libnssckbi.dylib"; #elif defined(XP_UNIX) || defined(XP_BEOS) "libnssckbi.so"; #elif defined(XP_MAC) @@ -387,7 +389,7 @@ loser: STAN_GetDefaultTrustDomain()); #ifndef XP_MAC /* only servers need this. We currently do not have a mac server */ - if ((!readOnly) && (!noModDB) && (!noCertDB) && (!noRootInit)) { + if ((!noModDB) && (!noCertDB) && (!noRootInit)) { if (!SECMOD_HasRootCerts()) { nss_FindExternalRoot(configdir); } diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c index 742335c9d..f6645c463 100644 --- a/security/nss/lib/pk11wrap/dev3hack.c +++ b/security/nss/lib/pk11wrap/dev3hack.c @@ -151,9 +151,19 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot) rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot); rvToken->slot->token = rvToken; rvToken->defaultSession->slot = rvToken->slot; + rvToken->arena = td->arena; return rvToken; } +NSS_IMPLEMENT void +nssToken_UpdateName(NSSToken *token) +{ + if (!token) { + return; + } + token->name = nssUTF8_Duplicate(token->pk11slot->token_name,token->arena); +} + NSS_IMPLEMENT PRBool nssSlot_IsPermanent ( @@ -164,6 +174,23 @@ nssSlot_IsPermanent } NSS_IMPLEMENT PRStatus +nssToken_Refresh(NSSToken *token) +{ + PK11SlotInfo *nss3slot; + + if (!token) { + return PR_SUCCESS; + } + nss3slot = token->pk11slot; + token->defaultSession = nssSession_ImportNSS3Session(token->slot->arena, + nss3slot->session, + nss3slot->sessionLock, + nss3slot->defRWSession); + nssToken_DestroyCertList(token); + return nssToken_LoadCerts(token); +} + +NSS_IMPLEMENT PRStatus nssSlot_Refresh ( NSSSlot *slot @@ -173,15 +200,11 @@ nssSlot_Refresh if (PK11_InitToken(nss3slot, PR_FALSE) != SECSuccess) { return PR_FAILURE; } - slot->token->defaultSession = nssSession_ImportNSS3Session(slot->arena, - nss3slot->session, - nss3slot->sessionLock, - nss3slot->defRWSession); - nssToken_DestroyCertList(slot->token); - return nssToken_LoadCerts(slot->token); + return nssToken_Refresh(slot->token); } + NSSTrustDomain * nssToken_GetTrustDomain(NSSToken *token) { diff --git a/security/nss/lib/pk11wrap/dev3hack.h b/security/nss/lib/pk11wrap/dev3hack.h index 3b8f1abf8..a24eacd8f 100644 --- a/security/nss/lib/pk11wrap/dev3hack.h +++ b/security/nss/lib/pk11wrap/dev3hack.h @@ -45,6 +45,12 @@ PR_BEGIN_EXTERN_C NSS_EXTERN NSSToken * nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot); +NSS_EXTERN void +nssToken_UpdateName(NSSToken *); + +NSS_EXTERN PRStatus +nssToken_Refresh(NSSToken *); + NSSTrustDomain * nssToken_GetTrustDomain(NSSToken *token); @@ -52,9 +58,6 @@ void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst); NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl); -NSS_EXTERN void -nssToken_DestroyCertList(NSSToken *token); - NSS_IMPLEMENT PRStatus nssToken_LoadCerts(NSSToken *token); diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 9bae7c27c..9611ff06f 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -101,10 +101,6 @@ static PRStatus convert_and_cache_cert(NSSCertificate *c, void *arg) * a CERTCertificate and fed into the callback. */ nssrv = nssTrustDomain_AddCertsToCache(td, &c, 1); - if (!nssList_Get(nss3cb->cached, c)) { - nssCertificate_AddRef(c); - nssList_Add(nss3cb->cached, c); - } /* This is why the hack of copying the cert was done above. The pointer * c passed to this function is provided by retrieve_cert. That function * will destroy the pointer once this function returns. Since c is a local @@ -116,13 +112,11 @@ static PRStatus convert_and_cache_cert(NSSCertificate *c, void *arg) * destroy the reference to the copy, the callback will use the reference * to the cached entry, and everyone should be happy. */ - if (cp == c) { - /* However, if the call to add c to the cache was successful, cp is - * now an extra copy within this function and needs to be destroyed. - */ - NSSCertificate_Destroy(cp); - } nssrv = convert_cert(c, arg); + /* This function owns a reference to the cert, either from the AddRef + * or by getting it from the cache. + */ + CERT_DestroyCertificate(STAN_GetCERTCertificate(c)); return nssrv; } @@ -708,23 +702,11 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey) CK_OBJECT_HANDLE handle = privKey->pkcs11ID; CK_OBJECT_HANDLE certID = PK11_MatchItem(slot,handle,CKO_CERTIFICATE); - SECStatus rv; CERTCertificate *cert; if (certID == CK_INVALID_HANDLE) { - /* couldn't find it on the card, look in our data base */ - SECItem derSubject; - - rv = PK11_ReadAttribute(slot, handle, CKA_SUBJECT, NULL, - &derSubject); - if (rv != SECSuccess) { - PORT_SetError(SSL_ERROR_NO_CERTIFICATE); - return NULL; - } - - cert = CERT_FindCertByName(CERT_GetDefaultCertDB(),&derSubject); - PORT_Free(derSubject.data); - return cert; + PORT_SetError(SSL_ERROR_NO_CERTIFICATE); + return NULL; } cert = PK11_MakeCertFromHandle(slot,certID,NULL); return (cert); @@ -1245,7 +1227,7 @@ get_newest_cert(NSSCertificate *c, void *arg) dc = nssCertificate_GetDecoding(c); founddc = nssCertificate_GetDecoding(*cfound); if (!founddc->isNewerThan(founddc, dc)) { - NSSCertificate_Destroy(*cfound); + CERT_DestroyCertificate(STAN_GetCERTCertificate(*cfound)); *cfound = nssCertificate_AddRef(c); } return PR_SUCCESS; @@ -1304,8 +1286,9 @@ filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname) cert != (NSSCertificate *)NULL; cert = (NSSCertificate *)nssListIterator_Next(certs)) { - if (!cert->nickname) continue; - if (nssUTF8_Equal(cert->nickname, nickname, &nssrv)) { + NSSUTF8 *tokenNick = NSSCertificate_GetNickname(cert, token); + if (!tokenNick) continue; + if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) { nssList_Add(rvList, nssCertificate_AddRef(cert)); } } @@ -1395,6 +1378,10 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { nssTokenCertSearch search; struct token_cbstr token_cb; nssList *certList; + + if (!PK11_IsPresent(slot)) { + return NULL; + } if (!PK11_IsFriendly(slot)) { if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { PK11_FreeSlot(slot); @@ -1402,7 +1389,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { } } /* find best cert on token */ - if (!nssToken_SearchCerts(token)) { + if (!nssToken_SearchCerts(token, NULL)) { /* token certs are in cache, filter the list of token certs to * match the nickname */ @@ -1428,16 +1415,14 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { search.cbarg = &token_cb; search.cached = certList; search.searchType = nssTokenSearchType_TokenOnly; - /* then filter the list of cached certs for only those on the - * token - */ - nssCertificateList_DoCallback(certList, - token_callback, - &token_cb); /* now search the token */ nssToken_TraverseCertificatesByNickname(token, NULL, (NSSUTF8 *)nickname, &search); + /* filter the list of cached certs for only those on the token */ + nssCertificateList_DoCallback(certList, + token_callback, + &token_cb); } if (certList) { nssList_Clear(certList, cert_destructor); @@ -1445,7 +1430,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { } /* if it wasn't found, repeat the process for email address */ if (!cert) { - if (!nssToken_SearchCerts(token)) { + if (!nssToken_SearchCerts(token, NULL)) { certList = filter_token_certs_email(token, nickname); if (certList) { nssCertificateList_DoCallback(certList, @@ -1460,12 +1445,12 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { nickname, certList); search.cached = certList; - nssCertificateList_DoCallback(certList, - token_callback, - &token_cb); nssToken_TraverseCertificatesByEmail(token, NULL, (NSSASCII7 *)nickname, &search); + nssCertificateList_DoCallback(certList, + token_callback, + &token_cb); } if (certList) { nssList_Clear(certList, cert_destructor); @@ -1542,7 +1527,11 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) { *delimit = '\0'; /* find token by name */ token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName); - slot = PK11_ReferenceSlot(token->pk11slot); + if (token) { + slot = PK11_ReferenceSlot(token->pk11slot); + } else { + slot = NULL; + } *delimit = ':'; } else { slot = PK11_GetInternalKeySlot(); @@ -1558,7 +1547,7 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) { return NULL; } } - if (!nssToken_SearchCerts(token)) { + if (!nssToken_SearchCerts(token, NULL)) { nameList = filter_token_certs_nickname(token, nickname); } else { nameList = nssList_Create(NULL, PR_FALSE); @@ -2667,7 +2656,7 @@ filter_list_for_token_certs(nssList *certList, NSSToken *token) if (!isToken) { /* safe since iterator is copied */ nssList_Remove(certList, c); - NSSCertificate_Destroy(c); + CERT_DestroyCertificate(STAN_GetCERTCertificate(c)); } } nssListIterator_Finish(certs); @@ -2718,7 +2707,7 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, td = STAN_GetDefaultTrustDomain(); NSSITEM_FROM_SECITEM(&subject, &cert->derSubject); token = PK11Slot_GetNSSToken(slot); - if (!nssToken_SearchCerts(token)) { + if (!nssToken_SearchCerts(token, NULL)) { subjectList = filter_token_certs_subject(token, &subject); if (subjectList) { nssrv = nssCertificateList_DoCallback(subjectList, @@ -2731,18 +2720,18 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, } (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, subjectList); - filter_list_for_token_certs(subjectList, token); /* set the search criteria */ search.callback = convert_and_cache_cert; search.cbarg = &pk11cb; search.cached = subjectList; search.searchType = nssTokenSearchType_TokenOnly; pk11cb.cached = subjectList; - nssrv = nssCertificateList_DoCallback(subjectList, - convert_cert, &pk11cb); + nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, + &subject, &search); if (nssrv == PR_SUCCESS) { - nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, - &subject, &search); + filter_list_for_token_certs(subjectList, token); + nssrv = nssCertificateList_DoCallback(subjectList, + convert_cert, &pk11cb); } } if (subjectList) { @@ -2809,7 +2798,7 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, } td = STAN_GetDefaultTrustDomain(); token = PK11Slot_GetNSSToken(slot); - if (!nssToken_SearchCerts(token)) { + if (!nssToken_SearchCerts(token, NULL)) { nameList = filter_token_certs_nickname(token, nick); if (nameList) { nssrv = nssCertificateList_DoCallback(nameList, @@ -2818,18 +2807,18 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, } else { nameList = nssList_Create(NULL, PR_FALSE); (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList); - filter_list_for_token_certs(nameList, token); /* set the search criteria */ search.callback = convert_and_cache_cert; search.cbarg = &pk11cb; search.cached = nameList; search.searchType = nssTokenSearchType_TokenOnly; pk11cb.cached = nameList; - nssrv = nssCertificateList_DoCallback(nameList, - convert_cert, &pk11cb); + nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, + nick, &search); if (nssrv == PR_SUCCESS) { - nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, - nick, &search); + filter_list_for_token_certs(nameList, token); + nssrv = nssCertificateList_DoCallback(nameList, + convert_cert, &pk11cb); } } if (nameList) { @@ -2880,7 +2869,7 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot, pk11cb.callback = callback; pk11cb.arg = arg; tok = PK11Slot_GetNSSToken(slot); - if (!nssToken_SearchCerts(tok)) { + if (!nssToken_SearchCerts(tok, NULL)) { certList = tok->certList; nssrv = nssCertificateList_DoCallback(certList, convert_cert, &pk11cb); } else { @@ -2889,17 +2878,17 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot, return SECFailure; } (void *)nssTrustDomain_GetCertsFromCache(td, certList); - filter_list_for_token_certs(certList, tok); /* set the search criteria */ search.callback = convert_and_cache_cert; search.cbarg = &pk11cb; search.cached = certList; search.searchType = nssTokenSearchType_TokenOnly; pk11cb.cached = certList; - nssrv = nssCertificateList_DoCallback(certList, - convert_cert, &pk11cb); + nssrv = nssToken_TraverseCertificates(tok, NULL, &search); if (nssrv == PR_SUCCESS) { - nssrv = nssToken_TraverseCertificates(tok, NULL, &search); + filter_list_for_token_certs(certList, tok); + nssrv = nssCertificateList_DoCallback(certList, + convert_cert, &pk11cb); } nssList_Clear(certList, cert_destructor); nssList_Destroy(certList); @@ -2975,7 +2964,13 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert, NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); tok = PK11Slot_GetNSSToken(slot); NSSITEM_FROM_SECITEM(&derCert, &cert->derCert); - if (!nssToken_SearchCerts(tok)) { + if (!PK11_IsFriendly(slot)) { + if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { + PK11_FreeSlot(slot); + return NULL; + } + } + if (!nssToken_SearchCerts(tok, NULL)) { c = filter_token_certs_DER(tok, &derCert); } else { c = nssTrustDomain_GetCertByDERFromCache(td, &derCert); @@ -3680,7 +3675,7 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) */ SECItem * PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, - SECItem *name, int type) + SECItem *name, int type, char **url) { CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL; CK_ATTRIBUTE theTemplate[] = { @@ -3688,7 +3683,10 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, { CKA_CLASS, NULL, 0 }, { CKA_NETSCAPE_KRL, NULL, 0 }, }; - CK_ATTRIBUTE crlData = { CKA_VALUE, NULL, 0 }; + CK_ATTRIBUTE crlData[] = { + { CKA_VALUE, NULL, 0 }, + { CKA_NETSCAPE_URL, NULL, 0 }, + }; /* if you change the array, change the variable below as well */ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]); CK_BBOOL ck_true = CK_TRUE; @@ -3712,6 +3710,9 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, /* loop through all the fortezza tokens */ for (le = list->head; le; le = le->next) { + if (le->slot->nssToken && !nssToken_HasCrls(le->slot->nssToken)) { + continue; + } crlh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize); if (crlh != CK_INVALID_HANDLE) { *slot = PK11_ReferenceSlot(le->slot); @@ -3725,7 +3726,7 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, PORT_SetError(SEC_ERROR_NO_KRL); return NULL; } - crv = PK11_GetAttributes(NULL,*slot,crlh,&crlData,1); + crv = PK11_GetAttributes(NULL,*slot,crlh,crlData,2); if (crv != CKR_OK) { PORT_SetError(PK11_MapError (crv)); goto loser; @@ -3736,17 +3737,27 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, goto loser; } - derCrl->data = crlData.pValue; - derCrl->len = crlData.ulValueLen; + derCrl->data = crlData[0].pValue; + derCrl->len = crlData[0].ulValueLen; if (crlHandle) { *crlHandle = crlh; } + if ((url) && crlData[1].ulValueLen != 0) { + /* make sure it's a null terminated string */ + *url = PORT_ZAlloc (crlData[1].ulValueLen+1); + if (*url) { + PORT_Memcpy(*url,crlData[1].pValue,crlData[1].ulValueLen); + } + } + + loser: if (!derCrl) { - if (crlData.pValue) PORT_Free(crlData.pValue); + if (crlData[0].pValue) PORT_Free(crlData[0].pValue); } + if (crlData[1].pValue) PORT_Free(crlData[1].pValue); return derCrl; } @@ -3776,12 +3787,14 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name, PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++; PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ? &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++; - PK11_SETATTRS(attrs, CKA_NETSCAPE_URL, url, PORT_Strlen(url)+1); attrs++; + if (url) { + PK11_SETATTRS(attrs, CKA_NETSCAPE_URL, url, PORT_Strlen(url)+1); attrs++; + } PK11_SETATTRS(attrs, CKA_VALUE,crl->data,crl->len); attrs++; PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true,sizeof(CK_BBOOL)); attrs++; tsize = attrs - &theTemplate[0]; - PORT_Assert(tsize >= sizeof(theTemplate)/sizeof(theTemplate[0])); + PORT_Assert(tsize <= sizeof(theTemplate)/sizeof(theTemplate[0])); rwsession = PK11_GetRWSession(slot); if (rwsession == CK_INVALID_SESSION) { @@ -3796,6 +3809,10 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name, } PK11_RestoreROSession(slot,rwsession); + + if (slot->nssToken) { + nssToken_SetHasCrls(slot->nssToken); + } return crlh; } diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h index 3ca29cc65..af3272f08 100644 --- a/security/nss/lib/pk11wrap/pk11func.h +++ b/security/nss/lib/pk11wrap/pk11func.h @@ -153,6 +153,7 @@ PRBool PK11_NeedLogin(PK11SlotInfo *slot); PRBool PK11_IsFriendly(PK11SlotInfo *slot); PRBool PK11_IsHW(PK11SlotInfo *slot); PRBool PK11_NeedUserInit(PK11SlotInfo *slot); +PRBool PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot); int PK11_GetSlotSeries(PK11SlotInfo *slot); int PK11_GetCurrentWrapIndex(PK11SlotInfo *slot); unsigned long PK11_GetDefaultFlags(PK11SlotInfo *slot); @@ -530,7 +531,7 @@ PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key); SECItem * PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *handle, - SECItem *derName, int type); + SECItem *derName, int type, char **url); CK_OBJECT_HANDLE PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c index 530548c36..f58fd60cb 100644 --- a/security/nss/lib/pk11wrap/pk11pqg.c +++ b/security/nss/lib/pk11wrap/pk11pqg.c @@ -34,20 +34,13 @@ * PKCS #11. */ +#include "pk11func.h" +#include "secmod.h" +#include "secmodi.h" +#include "pkcs11t.h" #include "pk11pqg.h" +#include "secerr.h" -/* Generate PQGParams and PQGVerify structs. - * Length of seed and length of h both equal length of P. - * All lengths are specified by "j", according to the table above. - */ -extern SECStatus -PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) { -#ifdef notdef - return PQG_ParamGen(j, pParams, pVfy); -#else - return SECFailure; -#endif -} /* Generate PQGParams and PQGVerify structs. * Length of P specified by j. Length of h will match length of P. @@ -56,12 +49,142 @@ PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) { */ extern SECStatus PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, - PQGParams **pParams, PQGVerify **pVfy) { -#ifdef notdef - return PQG_ParamGenSeedLen(j, seedBytes, pParams, pVfy); -#else + PQGParams **pParams, PQGVerify **pVfy) +{ + PK11SlotInfo *slot = NULL; + CK_ATTRIBUTE genTemplate[5]; + CK_ATTRIBUTE *attrs = genTemplate; + int count = sizeof(genTemplate)/sizeof(genTemplate[0]); + CK_MECHANISM mechanism; + CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE; + CK_RV crv; + CK_BBOOL cktrue = CK_TRUE; + CK_ATTRIBUTE pTemplate[] = { + { CKA_PRIME, NULL, 0 }, + { CKA_SUBPRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + }; + CK_ATTRIBUTE vTemplate[] = { + { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, + { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, + { CKA_NETSCAPE_PQG_H, NULL, 0 }, + }; + int pTemplateCount = sizeof(pTemplate)/sizeof(pTemplate[0]); + int vTemplateCount = sizeof(vTemplate)/sizeof(vTemplate[0]); + PRArenaPool *parena = NULL; + PRArenaPool *varena = NULL; + PQGParams *params = NULL; + PQGVerify *verify = NULL; + CK_ULONG primeBits = j; + CK_ULONG seedBits = seedBytes*8; + + *pParams = NULL; + *pVfy = NULL; + + PK11_SETATTRS(attrs, CKA_PRIME_BITS,&primeBits,sizeof(primeBits)); attrs++; + if (seedBits != 0) { + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS, + &seedBits, sizeof(seedBits)); attrs++; + } + count = attrs - genTemplate; + PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); + + slot = PK11_GetInternalSlot(); + if (slot == NULL) { + /* set error */ + goto loser; + } + + /* Initialize the Key Gen Mechanism */ + mechanism.mechanism = CKM_DSA_PARAMETER_GEN; + mechanism.pParameter = NULL; + mechanism.ulParameterLen = 0; + + PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB(slot)->C_GenerateKey(slot->session, + &mechanism, genTemplate, count, &objectID); + PK11_ExitSlotMonitor(slot); + + if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + goto loser; + } + + parena = PORT_NewArena(60); + crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount); + if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + goto loser; + } + + + params = (PQGParams *)PORT_ArenaAlloc(parena,sizeof(PQGParams)); + if (params == NULL) { + goto loser; + } + + /* fill in Params */ + params->arena = parena; + params->prime.data = pTemplate[0].pValue; + params->prime.len = pTemplate[0].ulValueLen; + params->subPrime.data = pTemplate[1].pValue; + params->subPrime.len = pTemplate[1].ulValueLen; + params->base.data = pTemplate[2].pValue; + params->base.len = pTemplate[2].ulValueLen; + + + varena = PORT_NewArena(60); + crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount); + if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + goto loser; + } + + + verify = (PQGVerify *)PORT_ArenaAlloc(varena,sizeof(PQGVerify)); + if (verify == NULL) { + goto loser; + } + /* fill in Params */ + verify->arena = varena; + verify->counter = (unsigned int)(*(CK_ULONG*)vTemplate[0].pValue); + verify->seed.data = vTemplate[1].pValue; + verify->seed.len = vTemplate[1].ulValueLen; + verify->h.data = vTemplate[2].pValue; + verify->h.len = vTemplate[2].ulValueLen; + + PK11_DestroyObject(slot,objectID); + PK11_FreeSlot(slot); + + *pParams = params; + *pVfy = verify; + + return SECSuccess; + +loser: + if (objectID != CK_INVALID_HANDLE) { + PK11_DestroyObject(slot,objectID); + } + if (parena != NULL) { + PORT_FreeArena(parena,PR_FALSE); + } + if (varena != NULL) { + PORT_FreeArena(varena,PR_FALSE); + } + if (slot) { + PK11_FreeSlot(slot); + } return SECFailure; -#endif +} + +/* Generate PQGParams and PQGVerify structs. + * Length of seed and length of h both equal length of P. + * All lengths are specified by "j", according to the table above. + */ +extern SECStatus +PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) +{ + return PK11_PQG_ParamGenSeedLen(j, 0, pParams, pVfy); } /* Test PQGParams for validity as DSS PQG values. @@ -73,31 +196,80 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, * If return value is SECSuccess, then *pResult has these meanings: * SECSuccess: PQGParams are valid. * SECFailure: PQGParams are invalid. - * - * Verify the following 12 facts about PQG counter SEED g and h - * 1. Q is 160 bits long. - * 2. P is one of the 9 valid lengths. - * 3. G < P - * 4. P % Q == 1 - * 5. Q is prime - * 6. P is prime - * Steps 7-12 are done only if the optional PQGVerify is supplied. - * 7. counter < 4096 - * 8. g >= 160 and g < 2048 (g is length of seed in bits) - * 9. Q generated from SEED matches Q in PQGParams. - * 10. P generated from (L, counter, g, SEED, Q) matches P in PQGParams. - * 11. 1 < h < P-1 - * 12. G generated from h matches G in PQGParams. */ extern SECStatus -PK11_PQG_VerifyParams(const PQGParams *params, - const PQGVerify *vfy, SECStatus *result) { -#ifdef notdef - return PQG_VerifyParams(params, vfy, result); -#else - return SECFailure; -#endif +PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy, + SECStatus *result) +{ + CK_ATTRIBUTE keyTempl[] = { + { CKA_CLASS, NULL, 0 }, + { CKA_KEY_TYPE, NULL, 0 }, + { CKA_PRIME, NULL, 0 }, + { CKA_SUBPRIME, NULL, 0 }, + { CKA_BASE, NULL, 0 }, + { CKA_TOKEN, NULL, 0 }, + { CKA_NETSCAPE_PQG_COUNTER, NULL, 0 }, + { CKA_NETSCAPE_PQG_SEED, NULL, 0 }, + { CKA_NETSCAPE_PQG_H, NULL, 0 }, + }; + CK_ATTRIBUTE *attrs; + CK_BBOOL ckfalse = CK_FALSE; + CK_OBJECT_CLASS class = CKO_KG_PARAMETERS; + CK_KEY_TYPE keyType = CKK_DSA; + SECStatus rv = SECSuccess; + PK11SlotInfo *slot; + int keyCount; + CK_OBJECT_HANDLE objectID; + CK_ULONG counter; + CK_RV crv; + + attrs = keyTempl; + PK11_SETATTRS(attrs, CKA_CLASS, &class, sizeof(class)); attrs++; + PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; + PK11_SETATTRS(attrs, CKA_PRIME, params->prime.data, + params->prime.len); attrs++; + PK11_SETATTRS(attrs, CKA_SUBPRIME, params->subPrime.data, + params->subPrime.len); attrs++; + PK11_SETATTRS(attrs, CKA_BASE,params->base.data,params->base.len); attrs++; + PK11_SETATTRS(attrs, CKA_TOKEN, &ckfalse, sizeof(ckfalse)); attrs++; + if (vfy) { + counter = vfy->counter; + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER, + &counter, sizeof(counter)); attrs++; + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED, + vfy->seed.data, vfy->seed.len); attrs++; + PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H, + vfy->h.data, vfy->h.len); attrs++; + } + + keyCount = attrs - keyTempl; + PORT_Assert(keyCount <= sizeof(keyTempl)/sizeof(keyTempl[0])); + + + slot = PK11_GetInternalSlot(); + if (slot == NULL) { + return SECFailure; + } + + PK11_EnterSlotMonitor(slot); + crv = PK11_GETTAB(slot)->C_CreateObject(slot->session, keyTempl, keyCount, + &objectID); + PK11_ExitSlotMonitor(slot); + + /* throw away the keys, we only wanted the return code */ + PK11_DestroyObject(slot,objectID); + PK11_FreeSlot(slot); + + *result = SECSuccess; + if (crv == CKR_ATTRIBUTE_VALUE_INVALID) { + *result = SECFailure; + } else if (crv != CKR_OK) { + PORT_SetError( PK11_MapError(crv) ); + rv = SECFailure; + } + return rv; + } diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index 76b63971c..b4c557496 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -51,6 +51,9 @@ #include "secerr.h" /*#include "secpkcs5.h" */ +#include "dev3hack.h" +#include "pki3hack.h" + /************************************************************* * local static and global data @@ -423,6 +426,7 @@ PK11_NewSlotInfo(void) slot->needLogin = PR_FALSE; slot->hasRandom = PR_FALSE; slot->defRWSession = PR_FALSE; + slot->protectedAuthPath = PR_FALSE; slot->flags = 0; slot->session = CK_INVALID_SESSION; slot->slotID = 0; @@ -443,6 +447,7 @@ PK11_NewSlotInfo(void) slot->minPassword = 0; slot->maxPassword = 0; slot->hasRootCerts = PR_FALSE; + slot->nssToken = NULL; return slot; } @@ -642,6 +647,11 @@ pk11_CheckPassword(PK11SlotInfo *slot,char *pw) SECStatus rv; int64 currtime = PR_Now(); + if (slot->protectedAuthPath) { + len = 0; + pw = NULL; + } + PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER, (unsigned char *)pw,len); @@ -677,6 +687,11 @@ PK11_CheckUserPassword(PK11SlotInfo *slot,char *pw) SECStatus rv; int64 currtime = PR_Now(); + if (slot->protectedAuthPath) { + len = 0; + pw = NULL; + } + /* force a logout */ PK11_EnterSlotMonitor(slot); PK11_GETTAB(slot)->C_Logout(slot->session); @@ -711,6 +726,10 @@ PK11_Logout(PK11SlotInfo *slot) PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_Logout(slot->session); PK11_ExitSlotMonitor(slot); + if (slot->nssToken && !PK11_IsFriendly(slot)) { + /* If the slot certs are not public readable, destroy them */ + nssToken_DestroyCertList(slot->nssToken, PR_TRUE); + } if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); return SECFailure; @@ -908,6 +927,11 @@ PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw) rwsession = PK11_GetRWSession(slot); if (rwsession == CK_INVALID_SESSION) return rv; + if (slot->protectedAuthPath) { + len = 0; + ssopw = NULL; + } + /* check the password */ crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO, (unsigned char *)ssopw,len); @@ -967,6 +991,13 @@ PK11_InitPin(PK11SlotInfo *slot,char *ssopw, char *userpw) rwsession = PK11_GetRWSession(slot); if (rwsession == CK_INVALID_SESSION) goto done; + if (slot->protectedAuthPath) { + len = 0; + ssolen = 0; + ssopw = NULL; + userpw = NULL; + } + /* check the password */ crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO, (unsigned char *)ssopw,ssolen); @@ -1114,6 +1145,10 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx) } if (rv == SECSuccess) { rv = pk11_CheckVerifyTest(slot); + if (rv == SECSuccess && slot->nssToken && !PK11_IsFriendly(slot)) { + /* notify stan about the login if certs are not public readable */ + nssToken_LoadCerts(slot->nssToken); + } } else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD); return rv; } @@ -1678,12 +1713,17 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE); slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); + slot->protectedAuthPath = + ((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) + ? PR_TRUE : PR_FALSE); tmp = PK11_MakeString(NULL,slot->token_name, (char *)tokenInfo.label, sizeof(tokenInfo.label)); slot->minPassword = tokenInfo.ulMinPinLen; slot->maxPassword = tokenInfo.ulMaxPinLen; PORT_Memcpy(slot->serial,tokenInfo.serialNumber,sizeof(slot->serial)); + nssToken_UpdateName(slot->nssToken); + slot->defRWSession = (PRBool)((!slot->readOnly) && (tokenInfo.ulMaxSessionCount == 1)); rv = PK11_ReadMechanismList(slot); @@ -1743,6 +1783,8 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); } + nssToken_Refresh(slot->nssToken); + if (!(slot->needLogin)) { return pk11_CheckVerifyTest(slot); } @@ -1784,6 +1826,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) } } } + return SECSuccess; } @@ -1902,6 +1945,10 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts) return PR_TRUE; } + if (slot->nssToken) { + return nssToken_IsPresent(slot->nssToken); + } + /* removable slots have a flag that says they are present */ if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); if (PK11_GETTAB(slot)->C_GetSlotInfo(slot->slotID,&slotInfo) != CKR_OK) { @@ -1993,13 +2040,20 @@ PK11_GetModule(PK11SlotInfo *slot) return slot->module; } -/* returnt the default flags of a slot */ +/* return the default flags of a slot */ unsigned long PK11_GetDefaultFlags(PK11SlotInfo *slot) { return slot->defaultFlags; } +/* Does this slot have a protected pin path? */ +PRBool +PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot) +{ + return slot->protectedAuthPath; +} + /* * we can initialize the password if 1) The toke is not inited * (need login == true and see need UserInit) or 2) the token has diff --git a/security/nss/lib/pk11wrap/pk11util.c b/security/nss/lib/pk11wrap/pk11util.c index c72294ef6..04feb3059 100644 --- a/security/nss/lib/pk11wrap/pk11util.c +++ b/security/nss/lib/pk11wrap/pk11util.c @@ -408,9 +408,11 @@ PK11_IsFIPS(void) /* combines NewModule() & AddModule */ /* give a string for the module name & the full-path for the dll, */ /* installs the PKCS11 module & update registry */ -SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath, +SECStatus SECMOD_AddNewModuleEx(char* moduleName, char* dllPath, unsigned long defaultMechanismFlags, - unsigned long cipherEnableFlags) { + unsigned long cipherEnableFlags, + char* modparms, + char* nssparms) { SECMODModule *module; SECStatus result = SECFailure; int s,i; @@ -418,7 +420,7 @@ SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath, PR_SetErrorText(0, NULL); - module = SECMOD_CreateModule(dllPath,moduleName,NULL, NULL); + module = SECMOD_CreateModule(dllPath,moduleName, modparms, nssparms); if (module->dllName != NULL) { if (module->dllName[0] != 0) { @@ -455,6 +457,15 @@ SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath, return result; } +SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath, + unsigned long defaultMechanismFlags, + unsigned long cipherEnableFlags) +{ + return SECMOD_AddNewModuleEx(moduleName, dllPath, defaultMechanismFlags, + cipherEnableFlags, + NULL, NULL); /* don't pass module or nss params */ +} + SECStatus SECMOD_UpdateModule(SECMODModule *module) { SECStatus result; diff --git a/security/nss/lib/pk11wrap/secmod.h b/security/nss/lib/pk11wrap/secmod.h index ad3b7e024..51920dbb9 100644 --- a/security/nss/lib/pk11wrap/secmod.h +++ b/security/nss/lib/pk11wrap/secmod.h @@ -113,6 +113,12 @@ extern SECStatus SECMOD_DeleteInternalModule(char *name); extern SECStatus SECMOD_AddNewModule(char* moduleName, char* dllPath, unsigned long defaultMechanismFlags, unsigned long cipherEnableFlags); +extern SECStatus SECMOD_AddNewModuleEx(char* moduleName, char* dllPath, + unsigned long defaultMechanismFlags, + unsigned long cipherEnableFlags, + char* modparms, + char* nssparms); + /* database/memory management */ extern SECMODModule *SECMOD_GetInternalModule(void); extern SECMODModule *SECMOD_ReferenceModule(SECMODModule *module); diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h index a10f97c77..9d3919903 100644 --- a/security/nss/lib/pk11wrap/secmodti.h +++ b/security/nss/lib/pk11wrap/secmodti.h @@ -129,6 +129,7 @@ struct PK11SlotInfoStr { PRBool hasRootTrust; PRBool hasRSAInfo; CK_FLAGS RSAInfoFlags; + PRBool protectedAuthPath; /* for Stan */ NSSToken *nssToken; }; diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index 93db6807f..f9dc9a7e3 100644 --- a/security/nss/lib/pki/certificate.c +++ b/security/nss/lib/pki/certificate.c @@ -92,6 +92,39 @@ NSSCertificate_Destroy return PR_SUCCESS; } +NSS_IMPLEMENT NSSUTF8 * +NSSCertificate_GetNickname +( + NSSCertificate *c, + NSSToken *tokenOpt +) +{ + NSSUTF8 *rvNick = NULL; + nssCryptokiInstance *instance; + nssListIterator *instances = c->object.instances; + if (c->object.cryptoContext) { + return c->object.tempName; + } + for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); + instance != (nssCryptokiInstance *)NULL; + instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) + { + if (tokenOpt) { + if (instance->token == tokenOpt) { + /* take the nickname on the given token */ + rvNick = instance->label; + break; + } + } else { + /* take the first one */ + rvNick = instance->label; + break; + } + } + nssListIterator_Finish(instances); + return rvNick; +} + NSS_IMPLEMENT PRStatus NSSCertificate_DeleteStoredObject ( @@ -862,3 +895,51 @@ nssCertificateList_AddReferences (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL); } +NSS_IMPLEMENT NSSTrust * +nssTrust_AddRef +( + NSSTrust *trust +) +{ + if (trust) { + nssPKIObject_AddRef(&trust->object); + } + return trust; +} + +NSS_IMPLEMENT PRStatus +nssTrust_Destroy +( + NSSTrust *trust +) +{ + if (trust) { + (void)nssPKIObject_Destroy(&trust->object); + } + return PR_SUCCESS; +} + +NSS_IMPLEMENT nssSMIMEProfile * +nssSMIMEProfile_AddRef +( + nssSMIMEProfile *profile +) +{ + if (profile) { + nssPKIObject_AddRef(&profile->object); + } + return profile; +} + +NSS_IMPLEMENT PRStatus +nssSMIMEProfile_Destroy +( + nssSMIMEProfile *profile +) +{ + if (profile) { + (void)nssPKIObject_Destroy(&profile->object); + } + return PR_SUCCESS; +} + diff --git a/security/nss/lib/pki/pki.h b/security/nss/lib/pki/pki.h index a232498f7..4460b52be 100644 --- a/security/nss/lib/pki/pki.h +++ b/security/nss/lib/pki/pki.h @@ -54,6 +54,13 @@ nssCertificate_AddRef NSSCertificate *c ); +NSS_EXTERN NSSUTF8 * +NSSCertificate_GetNickname +( + NSSCertificate *c, + NSSToken *tokenOpt +); + /* putting here for now, needs more thought */ NSS_EXTERN PRStatus nssCryptoContext_ImportTrust @@ -83,6 +90,30 @@ nssCryptoContext_FindSMIMEProfileForCertificate NSSCertificate *cert ); +NSS_EXTERN NSSTrust * +nssTrust_AddRef +( + NSSTrust *trust +); + +NSS_EXTERN PRStatus +nssTrust_Destroy +( + NSSTrust *trust +); + +NSS_EXTERN nssSMIMEProfile * +nssSMIMEProfile_AddRef +( + nssSMIMEProfile *profile +); + +NSS_EXTERN PRStatus +nssSMIMEProfile_Destroy +( + nssSMIMEProfile *profile +); + NSS_EXTERN nssSMIMEProfile * nssSMIMEProfile_Create ( diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index af07779f0..d26a68d2c 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -100,6 +100,9 @@ STAN_GetDefaultCryptoToken return PK11Slot_GetNSSToken(pk11slot); } +static CERTCertificate * +stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate); + /* stuff the cert in the global trust domain cache, and then add a reference * to remain with the token in a list. */ @@ -108,38 +111,131 @@ cache_token_cert(NSSCertificate *c, void *arg) { NSSToken *token = (NSSToken *)arg; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); + NSSCertificate *cp = nssCertificate_AddRef(c); if (nssList_Count(token->certList) > NSSTOKEN_MAX_LOCAL_CERTS) { - nssToken_DestroyCertList(token); + nssToken_DestroyCertList(token, PR_TRUE); /* terminate the traversal */ return PR_FAILURE; } nssTrustDomain_AddCertsToCache(td, &c, 1); + if (cp == c) { + NSSCertificate_Destroy(cp); + } else { + /* The cert was already in the cache, from another token. Add this + * token's instance to the cert. + */ + nssCryptokiInstance *tokenInstance, *instance; + nssList_GetArray(cp->object.instanceList, (void **)&tokenInstance, 1); + instance = nssCryptokiInstance_Create(c->object.arena, token, + tokenInstance->handle, PR_TRUE); + nssList_Add(c->object.instanceList, instance); + nssListIterator_Destroy(c->object.instances); + c->object.instances = nssList_CreateIterator(c->object.instanceList); + } /* This list reference persists with the token */ nssList_Add(token->certList, nssCertificate_AddRef(c)); /* The cert needs to become external (made into a CERTCertificate) * in order for it to be properly released. + * Force an update of the nickname and slot fields. */ - (void)STAN_GetCERTCertificate(c); + (void)stan_GetCERTCertificate(c, PR_TRUE); return PR_SUCCESS; } -static void cert_destructor(void *el) +static void remove_token_instance(NSSCertificate *c, NSSToken *token) { - NSSCertificate *c = (NSSCertificate *)el; - CERTCertificate *cert = STAN_GetCERTCertificate(c); - CERT_DestroyCertificate(cert); + nssListIterator *instances; + nssCryptokiInstance *instance, *rmInstance = NULL; + instances = c->object.instances; + for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); + instance != (nssCryptokiInstance *)NULL; + instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) + { + if (instance->token == token) { + rmInstance = instance; + break; + } + } + nssListIterator_Finish(instances); + if (rmInstance) { + nssList_Remove(c->object.instanceList, rmInstance); + nssListIterator_Destroy(instances); + c->object.instances = nssList_CreateIterator(c->object.instanceList); + } +} + +static PRBool instance_destructor(NSSCertificate *c, NSSToken *token) +{ + remove_token_instance(c, token); + if (nssList_Count(c->object.instanceList) == 0) { + return PR_TRUE; + } + return PR_FALSE; +} + +NSS_IMPLEMENT void +destroy_token_certs(nssList *certList, NSSToken *token, PRBool renewInstances) +{ + nssListIterator *certs; + NSSCertificate *cert; + PRBool removeIt; + certs = nssList_CreateIterator(certList); + for (cert = (NSSCertificate *)nssListIterator_Start(certs); + cert != (NSSCertificate *)NULL; + cert = (NSSCertificate *)nssListIterator_Next(certs)) + { + removeIt = instance_destructor(cert, token); + if (removeIt) { + nssList_Remove(certList, cert); + CERT_DestroyCertificate(STAN_GetCERTCertificate(cert)); + } else if (renewInstances) { + /* force an update of the nickname and slot fields of the cert */ + (void)stan_GetCERTCertificate(cert, PR_TRUE); + } + } + nssListIterator_Finish(certs); + nssListIterator_Destroy(certs); +} + +NSS_IMPLEMENT void +nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token) +{ + destroy_token_certs(certList, token, PR_TRUE); +} + +NSS_IMPLEMENT void +nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token) +{ + nssListIterator *certs; + NSSCertificate *cert; + PRBool removeIt; + certs = nssList_CreateIterator(certList); + for (cert = (NSSCertificate *)nssListIterator_Start(certs); + cert != (NSSCertificate *)NULL; + cert = (NSSCertificate *)nssListIterator_Next(certs)) + { + removeIt = instance_destructor(cert, token); + if (removeIt) { + nssList_Remove(certList, cert); + } else { + /* force an update of the nickname and slot fields of the cert */ + (void)stan_GetCERTCertificate(cert, PR_TRUE); + } + } + nssListIterator_Finish(certs); + nssListIterator_Destroy(certs); } /* destroy the list of certs on a token */ NSS_IMPLEMENT void -nssToken_DestroyCertList(NSSToken *token) +nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances) { if (!token->certList) { return; } - nssList_Clear(token->certList, cert_destructor); - nssList_Destroy(token->certList); - token->certList = NULL; + destroy_token_certs(token->certList, token, renewInstances); + nssList_Clear(token->certList, NULL); + /* leave the list non-null to prevent it from being searched */ } /* create a list of local cert references for certain tokens */ @@ -157,16 +253,31 @@ nssToken_LoadCerts(NSSToken *token) search.cbarg = token; search.cached = NULL; search.searchType = nssTokenSearchType_TokenOnly; - token->certList = nssList_Create(token->arena, PR_FALSE); if (!token->certList) { - return PR_FAILURE; + token->certList = nssList_Create(token->arena, PR_FALSE); + if (!token->certList) { + return PR_FAILURE; + } + } else if (nssList_Count(token->certList) > 0) { + /* already been done */ + return PR_SUCCESS; } /* ignore the rv, just work without the list */ (void)nssToken_TraverseCertificates(token, NULL, &search); + (void)nssToken_SetTrustCache(token); + (void)nssToken_SetCrlCache(token); + /* even if there are no certs, leave a valid list pointer should * any be imported. Having the pointer will also prevent searches, * see below. */ + if (nssList_Count(token->certList) == 0 && + !PK11_IsLoggedIn(token->pk11slot, NULL)) { + /* If the token is not logged in, that may be the reason no + * certs were found. + */ + token->loggedIn = PR_FALSE; + } } return nssrv; } @@ -174,12 +285,29 @@ nssToken_LoadCerts(NSSToken *token) NSS_IMPLEMENT PRBool nssToken_SearchCerts ( - NSSToken *token + NSSToken *token, + PRBool *notPresentOpt ) { + if (notPresentOpt) { + *notPresentOpt = PR_FALSE; + } if (!nssToken_IsPresent(token)) { - nssToken_DestroyCertList(token); /* will free cached certs */ - } + nssToken_DestroyCertList(token, PR_TRUE); /* will free cached certs */ + if (notPresentOpt) { + *notPresentOpt = PR_TRUE; + } + } else if (token->certList && + nssList_Count(token->certList) == 0 && + !token->loggedIn) { + /* If the token has no cached certs, but wasn't logged in, check + * to see if it is logged in now and retry + */ + if (PK11_IsLoggedIn(token->pk11slot, NULL)) { + token->loggedIn = PR_TRUE; + nssToken_LoadCerts(token); + } + } return (PRBool) (token->certList == NULL); } @@ -250,7 +378,7 @@ NSS_IMPLEMENT void STAN_DestroyNSSToken(NSSToken *token) { if (token->certList) { - nssToken_DestroyCertList(token); + nssToken_DestroyCertList(token, PR_FALSE); } nssToken_Destroy(token); } @@ -593,6 +721,24 @@ static int nsstoken_get_trust_order(NSSToken *token) return module->trustOrder; } +/* check all cert instances for private key */ +static PRBool is_user_cert(NSSCertificate *c, CERTCertificate *cc) +{ + PRBool isUser = PR_FALSE; + nssCryptokiInstance *instance; + nssListIterator *instances = c->object.instances; + for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); + instance != (nssCryptokiInstance *)NULL; + instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) + { + if (PK11_IsUserCert(instance->token->pk11slot, cc, instance->handle)) { + isUser = PR_TRUE; + } + } + nssListIterator_Finish(instances); + return isUser; +} + CERTCertTrust * nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) { @@ -634,7 +780,7 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) myTrustOrder < lastTrustOrder) { t.codeSigning = tokenTrust->codeSigning; } - (void)nssPKIObject_Destroy(&tokenTrust->object); + (void)nssTrust_Destroy(tokenTrust); lastTrustOrder = myTrustOrder; } } @@ -642,7 +788,7 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) nssListIterator_Destroy(tokens); rvTrust = cert_trust_from_stan_trust(&t, cc->arena); if (!rvTrust) return NULL; - if (cc->slot && PK11_IsUserCert(cc->slot, cc, cc->pkcs11ID)) { + if (is_user_cert(c, cc)) { rvTrust->sslFlags |= CERTDB_USER; rvTrust->emailFlags |= CERTDB_USER; rvTrust->objectSigningFlags |= CERTDB_USER; @@ -653,25 +799,49 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) static nssCryptokiInstance * get_cert_instance(NSSCertificate *c) { - nssCryptokiInstance *instance; + nssCryptokiInstance *instance, *ci; + nssListIterator *instances = c->object.instances; instance = NULL; - nssList_GetArray(c->object.instanceList, (void **)&instance, 1); + for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances); + ci != (nssCryptokiInstance *)NULL; + ci = (nssCryptokiInstance *)nssListIterator_Next(instances)) + { + if (!instance) { + instance = ci; + } else { + /* This only really works for two instances... But 3.4 can't + * handle more anyway. The logic is, if there are multiple + * instances, prefer the one that is not internal (e.g., on + * a hardware device. + */ + if (PK11_IsInternal(instance->token->pk11slot)) { + instance = ci; + } + } + } + nssListIterator_Finish(instances); return instance; } static void -fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc) +fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced) { NSSTrust *nssTrust; NSSCryptoContext *context = c->object.cryptoContext; nssCryptokiInstance *instance = get_cert_instance(c); + NSSUTF8 *stanNick = NULL; + if (instance) { + stanNick = instance->label; + } else if (context) { + stanNick = c->object.tempName; + } /* fill other fields needed by NSS3 functions using CERTCertificate */ - if (!cc->nickname && c->nickname) { + if ((!cc->nickname && stanNick) || forced) { PRStatus nssrv; int nicklen, tokenlen, len; NSSUTF8 *tokenName = NULL; char *nick; - nicklen = nssUTF8_Size(c->nickname, &nssrv); + nicklen = nssUTF8_Size(stanNick, &nssrv); if (instance && !PK11_IsInternal(instance->token->pk11slot)) { tokenName = nssToken_GetName(instance->token); tokenlen = nssUTF8_Size(tokenName, &nssrv); @@ -687,7 +857,7 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc) nick += tokenlen-1; *nick++ = ':'; } - memcpy(nick, c->nickname, nicklen-1); + memcpy(nick, stanNick, nicklen-1); cc->nickname[len-1] = '\0'; } if (context) { @@ -695,7 +865,7 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc) nssTrust = nssCryptoContext_FindTrustForCertificate(context, c); if (nssTrust) { cc->trust = cert_trust_from_stan_trust(nssTrust, cc->arena); - nssPKIObject_Destroy(&nssTrust->object); + nssTrust_Destroy(nssTrust); } } else if (instance) { /* slot */ @@ -716,8 +886,8 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc) cc->nssCertificate = c; } -NSS_EXTERN CERTCertificate * -STAN_GetCERTCertificate(NSSCertificate *c) +static CERTCertificate * +stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) { nssDecodedCert *dc; CERTCertificate *cc; @@ -730,8 +900,8 @@ STAN_GetCERTCertificate(NSSCertificate *c) } cc = (CERTCertificate *)dc->data; if (cc) { - if (!cc->nssCertificate) { - fill_CERTCertificateFields(c, cc); + if (!cc->nssCertificate || forceUpdate) { + fill_CERTCertificateFields(c, cc, forceUpdate); } else if (!cc->trust && !c->object.cryptoContext) { /* if it's a perm cert, it might have been stored before the * trust, so look for the trust again. But a temp cert can be @@ -743,6 +913,12 @@ STAN_GetCERTCertificate(NSSCertificate *c) return cc; } +NSS_IMPLEMENT CERTCertificate * +STAN_GetCERTCertificate(NSSCertificate *c) +{ + return stan_GetCERTCertificate(c, PR_FALSE); +} + static CK_TRUST get_stan_trust(unsigned int t, PRBool isClientAuth) { @@ -809,12 +985,6 @@ STAN_GetNSSCertificate(CERTCertificate *cc) nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data); PORT_Free(derSerial.data); } - if (cc->nickname) { - c->nickname = nssUTF8_Create(arena, - nssStringType_UTF8String, - (NSSUTF8 *)cc->nickname, - PORT_Strlen(cc->nickname)); - } if (cc->emailAddr) { c->email = nssUTF8_Create(arena, nssStringType_PrintableString, @@ -826,6 +996,12 @@ STAN_GetNSSCertificate(CERTCertificate *cc) instance->token = PK11Slot_GetNSSToken(cc->slot); instance->handle = cc->pkcs11ID; instance->isTokenObject = PR_TRUE; + if (cc->nickname) { + instance->label = nssUTF8_Create(arena, + nssStringType_UTF8String, + (NSSUTF8 *)cc->nickname, + PORT_Strlen(cc->nickname)); + } nssList_Add(c->object.instanceList, instance); /* XXX Fix this! */ nssListIterator_Destroy(c->object.instances); @@ -880,15 +1056,13 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) NSSCryptoContext *cc = c->object.cryptoContext; nssrv = nssCryptoContext_ImportTrust(cc, nssTrust); if (nssrv != PR_SUCCESS) { - nssPKIObject_Destroy(&nssTrust->object); + nssTrust_Destroy(nssTrust); return nssrv; } if (nssList_Count(c->object.instanceList) == 0) { /* The context is the only instance, finished */ return nssrv; } - /* prevent it from being destroyed */ - nssPKIObject_AddRef(&nssTrust->object); } td = STAN_GetDefaultTrustDomain(); if (PK11_IsReadOnly(cc->slot)) { @@ -913,14 +1087,15 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) /* this is kind of hacky. the softoken needs the cert * object in order to store trust. forcing it to be perm */ - nssrv = nssToken_ImportCertificate(tok, NULL, c, PR_TRUE); + NSSUTF8 *nickname = NSSCertificate_GetNickname(c, NULL); + nssrv = nssToken_ImportCertificate(tok, NULL, c, nickname, PR_TRUE); if (nssrv != PR_SUCCESS) return nssrv; } nssrv = nssToken_ImportTrust(tok, NULL, nssTrust, PR_TRUE); } else { nssrv = PR_FAILURE; } - (void)nssPKIObject_Destroy(&nssTrust->object); + (void)nssTrust_Destroy(nssTrust); return nssrv; } diff --git a/security/nss/lib/pki/pki3hack.h b/security/nss/lib/pki/pki3hack.h index df4010285..b2d908b6f 100644 --- a/security/nss/lib/pki/pki3hack.h +++ b/security/nss/lib/pki/pki3hack.h @@ -42,6 +42,8 @@ static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name #include "nsspkit.h" #endif /* NSSPKIT_H */ +#include "base.h" + #include "cert.h" PR_BEGIN_EXTERN_C @@ -75,9 +77,23 @@ STAN_DestroyNSSToken(NSSToken *token); NSS_EXTERN PRBool nssToken_SearchCerts ( - NSSToken *token + NSSToken *token, + PRBool *notPresentOpt ); +/* renewInstances -- if the cached token certs have multiple instances, + * don't destroy them. If this parameter is false, they will be destroyed + * anyway (used for clean shutdown). + */ +NSS_EXTERN void +nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances); + +NSS_EXTERN void +nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token); + +NSS_EXTERN void +nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token); + NSS_EXTERN SECStatus STAN_AddModuleToDefaultTrustDomain ( diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c index d2568a875..0b1463fcb 100644 --- a/security/nss/lib/pki/pkistore.c +++ b/security/nss/lib/pki/pkistore.c @@ -276,10 +276,10 @@ remove_certificate_entry if (entry) { nssHash_Remove(store->issuer_and_serial, cert); if (entry->trust) { - nssPKIObject_Destroy(&entry->trust->object); + nssTrust_Destroy(entry->trust); } if (entry->profile) { - nssPKIObject_Destroy(&entry->profile->object); + nssSMIMEProfile_Destroy(entry->profile); } nss_ZFreeIf(entry); } @@ -358,6 +358,35 @@ nssCertificateStore_Remove PZ_Unlock(store->lock); } +static NSSCertificate ** +get_array_from_list +( + nssList *certList, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + PRUint32 count; + NSSCertificate **rvArray = NULL; + count = nssList_Count(certList); + if (count == 0) { + return NULL; + } + if (maximumOpt > 0) { + count = PR_MIN(maximumOpt, count); + } + if (rvOpt) { + nssList_GetArray(certList, (void **)rvOpt, count); + } else { + rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1); + if (rvArray) { + nssList_GetArray(certList, (void **)rvArray, count); + } + } + return rvArray; +} + NSS_IMPLEMENT NSSCertificate ** nssCertificateStore_FindCertificatesBySubject ( @@ -368,25 +397,14 @@ nssCertificateStore_FindCertificatesBySubject NSSArena *arenaOpt ) { - PRUint32 count; NSSCertificate **rvArray = NULL; nssList *subjectList; PZ_Lock(store->lock); subjectList = (nssList *)nssHash_Lookup(store->subject, subject); if (subjectList) { nssCertificateList_AddReferences(subjectList); - count = nssList_Count(subjectList); - if (maximumOpt > 0) { - count = PR_MIN(maximumOpt, count); - } - if (rvOpt) { - nssList_GetArray(subjectList, (void **)rvOpt, count); - } else { - rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1); - if (rvArray) { - nssList_GetArray(subjectList, (void **)rvArray, count); - } - } + rvArray = get_array_from_list(subjectList, + rvOpt, maximumOpt, arenaOpt); } PZ_Unlock(store->lock); return rvArray; @@ -413,11 +431,13 @@ static void match_nickname(const void *k, void *v, void *a) { PRStatus nssrv; NSSCertificate *c; + NSSUTF8 *nickname; nssList *subjectList = (nssList *)v; struct nickname_template_str *nt = (struct nickname_template_str *)a; nssrv = nssList_GetArray(subjectList, (void **)&c, 1); + nickname = NSSCertificate_GetNickname(c, NULL); if (nssrv == PR_SUCCESS && - nssUTF8_Equal(c->nickname, nt->nickname, &nssrv)) + nssUTF8_Equal(nickname, nt->nickname, &nssrv)) { nt->subjectList = subjectList; } @@ -436,7 +456,6 @@ nssCertificateStore_FindCertificatesByNickname NSSArena *arenaOpt ) { - PRUint32 count; NSSCertificate **rvArray = NULL; struct nickname_template_str nt; nt.nickname = nickname; @@ -445,18 +464,8 @@ nssCertificateStore_FindCertificatesByNickname nssHash_Iterate(store->subject, match_nickname, &nt); if (nt.subjectList) { nssCertificateList_AddReferences(nt.subjectList); - count = nssList_Count(nt.subjectList); - if (maximumOpt > 0) { - count = PR_MIN(maximumOpt, count); - } - if (rvOpt) { - nssList_GetArray(nt.subjectList, (void **)rvOpt, count); - } else { - rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1); - if (rvArray) { - nssList_GetArray(nt.subjectList, (void **)rvArray, count); - } - } + rvArray = get_array_from_list(nt.subjectList, + rvOpt, maximumOpt, arenaOpt); } PZ_Unlock(store->lock); return rvArray; @@ -505,7 +514,6 @@ nssCertificateStore_FindCertificatesByEmail NSSArena *arenaOpt ) { - PRUint32 count; NSSCertificate **rvArray = NULL; struct email_template_str et; et.email = email; @@ -521,18 +529,8 @@ nssCertificateStore_FindCertificatesByEmail } PZ_Unlock(store->lock); if (et.emailList) { - count = nssList_Count(et.emailList); - if (maximumOpt > 0) { - count = PR_MIN(maximumOpt, count); - } - if (rvOpt) { - nssList_GetArray(et.emailList, (void **)rvOpt, count); - } else { - rvArray = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1); - if (rvArray) { - nssList_GetArray(et.emailList, (void **)rvArray, count); - } - } + rvArray = get_array_from_list(et.emailList, + rvOpt, maximumOpt, arenaOpt); nssList_Destroy(et.emailList); } return rvArray; @@ -631,7 +629,7 @@ nssCertificateStore_AddTrust entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); if (entry) { - entry->trust = trust; + entry->trust = nssTrust_AddRef(trust); } PZ_Unlock(store->lock); return (entry) ? PR_SUCCESS : PR_FAILURE; @@ -645,14 +643,15 @@ nssCertificateStore_FindTrustForCertificate ) { certificate_hash_entry *entry; + NSSTrust *rvTrust = NULL; PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); - PZ_Unlock(store->lock); - if (entry) { - return entry->trust; + if (entry && entry->trust) { + rvTrust = nssTrust_AddRef(entry->trust); } - return NULL; + PZ_Unlock(store->lock); + return rvTrust; } NSS_EXTERN PRStatus @@ -669,7 +668,7 @@ nssCertificateStore_AddSMIMEProfile entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); if (entry) { - entry->profile = profile; + entry->profile = nssSMIMEProfile_AddRef(profile); } PZ_Unlock(store->lock); return (entry) ? PR_SUCCESS : PR_FAILURE; @@ -683,14 +682,15 @@ nssCertificateStore_FindSMIMEProfileForCertificate ) { certificate_hash_entry *entry; + nssSMIMEProfile *rvProfile = NULL; PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, cert); - PZ_Unlock(store->lock); - if (entry) { - return entry->profile; + if (entry && entry->profile) { + rvProfile = nssSMIMEProfile_AddRef(entry->profile); } - return NULL; + PZ_Unlock(store->lock); + return rvProfile; } /* XXX this is also used by cache and should be somewhere else */ diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h index 1806b5ef6..1e0f98a4f 100644 --- a/security/nss/lib/pki/pkit.h +++ b/security/nss/lib/pki/pkit.h @@ -108,6 +108,8 @@ struct nssPKIObjectBaseStr NSSTrustDomain *trustDomain; /* The object may live in a crypto context */ NSSCryptoContext *cryptoContext; + /* XXX added so temp certs can have nickname, think more ... */ + NSSUTF8 *tempName; }; struct NSSTrustStr @@ -139,7 +141,6 @@ struct NSSCertificateStr NSSDER issuer; NSSDER subject; NSSDER serial; - NSSUTF8 *nickname; NSSASCII7 *email; nssDecodedCert *decoding; }; diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index 4d80e8b76..e34c6403a 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -308,11 +308,12 @@ remove_nickname_entry ) { PRStatus nssrv; - if (cert->nickname) { - nssHash_Remove(cache->nickname, cert->nickname); + NSSUTF8 *nickname = NSSCertificate_GetNickname(cert, NULL); + if (nickname) { + nssHash_Remove(cache->nickname, nickname); nssrv = PR_SUCCESS; #ifdef DEBUG_CACHE - PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", cert->nickname)); + PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname)); #endif } else { nssrv = PR_FAILURE; @@ -561,8 +562,9 @@ add_nickname_entry ) { PRStatus nssrv = PR_SUCCESS; + NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); cache_entry *ce; - ce = (cache_entry *)nssHash_Lookup(cache->nickname, cert->nickname); + ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname); if (ce) { /* This is a collision. A nickname entry already exists for this * subject, but a subject entry didn't. This would imply there are @@ -575,7 +577,7 @@ add_nickname_entry if (!ce) { return PR_FAILURE; } - nickname = nssUTF8_Duplicate(cert->nickname, arena); + nickname = nssUTF8_Duplicate(certNickname, arena); if (!nickname) { return PR_FAILURE; } @@ -696,7 +698,8 @@ add_cert_to_cache /* If a new subject entry was created, also need nickname and/or email */ if (subjectList != NULL) { PRBool handle = PR_FALSE; - if (cert->nickname) { + NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); + if (certNickname) { nssrv = add_nickname_entry(arena, td->cache, cert, subjectList); if (nssrv != PR_SUCCESS) { goto loser; @@ -729,6 +732,7 @@ add_cert_to_cache return nssrv; loser: /* Remove any handles that have been created */ + subjectList = NULL; if (added >= 1) { (void)remove_issuer_and_serial_entry(td->cache, cert); } @@ -741,6 +745,10 @@ loser: if (added >= 4) { (void)remove_email_entry(td->cache, cert, subjectList); } + if (subjectList) { + nssHash_Remove(td->cache->subject, &cert->subject); + nssList_Destroy(subjectList); + } if (arena) { nssArena_Destroy(arena); } diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c index a84e8c4f4..1e3ca163a 100644 --- a/security/nss/lib/pki/trustdomain.c +++ b/security/nss/lib/pki/trustdomain.c @@ -411,6 +411,7 @@ NSSTrustDomain_FindBestCertificateByNickname nssTokenCertSearch search; nssBestCertificateCB best; nssList *nameList; + PRBool notPresent; /* set the criteria for determining the best cert */ nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); /* find all matching certs in the cache */ @@ -421,19 +422,21 @@ NSSTrustDomain_FindBestCertificateByNickname search.cbarg = &best; search.cached = nameList; search.searchType = nssTokenSearchType_TokenOnly; - nssCertificateList_DoCallback(nameList, - nssBestCertificate_Callback, &best); /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; token = (NSSToken *)nssListIterator_Next(td->tokens)) { - if (nssToken_SearchCerts(token)) { + if (nssToken_SearchCerts(token, ¬Present)) { nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, name, &search); } + if (notPresent) { + nssCertificateList_DestroyTokenCerts(nameList, token); + } } nssListIterator_Finish(td->tokens); + nssCertificateList_DoCallback(nameList, nssBestCertificate_Callback, &best); nssList_Clear(nameList, cert_destructor); nssList_Destroy(nameList); if (best.cert) { @@ -457,8 +460,9 @@ NSSTrustDomain_FindCertificatesByNickname PRUint32 count; PRStatus nssrv; nssList *nameList; - struct collect_arg_str ca; nssTokenCertSearch search; + struct collect_arg_str ca; + PRBool notPresent; /* set up the collection */ nameList = nssList_Create(NULL, PR_FALSE); (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList); @@ -474,10 +478,13 @@ NSSTrustDomain_FindCertificatesByNickname token != (NSSToken *)NULL; token = (NSSToken *)nssListIterator_Next(td->tokens)) { - if (nssToken_SearchCerts(token)) { + if (nssToken_SearchCerts(token, ¬Present)) { nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, name, &search); } + if (notPresent) { + nssCertificateList_DestroyTokenCerts(nameList, token); + } } nssListIterator_Finish(td->tokens); count = nssList_Count(nameList); @@ -497,6 +504,32 @@ NSSTrustDomain_FindCertificatesByNickname return rvCerts; } +static PRBool cert_token_not_present(NSSCertificate *c) +{ + nssListIterator *instances; + nssCryptokiInstance *instance; + PRBool freeIt = PR_TRUE; + instances = nssList_CreateIterator(c->object.instanceList); + for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); + instance != (nssCryptokiInstance *)NULL; + instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) + { + if (!nssToken_IsPresent(instance->token)) { + nssToken_DestroyCertList(instance->token, PR_TRUE); + nssList_Remove(c->object.instanceList, instance); + } else { + freeIt = PR_FALSE; + } + } + nssListIterator_Finish(instances); + nssListIterator_Destroy(instances); + if (!freeIt) { + nssListIterator_Destroy(c->object.instances); + c->object.instances = nssList_CreateIterator(c->object.instanceList); + } + return freeIt; +} + NSS_IMPLEMENT NSSCertificate * NSSTrustDomain_FindCertificateByIssuerAndSerialNumber ( @@ -512,6 +545,10 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber issuer, serialNumber); if (rvCert) { + if (cert_token_not_present(rvCert)) { + CERT_DestroyCertificate(STAN_GetCERTCertificate(rvCert)); + rvCert = NULL; + } return rvCert; } /* Not cached, look for it on tokens */ @@ -519,7 +556,7 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber tok != (NSSToken *)NULL; tok = (NSSToken *)nssListIterator_Next(td->tokens)) { - if (nssToken_SearchCerts(tok)) { + if (nssToken_SearchCerts(tok, NULL)) { rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok, NULL, issuer, @@ -541,7 +578,7 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber if (secrv == SECSuccess) { decodedSerial.data = ds.data; decodedSerial.size = ds.len; - if (nssToken_SearchCerts(tok)) { + if (nssToken_SearchCerts(tok, NULL)) { rvCert = nssToken_FindCertificateByIssuerAndSerialNumber( tok, NULL, @@ -578,6 +615,7 @@ NSSTrustDomain_FindBestCertificateBySubject nssList *subjectList; nssBestCertificateCB best; nssTokenCertSearch search; + PRBool notPresent; /* set the criteria for determining the best cert */ nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); /* find all matching certs in the cache */ @@ -588,19 +626,22 @@ NSSTrustDomain_FindBestCertificateBySubject search.cbarg = &best; search.cached = subjectList; search.searchType = nssTokenSearchType_TokenOnly; - nssCertificateList_DoCallback(subjectList, - nssBestCertificate_Callback, &best); /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; token = (NSSToken *)nssListIterator_Next(td->tokens)) { - if (nssToken_SearchCerts(token)) { + if (nssToken_SearchCerts(token, ¬Present)) { nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, subject, &search); } + if (notPresent) { + nssCertificateList_DestroyTokenCerts(subjectList, token); + } } nssListIterator_Finish(td->tokens); + nssCertificateList_DoCallback(subjectList, + nssBestCertificate_Callback, &best); nssList_Clear(subjectList, cert_destructor); nssList_Destroy(subjectList); if (best.cert) { @@ -626,6 +667,7 @@ NSSTrustDomain_FindCertificatesBySubject nssList *subjectList; struct collect_arg_str ca; nssTokenCertSearch search; + PRBool notPresent; /* set up the collection */ subjectList = nssList_Create(NULL, PR_FALSE); (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList); @@ -641,10 +683,13 @@ NSSTrustDomain_FindCertificatesBySubject token != (NSSToken *)NULL; token = (NSSToken *)nssListIterator_Next(td->tokens)) { - if (nssToken_SearchCerts(token)) { + if (nssToken_SearchCerts(token, ¬Present)) { nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, subject, &search); } + if (notPresent) { + nssCertificateList_DestroyTokenCerts(subjectList, token); + } } nssListIterator_Finish(td->tokens); count = nssList_Count(subjectList); @@ -704,6 +749,10 @@ NSSTrustDomain_FindCertificateByEncodedCertificate /* Try the cache */ rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate); if (rvCert) { + if (cert_token_not_present(rvCert)) { + CERT_DestroyCertificate(STAN_GetCERTCertificate(rvCert)); + rvCert = NULL; + } return rvCert; } /* Not cached, look for it on tokens */ @@ -711,7 +760,7 @@ NSSTrustDomain_FindCertificateByEncodedCertificate tok != (NSSToken *)NULL; tok = (NSSToken *)nssListIterator_Next(td->tokens)) { - if (nssToken_SearchCerts(tok)) { + if (nssToken_SearchCerts(tok, NULL)) { rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL, encodedCertificate, nssTokenSearchType_TokenOnly); @@ -741,6 +790,7 @@ NSSTrustDomain_FindCertificateByEmail nssBestCertificateCB best; nssTokenCertSearch search; nssList *emailList; + PRBool notPresent; /* set the criteria for determining the best cert */ nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); /* find all matching certs in the cache */ @@ -751,19 +801,22 @@ NSSTrustDomain_FindCertificateByEmail search.cbarg = &best; search.cached = emailList; search.searchType = nssTokenSearchType_TokenOnly; - nssCertificateList_DoCallback(emailList, - nssBestCertificate_Callback, &best); /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; token = (NSSToken *)nssListIterator_Next(td->tokens)) { - if (nssToken_SearchCerts(token)) { + if (nssToken_SearchCerts(token, ¬Present)) { nssrv = nssToken_TraverseCertificatesByEmail(token, NULL, email, &search); } + if (notPresent) { + nssCertificateList_DestroyTokenCerts(emailList, token); + } } nssListIterator_Finish(td->tokens); + nssCertificateList_DoCallback(emailList, + nssBestCertificate_Callback, &best); nssList_Clear(emailList, cert_destructor); nssList_Destroy(emailList); if (best.cert) { @@ -927,13 +980,11 @@ static PRStatus traverse_callback(NSSCertificate *c, void *arg) * destroy the reference to the copy, the callback will use the reference * to the cached entry, and everyone should be happy. */ - if (cp == c) { - /* However, if the call to add c to the cache was successful, cp is - * now an extra copy within this function and needs to be destroyed. - */ - NSSCertificate_Destroy(cp); - } nssrv = (*ta->callback)(c, ta->arg); + /* This function owns a reference to the cert, either from the AddRef + * or by getting it from the cache. + */ + CERT_DestroyCertificate(STAN_GetCERTCertificate(c)); return nssrv; } @@ -948,7 +999,7 @@ static void cert_destructor_with_cache(void *el) CERT_DestroyCertificate(cert); } #endif - + NSS_IMPLEMENT PRStatus * NSSTrustDomain_TraverseCertificates ( @@ -959,13 +1010,18 @@ NSSTrustDomain_TraverseCertificates { PRStatus nssrv; NSSToken *token; - nssList *certList; + nssList *certList, *cacheList; nssTokenCertSearch search; struct traverse_arg ta; nssListIterator *tokens; + PRBool notPresent; certList = nssList_Create(NULL, PR_FALSE); if (!certList) return NULL; (void *)nssTrustDomain_GetCertsFromCache(td, certList); + cacheList = nssList_Clone(certList); + if (!cacheList) { + goto cleanup; + } /* set traverse args */ ta.callback = callback; ta.cached = certList; @@ -975,8 +1031,6 @@ NSSTrustDomain_TraverseCertificates search.cbarg = &ta; search.cached = certList; search.searchType = nssTokenSearchType_TokenOnly; - nssCertificateList_DoCallback(certList, - traverse_callback, &ta); /* Must create a local copy of the token list, because the callback * above may want to traverse the tokens as well. */ @@ -989,12 +1043,20 @@ NSSTrustDomain_TraverseCertificates token != (NSSToken *)NULL; token = (NSSToken *)nssListIterator_Next(tokens)) { - if (nssToken_SearchCerts(token)) { + if (nssToken_SearchCerts(token, ¬Present)) { nssrv = nssToken_TraverseCertificates(token, NULL, &search); } + if (notPresent) { + nssCertificateList_RemoveTokenCerts(cacheList, token); + } } nssListIterator_Finish(tokens); nssListIterator_Destroy(tokens); + /* now do the callback on the cached certs, + * sans certs from removed tokens + */ + nssCertificateList_DoCallback(cacheList, callback, arg); + nssList_Destroy(cacheList); cleanup: #ifdef NSS_3_4_CODE nssList_Clear(certList, cert_destructor_with_cache); diff --git a/security/nss/lib/smime/smime.def b/security/nss/lib/smime/smime.def index 1657a3061..62473e810 100644 --- a/security/nss/lib/smime/smime.def +++ b/security/nss/lib/smime/smime.def @@ -175,7 +175,7 @@ NSSSMIME_VersionCheck; ;+ local: ;+ *; ;+}; -;+NSS_3.3 { # NSS 3.3. release +;+NSS_3.3 { # NSS 3.3 release ;+ global: SEC_PKCS7AddCertificate; SEC_PKCS7CreateCertsOnly; @@ -183,14 +183,20 @@ SEC_PKCS7Encode; ;+ local: ;+ *; ;+}; -;+NSS_3.4 { # NSS 3.4. release +;+NSS_3.4 { # NSS 3.4 release ;+ global: -;+# FOR PSM CERT_DecodeCertFromPackage; -NSS_CMSSignedData_SetDigestValue; NSS_CMSMessage_IsSigned; +NSS_CMSSignedData_SetDigestValue; NSS_SMIMESignerInfo_SaveSMIMEProfile; +SEC_PKCS7ContainsCertsOrCrls; +SEC_PKCS7ContentIsEncrypted; +SEC_PKCS7ContentIsSigned; SEC_PKCS7CopyContentInfo; +SEC_PKCS7GetSignerCommonName; +SEC_PKCS7GetSignerEmailAddress; +SEC_PKCS7GetSigningTime; +SEC_PKCS7SetContent; SEC_PKCS7VerifyDetachedSignature; SECMIME_DecryptionAllowed; ;+ local: diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk index f280dec2d..b59f0cf32 100644 --- a/security/nss/lib/softoken/config.mk +++ b/security/nss/lib/softoken/config.mk @@ -89,7 +89,7 @@ endif ifeq ($(OS_TARGET),SunOS) ifndef USE_64 ifeq ($(CPU_ARCH),sparc) -# The -R '$ORIGIN' linker option instructs libnss3.so to search for its +# The -R '$ORIGIN' linker option instructs libsoftokn3.so to search for its # dependencies (libfreebl_*.so) in the same directory where it resides. MKSHLIB += -R '$$ORIGIN' endif diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c index a44c0f94d..fcc906d06 100644 --- a/security/nss/lib/softoken/pk11db.c +++ b/security/nss/lib/softoken/pk11db.c @@ -72,9 +72,9 @@ secmod_parseTokenParameters(char *param, pk11_token_parameters *parsed) index = pk11_argStrip(param); while (*index) { - PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configdir=",;) - PK11_HANDLE_STRING_ARG(index,parsed->certPrefix,"certprefix=",;) - PK11_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyprefix=",;) + PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;) + PK11_HANDLE_STRING_ARG(index,parsed->certPrefix,"certPrefix=",;) + PK11_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyPrefix=",;) PK11_HANDLE_STRING_ARG(index,parsed->tokdes,"tokenDescription=",;) PK11_HANDLE_STRING_ARG(index,parsed->slotdes,"slotDescription=",;) PK11_HANDLE_STRING_ARG(index,tmp,"minPWLen=", @@ -148,13 +148,13 @@ secmod_parseParameters(char *param, pk11_parameters *parsed, PRBool isFIPS) PORT_Memset(parsed, 0, sizeof(pk11_parameters)); while (*index) { - PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configdir=",;) + PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;) PK11_HANDLE_STRING_ARG(index,parsed->secmodName,"secmod=",;) - PK11_HANDLE_STRING_ARG(index,parsed->man,"manufactureID=",;) + PK11_HANDLE_STRING_ARG(index,parsed->man,"manufacturerID=",;) PK11_HANDLE_STRING_ARG(index,parsed->libdes,"libraryDescription=",;) /* constructed values, used so legacy interfaces still work */ - PK11_HANDLE_STRING_ARG(index,certPrefix,"certprefix=",;) - PK11_HANDLE_STRING_ARG(index,keyPrefix,"keyprefix=",;) + PK11_HANDLE_STRING_ARG(index,certPrefix,"certPrefix=",;) + PK11_HANDLE_STRING_ARG(index,keyPrefix,"keyPrefix=",;) PK11_HANDLE_STRING_ARG(index,tokdes,"cryptoTokenDescription=",;) PK11_HANDLE_STRING_ARG(index,ptokdes,"dbTokenDescription=",;) PK11_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;) @@ -187,6 +187,7 @@ secmod_parseParameters(char *param, pk11_parameters *parsed, PRBool isFIPS) 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; certPrefix = NULL; @@ -257,7 +258,7 @@ secmod_getSecmodName(char *param, PRBool *rw) while (*param) { - PK11_HANDLE_STRING_ARG(param,configdir,"configdir=",;) + PK11_HANDLE_STRING_ARG(param,configdir,"configDir=",;) PK11_HANDLE_STRING_ARG(param,secmodName,"secmod=",;) PK11_HANDLE_FINAL_ARG(param) } diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 899241eaa..d0bcac938 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -398,12 +398,49 @@ static const struct mechanismList mechanisms[] = { static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]); static char * -pk11_setStringName(const char *inString, char *buffer, int buffer_length) { +pk11_setStringName(const char *inString, char *buffer, int buffer_length) +{ int full_length, string_length; full_length = buffer_length -1; string_length = PORT_Strlen(inString); - if (string_length > full_length) string_length = full_length; + /* + * 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); buffer[full_length] = 0; PORT_Memcpy(buffer,inString,string_length); @@ -1368,6 +1405,108 @@ pk11_handleKeyObject(PK11Session *session, PK11Object *object) return CKR_ATTRIBUTE_VALUE_INVALID; } +/* + * check the consistancy and Verify a DSA Parameter Object + */ +static CK_RV +pk11_handleDSAParameterObject(PK11Session *session, PK11Object *object) +{ + PK11Attribute *primeAttr = NULL; + PK11Attribute *subPrimeAttr = NULL; + PK11Attribute *baseAttr = NULL; + PK11Attribute *seedAttr = NULL; + PK11Attribute *hAttr = NULL; + PK11Attribute *attribute; + CK_RV crv = CKR_TEMPLATE_INCOMPLETE; + PQGParams params; + PQGVerify vfy, *verify = NULL; + SECStatus result,rv; + + primeAttr = pk11_FindAttribute(object,CKA_PRIME); + if (primeAttr == NULL) goto loser; + params.prime.data = primeAttr->attrib.pValue; + params.prime.len = primeAttr->attrib.ulValueLen; + + subPrimeAttr = pk11_FindAttribute(object,CKA_SUBPRIME); + if (subPrimeAttr == NULL) goto loser; + params.subPrime.data = subPrimeAttr->attrib.pValue; + params.subPrime.len = subPrimeAttr->attrib.ulValueLen; + + baseAttr = pk11_FindAttribute(object,CKA_BASE); + if (baseAttr == NULL) goto loser; + params.base.data = baseAttr->attrib.pValue; + params.base.len = baseAttr->attrib.ulValueLen; + + attribute = pk11_FindAttribute(object, CKA_NETSCAPE_PQG_COUNTER); + if (attribute != NULL) { + vfy.counter = *(CK_ULONG *) attribute->attrib.pValue; + pk11_FreeAttribute(attribute); + + seedAttr = pk11_FindAttribute(object, CKA_NETSCAPE_PQG_SEED); + if (seedAttr == NULL) goto loser; + vfy.seed.data = seedAttr->attrib.pValue; + vfy.seed.len = seedAttr->attrib.ulValueLen; + + hAttr = pk11_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) pk11_FreeAttribute(hAttr); + if (seedAttr) pk11_FreeAttribute(seedAttr); + if (baseAttr) pk11_FreeAttribute(baseAttr); + if (subPrimeAttr) pk11_FreeAttribute(subPrimeAttr); + if (primeAttr) pk11_FreeAttribute(primeAttr); + + return crv; +} + +/* + * check the consistancy and initialize a Key Parameter Object + */ +static CK_RV +pk11_handleKeyParameterObject(PK11Session *session, PK11Object *object) +{ + PK11Attribute *attribute; + CK_KEY_TYPE key_type; + CK_BBOOL cktrue = CK_TRUE; + CK_BBOOL ckfalse = CK_FALSE; + CK_RV crv; + + /* verify the required fields */ + if ( !pk11_hasAttribute(object,CKA_KEY_TYPE) ) { + return CKR_TEMPLATE_INCOMPLETE; + } + + /* now verify the common fields */ + crv = pk11_defaultAttribute(object,CKA_LOCAL,&ckfalse,sizeof(CK_BBOOL)); + if (crv != CKR_OK) return crv; + + /* get the key type */ + attribute = pk11_FindAttribute(object,CKA_KEY_TYPE); + key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; + pk11_FreeAttribute(attribute); + + switch (key_type) { + case CKK_DSA: + return pk11_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 @@ -1443,6 +1582,9 @@ pk11_handleObject(PK11Object *object, PK11Session *session) case CKO_SECRET_KEY: crv = pk11_handleKeyObject(session,object); break; + case CKO_KG_PARAMETERS: + crv = pk11_handleKeyParameterObject(session,object); + break; default: crv = CKR_ATTRIBUTE_VALUE_INVALID; break; diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 91d776f14..d4dfc1b75 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -2562,6 +2562,76 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism, } return CKR_OK; } +static CK_RV +nsc_parameter_gen(CK_KEY_TYPE key_type, PK11Object *key) +{ + PK11Attribute *attribute; + CK_ULONG counter; + unsigned int seedBits = 0; + unsigned int primeBits; + CK_RV crv = CKR_OK; + PQGParams *params = NULL; + PQGVerify *vfy = NULL; + SECStatus rv; + + attribute = pk11_FindAttribute(key, CKA_PRIME_BITS); + if (attribute == NULL) { + return CKR_TEMPLATE_INCOMPLETE; + } + primeBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; + pk11_FreeAttribute(attribute); + + attribute = pk11_FindAttribute(key, CKA_NETSCAPE_PQG_SEED_BITS); + if (attribute != NULL) { + seedBits = (unsigned int) *(CK_ULONG *)attribute->attrib.pValue; + pk11_FreeAttribute(attribute); + } + + pk11_DeleteAttributeType(key,CKA_PRIME_BITS); + pk11_DeleteAttributeType(key,CKA_NETSCAPE_PQG_SEED_BITS); + + if (seedBits == 0) { + rv = PQG_ParamGen(primeBits, ¶ms, &vfy); + } else { + rv = PQG_ParamGenSeedLen(primeBits,seedBits/8, ¶ms, &vfy); + } + + if (rv != SECSuccess) { + return CKR_DEVICE_ERROR; + } + crv = pk11_AddAttributeType(key,CKA_PRIME, + params->prime.data, params->prime.len); + if (crv != CKR_OK) goto loser; + crv = pk11_AddAttributeType(key,CKA_SUBPRIME, + params->subPrime.data, params->subPrime.len); + if (crv != CKR_OK) goto loser; + crv = pk11_AddAttributeType(key,CKA_BASE, + params->base.data, params->base.len); + if (crv != CKR_OK) goto loser; + counter = vfy->counter; + crv = pk11_AddAttributeType(key,CKA_NETSCAPE_PQG_COUNTER, + &counter, sizeof(counter)); + crv = pk11_AddAttributeType(key,CKA_NETSCAPE_PQG_SEED, + vfy->seed.data, vfy->seed.len); + if (crv != CKR_OK) goto loser; + crv = pk11_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 @@ -2747,7 +2817,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession, int i; PK11Slot *slot = pk11_SlotFromSessionHandle(hSession); char buf[MAX_KEY_LEN]; - enum {nsc_pbe, nsc_ssl, nsc_bulk} key_gen_type; + enum {nsc_pbe, nsc_ssl, nsc_bulk, nsc_param} key_gen_type; NSSPKCS5PBEParameter *pbe_param; SSL3RSAPreMasterSecret *rsa_pms; CK_VERSION *version; @@ -2837,6 +2907,12 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession, key_gen_type = nsc_pbe; crv = nsc_SetupPBEKeyGen(pMechanism,&pbe_param, &key_type); 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; @@ -2879,6 +2955,11 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession, } while (crv == CKR_OK && checkWeak && pk11_IsWeakKey((unsigned char *)buf,key_type)); break; + case nsc_param: + /* generate parameters */ + *buf = 0; + crv = nsc_parameter_gen(key_type,key); + break; } if (crv != CKR_OK) { pk11_FreeObject(key); return crv; } @@ -2888,10 +2969,10 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession, if (crv != CKR_OK) { pk11_FreeObject(key); return crv; } crv = pk11_AddAttributeType(key,CKA_KEY_TYPE,&key_type,sizeof(CK_KEY_TYPE)); if (crv != CKR_OK) { pk11_FreeObject(key); return crv; } - crv = pk11_AddAttributeType(key,CKA_CLASS,&objclass,sizeof(CK_OBJECT_CLASS)); - if (crv != CKR_OK) { pk11_FreeObject(key); return crv; } - crv = pk11_AddAttributeType(key,CKA_VALUE,buf,key_length); - if (crv != CKR_OK) { pk11_FreeObject(key); return crv; } + if (key_length != 0) { + crv = pk11_AddAttributeType(key,CKA_VALUE,buf,key_length); + if (crv != CKR_OK) { pk11_FreeObject(key); return crv; } + } /* get the session */ session = pk11_SessionFromHandle(hSession); diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index a683426d0..391f2f152 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -423,7 +423,7 @@ struct PK11SSLMACInfoStr { #define PK11_TOKEN_TYPE_SMIME 0x60000000L #define PK11_TOKEN_TYPE_CERT 0x70000000L -#define PK11_TOKEN_KRL_HANDLE (PK11_TOKEN_MAGIC|PK11_TOKEN_TYPE_CRL|0) +#define PK11_TOKEN_KRL_HANDLE (PK11_TOKEN_MAGIC|PK11_TOKEN_TYPE_CRL|1) /* how big a password/pin we can deal with */ #define PK11_MAX_PIN 255 diff --git a/security/nss/lib/softoken/pkcs11n.h b/security/nss/lib/softoken/pkcs11n.h index 8ad69a3da..7ee4c6c34 100644 --- a/security/nss/lib/softoken/pkcs11n.h +++ b/security/nss/lib/softoken/pkcs11n.h @@ -97,7 +97,12 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; #define CKA_NETSCAPE_PKCS8_SALT (CKA_NETSCAPE + 5) #define CKA_NETSCAPE_PASSWORD_CHECK (CKA_NETSCAPE + 6) #define CKA_NETSCAPE_EXPIRES (CKA_NETSCAPE + 7) -#define CKA_NETSCAPE_KRL (CKA_NETSCAPE + 7) +#define CKA_NETSCAPE_KRL (CKA_NETSCAPE + 8) + +#define CKA_NETSCAPE_PQG_COUNTER (CKA_NETSCAPE + 20) +#define CKA_NETSCAPE_PQG_SEED (CKA_NETSCAPE + 21) +#define CKA_NETSCAPE_PQG_H (CKA_NETSCAPE + 22) +#define CKA_NETSCAPE_PQG_SEED_BITS (CKA_NETSCAPE + 23) /* * Trust attributes: diff --git a/security/nss/lib/softoken/pkcs11t.h b/security/nss/lib/softoken/pkcs11t.h index 124a1bb27..9ebed9e85 100644 --- a/security/nss/lib/softoken/pkcs11t.h +++ b/security/nss/lib/softoken/pkcs11t.h @@ -360,6 +360,7 @@ typedef CK_ULONG CK_OBJECT_CLASS; #define CKO_SECRET_KEY 0x00000004 #define CKO_HW_FEATURE 0x00000005 #define CKO_DOMAIN_PARAMETERS 0x00000006 +#define CKO_KG_PARAMETERS 0x00000006 #define CKO_VENDOR_DEFINED 0x80000000 typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index e7e15d0a5..2dd69ed39 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -1948,11 +1948,15 @@ pk11_DestroyObject(PK11Object *object) if (so) { pk11_PutObjectToList(so); } else { - PK11_USE_THREADS(PZ_DestroyLock(object->refLock);) - PORT_Free(to);; + if (object->refLock) { + PK11_USE_THREADS(PZ_DestroyLock(object->refLock);) + } + PORT_Free(to); } #else - PK11_USE_THREADS(PZ_DestroyLock(object->refLock);) + if (object->refLock) { + PK11_USE_THREADS(PZ_DestroyLock(object->refLock);) + } arena = object->arena; PORT_FreeArena(arena,PR_FALSE); #endif @@ -2557,7 +2561,7 @@ pk11_NewTokenObject(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle) arena = PORT_NewArena(2048); if (arena == NULL) return NULL; - object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11TokenObject)); + object = (PK11Object*)PORT_ArenaZAlloc(arena,sizeof(PK11TokenObject)); if (object == NULL) { PORT_FreeArena(arena,PR_FALSE); return NULL; @@ -2568,7 +2572,6 @@ pk11_NewTokenObject(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle) object->objclass = handleToClass(handle); object->handle = handle; - object->refCount = 1; object->slot = slot; object->objectInfo = NULL; object->infoFree = NULL; @@ -2593,11 +2596,12 @@ pk11_NewTokenObject(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle) goto loser; } #endif + object->refCount = 1; return object; loser: if (object) { - pk11_FreeObject(object); + (void) pk11_DestroyObject(object); } return NULL; diff --git a/security/nss/lib/softoken/softokn.def b/security/nss/lib/softoken/softokn.def index ef5e51e77..d851aa34d 100644 --- a/security/nss/lib/softoken/softokn.def +++ b/security/nss/lib/softoken/softokn.def @@ -44,14 +44,14 @@ ;+# 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 ";-" -;+SOFTOKEN_3.4 { # Softoken 3.4 release +;+NSS_3.4 { # NSS 3.4 release ;+ global: LIBRARY softokn3 ;- -EXPORTS ;- -NSC_GetFunctionList ; -NSC_ModuleDBFunc ; -FC_GetFunctionList ; -C_GetFunctionList ; Make this function like a real PKCS #11 module as well +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/ssl/ssl.def b/security/nss/lib/ssl/ssl.def index 89e23dde3..7833ae741 100644 --- a/security/nss/lib/ssl/ssl.def +++ b/security/nss/lib/ssl/ssl.def @@ -107,14 +107,11 @@ NSSSSL_VersionCheck; ;+}; ;+NSS_3.4 { # NSS 3.4 release ;+ global: -;+# We have not yet decided whether these functions will be exported -;+# in the final 3.4 release, so please treat them as exported private -;+# functions for now. -SSL_GetMaxServerCacheLocks; -SSL_SetMaxServerCacheLocks; SSL_GetChannelInfo; SSL_GetCipherSuiteInfo; +SSL_GetMaxServerCacheLocks; SSL_LocalCertificate; +SSL_SetMaxServerCacheLocks; ;+ local: ;+*; ;+}; diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index f080cb134..1e2da2e94 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -450,7 +450,7 @@ ssl3_config_match_init(sslSocket *ss) if (!ss->enableSSL3 && !ss->enableTLS) { return 0; } - isServer = (PRBool)( ss && ss->sec && ss->sec->isServer ); + isServer = (PRBool)( ss && ss->sec.isServer ); for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { suite = &ss->cipherSuites[i]; @@ -997,7 +997,6 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3) ssl3CipherSpec * pwSpec; ssl3CipherSpec * cwSpec; ssl3CipherSuite suite = ssl3->hs.cipher_suite; - sslSecurityInfo * sec = ss->sec; SSL3MACAlgorithm mac; SSL3BulkCipher cipher; SSL3KeyExchangeAlgorithm kea; @@ -1048,9 +1047,9 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, ssl3State *ssl3) PORT_Assert(pwSpec->mac_def->mac == mac); - sec->keyBits = pwSpec->cipher_def->key_size * BPB; - sec->secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB; - sec->cipherType = cipher; + ss->sec.keyBits = pwSpec->cipher_def->key_size * BPB; + ss->sec.secretKeyBits = pwSpec->cipher_def->secret_key_size * BPB; + ss->sec.cipherType = cipher; pwSpec->encodeContext = NULL; pwSpec->decodeContext = NULL; @@ -1073,7 +1072,6 @@ static SECStatus ssl3_InitPendingCipherSpec(sslSocket *ss, PK11SymKey *pms) { ssl3CipherSpec * pwSpec; - sslSecurityInfo * sec = ss->sec; const ssl3BulkCipherDef *cipher_def; PK11Context * serverContext = NULL; PK11Context * clientContext = NULL; @@ -1143,7 +1141,7 @@ const ssl3BulkCipherDef *cipher_def; goto fail; } serverContext = PK11_CreateContextBySymKey(mechanism, - (sec->isServer ? CKA_ENCRYPT : CKA_DECRYPT), + (ss->sec.isServer ? CKA_ENCRYPT : CKA_DECRYPT), pwSpec->server.write_key, param); iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); if (iv.data) @@ -1165,7 +1163,7 @@ const ssl3BulkCipherDef *cipher_def; goto fail; } clientContext = PK11_CreateContextBySymKey(mechanism, - (sec->isServer ? CKA_DECRYPT : CKA_ENCRYPT), + (ss->sec.isServer ? CKA_DECRYPT : CKA_ENCRYPT), pwSpec->client.write_key, param); iv.data = PK11_IVFromParam(mechanism, param, (int *)&iv.len); if (iv.data) @@ -1176,8 +1174,8 @@ const ssl3BulkCipherDef *cipher_def; goto fail; } - pwSpec->encodeContext = (sec->isServer) ? serverContext : clientContext; - pwSpec->decodeContext = (sec->isServer) ? clientContext : serverContext; + pwSpec->encodeContext = (ss->sec.isServer) ? serverContext : clientContext; + pwSpec->decodeContext = (ss->sec.isServer) ? clientContext : serverContext; pwSpec->encode = (SSLCipher) PK11_CipherOp; pwSpec->decode = (SSLCipher) PK11_CipherOp; pwSpec->destroy = (SSLDestroy) PK11_DestroyContext; @@ -1336,7 +1334,7 @@ ssl3_SendRecord( sslSocket * ss, PRInt32 flags) { ssl3CipherSpec * cwSpec; - sslBuffer * write = &ss->sec->writeBuf; + sslBuffer * write = &ss->sec.writeBuf; const ssl3BulkCipherDef * cipher_def; SECStatus rv; PRUint32 bufSize = 0; @@ -1405,8 +1403,8 @@ ssl3_SendRecord( sslSocket * ss, * Add the MAC */ rv = ssl3_ComputeRecordMAC( - cwSpec, (ss->sec->isServer) ? cwSpec->server.write_mac_context - : cwSpec->client.write_mac_context, + cwSpec, (ss->sec.isServer) ? cwSpec->server.write_mac_context + : cwSpec->client.write_mac_context, type, cwSpec->version, cwSpec->write_seq_num, write->buf + SSL3_RECORD_HEADER_LENGTH, contentLen, write->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen); @@ -1575,23 +1573,19 @@ static SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags) { PRInt32 rv; - sslConnectInfo *ci; - PORT_Assert(ss->sec != NULL); PORT_Assert( ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert( ssl_HaveXmitBufLock(ss) ); - ci = &ss->sec->ci; - - if (!ci->sendBuf.buf || !ci->sendBuf.len) + if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) return SECSuccess; - rv = ssl3_SendRecord(ss, content_handshake, ci->sendBuf.buf, - ci->sendBuf.len, flags); + rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf, + ss->sec.ci.sendBuf.len, flags); if (rv < 0) { return (SECStatus)rv; /* error code set by ssl3_SendRecord */ } - ci->sendBuf.len = 0; + ss->sec.ci.sendBuf.len = 0; return SECSuccess; } @@ -1604,13 +1598,13 @@ ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags) static SECStatus ssl3_HandleNoCertificate(sslSocket *ss) { - if (ss->sec->peerCert != NULL) { - if (ss->sec->peerKey != NULL) { - SECKEY_DestroyPublicKey(ss->sec->peerKey); - ss->sec->peerKey = NULL; + if (ss->sec.peerCert != NULL) { + if (ss->sec.peerKey != NULL) { + SECKEY_DestroyPublicKey(ss->sec.peerKey); + ss->sec.peerKey = NULL; } - CERT_DestroyCertificate(ss->sec->peerCert); - ss->sec->peerCert = NULL; + CERT_DestroyCertificate(ss->sec.peerCert); + ss->sec.peerCert = NULL; } ssl3_CleanupPeerCerts(ss->ssl3); @@ -1625,7 +1619,7 @@ ssl3_HandleNoCertificate(sslSocket *ss) (!ss->firstHsDone && (ss->requireCertificate > 1))) { PRFileDesc * lower; - ss->sec->uncache(ss->sec->ci.sid); + ss->sec.uncache(ss->sec.ci.sid); SSL3_SendAlert(ss, alert_fatal, bad_certificate); lower = ss->fd->lower; @@ -1681,8 +1675,8 @@ SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level, SSL3AlertDescription desc) ssl_GetSSL3HandshakeLock(ss); if (level == alert_fatal) { - if (ss->sec->ci.sid) { - ss->sec->uncache(ss->sec->ci.sid); + if (ss->sec.ci.sid) { + ss->sec.uncache(ss->sec.ci.sid); } } ssl_GetXmitBufLock(ss); @@ -1707,8 +1701,8 @@ ssl3_IllegalParameter(sslSocket *ss) isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0); (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); - PORT_SetError(ss->sec->isServer ? SSL_ERROR_BAD_CLIENT - : SSL_ERROR_BAD_SERVER ); + PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT + : SSL_ERROR_BAD_SERVER ); return SECFailure; } @@ -1719,8 +1713,8 @@ static SECStatus ssl3_HandshakeFailure(sslSocket *ss) { (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); - PORT_SetError( ss->sec->isServer ? SSL_ERROR_BAD_CLIENT - : SSL_ERROR_BAD_SERVER ); + PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT + : SSL_ERROR_BAD_SERVER ); return SECFailure; } @@ -1733,8 +1727,8 @@ ssl3_DecodeError(sslSocket *ss) (void)SSL3_SendAlert(ss, alert_fatal, ss->version > SSL_LIBRARY_VERSION_3_0 ? decode_error : illegal_parameter); - PORT_SetError( ss->sec->isServer ? SSL_ERROR_BAD_CLIENT - : SSL_ERROR_BAD_SERVER ); + PORT_SetError( ss->sec.isServer ? SSL_ERROR_BAD_CLIENT + : SSL_ERROR_BAD_SERVER ); return SECFailure; } @@ -1802,7 +1796,7 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; } if (level == alert_fatal) { - ss->sec->uncache(ss->sec->ci.sid); + ss->sec.uncache(ss->sec.ci.sid); if ((ss->ssl3->hs.ws == wait_server_hello) && (desc == handshake_failure)) { /* XXX This is a hack. We're assuming that any handshake failure @@ -1817,7 +1811,7 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) /* I'm a server. I've requested a client cert. He hasn't got one. */ SECStatus rv; - PORT_Assert(ss->sec->isServer); + PORT_Assert(ss->sec.isServer); ss->ssl3->hs.ws = wait_client_key; rv = ssl3_HandleNoCertificate(ss); return rv; @@ -2191,20 +2185,18 @@ ssl3_UpdateHandshakeHashes(sslSocket *ss, unsigned char *b, unsigned int l) static SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes) { - sslConnectInfo * ci = &ss->sec->ci; unsigned char * src = (unsigned char *)void_src; - int room = ci->sendBuf.space - ci->sendBuf.len; + int room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; SECStatus rv; PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) ); /* protects sendBuf. */ - if (ci->sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) { - rv = sslBuffer_Grow(&ci->sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH, - PR_MIN(MAX_SEND_BUF_LENGTH, - ci->sendBuf.len + bytes))); + if (ss->sec.ci.sendBuf.space < MAX_SEND_BUF_LENGTH && room < bytes) { + rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, PR_MAX(MIN_SEND_BUF_LENGTH, + PR_MIN(MAX_SEND_BUF_LENGTH, ss->sec.ci.sendBuf.len + bytes))); if (rv != SECSuccess) return rv; /* sslBuffer_Grow has set a memory error code. */ - room = ci->sendBuf.space - ci->sendBuf.len; + room = ss->sec.ci.sendBuf.space - ss->sec.ci.sendBuf.len; } PRINT_BUF(60, (ss, "Append to Handshake", (unsigned char*)void_src, bytes)); @@ -2214,19 +2206,20 @@ ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes) while (bytes > room) { if (room > 0) - PORT_Memcpy(ci->sendBuf.buf + ci->sendBuf.len, src, room); - ci->sendBuf.len += room; + PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, + room); + ss->sec.ci.sendBuf.len += room; rv = ssl3_FlushHandshake(ss, ssl_SEND_FLAG_FORCE_INTO_BUFFER); if (rv != SECSuccess) { return rv; /* error code set by ssl3_FlushHandshake */ } bytes -= room; src += room; - room = ci->sendBuf.space; - PORT_Assert(ci->sendBuf.len == 0); + room = ss->sec.ci.sendBuf.space; + PORT_Assert(ss->sec.ci.sendBuf.len == 0); } - PORT_Memcpy(ci->sendBuf.buf + ci->sendBuf.len, src, bytes); - ci->sendBuf.len += bytes; + PORT_Memcpy(ss->sec.ci.sendBuf.buf + ss->sec.ci.sendBuf.len, src, bytes); + ss->sec.ci.sendBuf.len += bytes; return SECSuccess; } @@ -2556,7 +2549,7 @@ ssl3_StartHandshakeHash(sslSocket *ss, unsigned char * buf, int length) PORT_Memset(&ss->ssl3->hs.client_random, 0, SSL3_RANDOM_LENGTH); PORT_Memcpy( &ss->ssl3->hs.client_random.rand[SSL3_RANDOM_LENGTH - SSL_CHALLENGE_BYTES], - &ss->sec->ci.clientChallenge, + &ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); rv = ssl3_UpdateHandshakeHashes(ss, buf, length); @@ -2580,7 +2573,6 @@ done: SECStatus ssl3_SendClientHello(sslSocket *ss) { - sslSecurityInfo *sec = ss->sec; sslSessionID * sid; ssl3CipherSpec * cwSpec; SECStatus rv; @@ -2613,15 +2605,13 @@ ssl3_SendClientHello(sslSocket *ss) return rv; } - PORT_Assert(sec); - - /* We ignore ss->sec->ci.sid here, and use ssl_Lookup because Lookup + /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup * handles expired entries and other details. * XXX If we've been called from ssl2_BeginClientHandshake, then * this lookup is duplicative and wasteful. */ sid = (ss->noCache) ? NULL - : ssl_LookupSID(&sec->ci.peer, sec->ci.port, ss->peerID, ss->url); + : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url); /* We can't resume based on a different token. If the sid exists, * make sure the token that holds the master secret still exists ... @@ -2680,7 +2670,7 @@ ssl3_SendClientHello(sslSocket *ss) if (!sidOK) { ++ssl3stats.sch_sid_cache_not_ok; - (*ss->sec->uncache)(sid); + (*ss->sec.uncache)(sid); ssl_FreeSID(sid); sid = NULL; } @@ -2718,12 +2708,12 @@ ssl3_SendClientHello(sslSocket *ss) } ssl_ReleaseSpecWriteLock(ss); - if (sec->ci.sid != NULL) { - ssl_FreeSID(sec->ci.sid); /* decrement ref count, free if zero */ + if (ss->sec.ci.sid != NULL) { + ssl_FreeSID(ss->sec.ci.sid); /* decrement ref count, free if zero */ } - sec->ci.sid = sid; + ss->sec.ci.sid = sid; - sec->send = ssl3_SendApplicationData; + ss->sec.send = ssl3_SendApplicationData; /* shouldn't get here if SSL3 is disabled, but ... */ PORT_Assert(ss->enableSSL3 || ss->enableTLS); @@ -2836,7 +2826,7 @@ ssl3_SendClientHello(sslSocket *ss) static SECStatus ssl3_HandleHelloRequest(sslSocket *ss) { - sslSessionID *sid = ss->sec->ci.sid; + sslSessionID *sid = ss->sec.ci.sid; SECStatus rv; SSL_TRC(3, ("%d: SSL3[%d]: handle hello_request handshake", @@ -2848,15 +2838,15 @@ ssl3_HandleHelloRequest(sslSocket *ss) if (ss->ssl3->hs.ws == wait_server_hello) return SECSuccess; - if (ss->ssl3->hs.ws != idle_handshake || ss->sec->isServer) { + if (ss->ssl3->hs.ws != idle_handshake || ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST); return SECFailure; } if (sid) { - ss->sec->uncache(sid); + ss->sec.uncache(sid); ssl_FreeSID(sid); - ss->sec->ci.sid = NULL; + ss->sec.ci.sid = NULL; } ssl_GetXmitBufLock(ss); @@ -3351,7 +3341,7 @@ sendFortezzaCKXClientAuth(sslSocket *ss, SSL3FortezzaKeys * fortezza_CKE) { SECKEYPublicKey * pubKey = NULL; SECKEYPrivateKey * privKeaKey = NULL; - CERTCertificate * peerCert = ss->sec->peerCert; + CERTCertificate * peerCert = ss->sec.peerCert; void * pwArg = ss->pkcs11PinArg; SECStatus rv = SECFailure; SECItem sigItem; @@ -3469,7 +3459,7 @@ sendFortezzaCKXNoClientAuth(sslSocket *ss) SECKEYPublicKey * foundPubKey = NULL; SECKEYPrivateKey * privKeaKey = NULL; CERTCertificate * ccert = NULL; - CERTCertificate * peerCert = ss->sec->peerCert; + CERTCertificate * peerCert = ss->sec.peerCert; void * pwArg = ss->pkcs11PinArg; SECStatus rv = SECFailure; @@ -3524,7 +3514,7 @@ static SECStatus sendFortezzaClientKeyExchange(sslSocket * ss, SECKEYPublicKey * serverKey) { ssl3CipherSpec * pwSpec = NULL; - sslSessionID * sid = ss->sec->ci.sid; + sslSessionID * sid = ss->sec.ci.sid; PK11SlotInfo * slot = NULL; PK11SymKey * pms = NULL; PK11SymKey * tek = NULL; @@ -3779,15 +3769,15 @@ ssl3_SendClientKeyExchange(sslSocket *ss) PORT_Assert( ssl_HaveXmitBufLock(ss)); PORT_Assert( ssl_HaveSSL3HandshakeLock(ss)); - if (ss->sec->peerKey == NULL) { - serverKey = CERT_ExtractPublicKey(ss->sec->peerCert); + if (ss->sec.peerKey == NULL) { + serverKey = CERT_ExtractPublicKey(ss->sec.peerCert); if (serverKey == NULL) { PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); return SECFailure; } } else { - serverKey = ss->sec->peerKey; - ss->sec->peerKey = NULL; /* we're done with it now */ + serverKey = ss->sec.peerKey; + ss->sec.peerKey = NULL; /* we're done with it now */ } isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0); @@ -3805,8 +3795,8 @@ ssl3_SendClientKeyExchange(sslSocket *ss) } } - ss->sec->keaType = ss->ssl3->hs.kea_def->exchKeyType; - ss->sec->keaKeyBits = SECKEY_PublicKeyStrength(serverKey) * BPB; + ss->sec.keaType = ss->ssl3->hs.kea_def->exchKeyType; + ss->sec.keaKeyBits = SECKEY_PublicKeyStrength(serverKey) * BPB; switch (ss->ssl3->hs.kea_def->exchKeyType) { case kt_rsa: @@ -3864,7 +3854,7 @@ ssl3_SendCertificateVerify(sslSocket *ss) rv = ssl3_SignHashes(&hashes, ssl3->clientPrivateKey, &buf, isTLS); if (rv == SECSuccess) { PK11SlotInfo * slot; - sslSessionID * sid = ss->sec->ci.sid; + sslSessionID * sid = ss->sec.ci.sid; /* Remember the info about the slot that did the signing. ** Later, when doing an SSL restart handshake, verify this. @@ -3911,7 +3901,7 @@ done: static SECStatus ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { - sslSessionID *sid = ss->sec->ci.sid; + sslSessionID *sid = ss->sec.ci.sid; PRInt32 temp; /* allow for consume number failure */ PRBool suite_found = PR_FALSE; int i; @@ -4053,12 +4043,11 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PK11SymKey * wrapKey; /* wrapping key */ SECItem wrappedMS; /* wrapped master secret. */ CK_FLAGS keyFlags = 0; - sslSecurityInfo *sec = ss->sec; - sec->authAlgorithm = sid->authAlgorithm; - sec->authKeyBits = sid->authKeyBits; - sec->keaType = sid->keaType; - sec->keaKeyBits = sid->keaKeyBits; + ss->sec.authAlgorithm = sid->authAlgorithm; + ss->sec.authKeyBits = sid->authKeyBits; + ss->sec.keaType = sid->keaType; + ss->sec.keaKeyBits = sid->keaKeyBits; slot = SECMOD_LookupSlot(sid->u.ssl3.masterModuleID, sid->u.ssl3.masterSlotID); @@ -4101,7 +4090,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) /* copy the peer cert from the SID */ if (sid->peerCert != NULL) { - ss->sec->peerCert = CERT_DupCertificate(sid->peerCert); + ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); } /* reload the FORTEZZA key material. These keys aren't generated @@ -4149,11 +4138,11 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) /* throw the old one away */ sid->u.ssl3.resumable = PR_FALSE; - (*ss->sec->uncache)(sid); + (*ss->sec.uncache)(sid); ssl_FreeSID(sid); /* get a new sid */ - ss->sec->ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE); + ss->sec.ci.sid = sid = ssl3_NewSessionID(ss, PR_FALSE); if (sid == NULL) { goto alert_loser; /* memory error is set. */ } @@ -4209,7 +4198,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) desc = unexpected_message; goto alert_loser; } - if (ss->sec->peerCert == NULL) { + if (ss->sec.peerCert == NULL) { errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH; desc = unexpected_message; goto alert_loser; @@ -4253,7 +4242,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); goto alert_loser; } - rv = ssl3_VerifySignedHashes(&hashes, ss->sec->peerCert, &signature, + rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, isTLS, ss->pkcs11PinArg); if (rv != SECSuccess) { errCode = @@ -4287,7 +4276,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_FreeArena(arena, PR_FALSE); goto no_memory; } - ss->sec->peerKey = peerKey; + ss->sec.peerKey = peerKey; SECITEM_FreeItem(&modulus, PR_FALSE); SECITEM_FreeItem(&exponent, PR_FALSE); SECITEM_FreeItem(&signature, PR_FALSE); @@ -4336,7 +4325,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ssl_MapLowLevelError(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE); goto alert_loser; } - rv = ssl3_VerifySignedHashes(&hashes, ss->sec->peerCert, &signature, + rv = ssl3_VerifySignedHashes(&hashes, ss->sec.peerCert, &signature, isTLS, ss->pkcs11PinArg); if (rv != SECSuccess) { errCode = @@ -4354,7 +4343,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) goto no_memory; } - ss->sec->peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); + ss->sec.peerKey = peerKey = PORT_ArenaZNew(arena, SECKEYPublicKey); if (peerKey == NULL) { goto no_memory; } @@ -4371,7 +4360,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_FreeArena(arena, PR_FALSE); goto no_memory; } - ss->sec->peerKey = peerKey; + ss->sec.peerKey = peerKey; SECITEM_FreeItem(&dh_p, PR_FALSE); SECITEM_FreeItem(&dh_g, PR_FALSE); SECITEM_FreeItem(&dh_Ys, PR_FALSE); @@ -4651,7 +4640,7 @@ ssl3_RestartHandshakeAfterCertReq(sslSocket * ss, } ssl_GetRecvBufLock(ss); if (ss->ssl3->hs.msgState.buf != NULL) { - rv = ssl3_HandleRecord(ss, NULL, &ss->gather->buf); + rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); } ssl_ReleaseRecvBufLock(ss); } @@ -4779,8 +4768,8 @@ ssl3_NewSessionID(sslSocket *ss, PRBool is_server) sid->peerID = (ss->peerID == NULL) ? NULL : PORT_Strdup(ss->peerID); sid->urlSvrName = (ss->url == NULL) ? NULL : PORT_Strdup(ss->url); - sid->addr = ss->sec->ci.peer; - sid->port = ss->sec->ci.port; + sid->addr = ss->sec.ci.peer; + sid->port = ss->sec.ci.port; sid->references = 1; sid->cached = never_cached; sid->version = ss->version; @@ -4891,7 +4880,6 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) { sslSessionID * sid = NULL; ssl3State * ssl3; - sslConnectInfo * ci; PRInt32 tmp; unsigned int i; int j; @@ -4929,7 +4917,6 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) errCode = SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO; goto alert_loser; } - ci = &ss->sec->ci; tmp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); if (tmp < 0) @@ -4957,10 +4944,11 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (sidBytes.len > 0) { SSL_TRC(7, ("%d: SSL3[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x", - SSL_GETPID(), ss->fd, ci->peer.pr_s6_addr32[0], - ci->peer.pr_s6_addr32[1], ci->peer.pr_s6_addr32[2], - ci->peer.pr_s6_addr32[3])); - sid = (*ssl_sid_lookup)(&ci->peer, sidBytes.data, sidBytes.len, + SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0], + ss->sec.ci.peer.pr_s6_addr32[1], + ss->sec.ci.peer.pr_s6_addr32[2], + ss->sec.ci.peer.pr_s6_addr32[3])); + sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sidBytes.data, sidBytes.len, ss->dbHandle); } SECITEM_FreeItem(&sidBytes, PR_FALSE); @@ -4996,7 +4984,7 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ((ss->requireCertificate == 2) && !ss->firstHsDone))) { ++ssl3stats.hch_sid_cache_not_ok; - ss->sec->uncache(sid); + ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; } @@ -5076,7 +5064,7 @@ compression_found: PORT_Free(comps.data); comps.data = NULL; - ss->sec->send = ssl3_SendApplicationData; + ss->sec.send = ssl3_SendApplicationData; /* If there are any failures while processing the old sid, * we don't consider them to be errors. Instead, We just behave @@ -5094,13 +5082,13 @@ compression_found: break; /* not an error */ } - if (ci->sid) { - ss->sec->uncache(ci->sid); - PORT_Assert(ci->sid != sid); /* should be impossible, but ... */ - if (ci->sid != sid) { - ssl_FreeSID(ci->sid); + if (ss->sec.ci.sid) { + ss->sec.uncache(ss->sec.ci.sid); + PORT_Assert(ss->sec.ci.sid != sid); /* should be impossible, but ... */ + if (ss->sec.ci.sid != sid) { + ssl_FreeSID(ss->sec.ci.sid); } - ci->sid = NULL; + ss->sec.ci.sid = NULL; } /* we need to resurrect the master secret.... */ @@ -5130,9 +5118,9 @@ compression_found: if (pwSpec->master_secret == NULL) { break; /* not an error */ } - ci->sid = sid; + ss->sec.ci.sid = sid; if (sid->peerCert != NULL) { - ss->sec->peerCert = CERT_DupCertificate(sid->peerCert); + ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); } /* @@ -5143,17 +5131,17 @@ compression_found: ++ssl3stats.hch_sid_cache_hits; ssl3->hs.isResuming = PR_TRUE; - ss->sec->authAlgorithm = sid->authAlgorithm; - ss->sec->authKeyBits = sid->authKeyBits; - ss->sec->keaType = sid->keaType; - ss->sec->keaKeyBits = sid->keaKeyBits; + ss->sec.authAlgorithm = sid->authAlgorithm; + ss->sec.authKeyBits = sid->authKeyBits; + ss->sec.keaType = sid->keaType; + ss->sec.keaKeyBits = sid->keaKeyBits; /* server sids don't remember the server cert we previously sent, ** but they do remember the kea type we originally used, so we ** can locate it again, provided that the current ssl socket ** has had its server certs configured the same as the previous one. */ - ss->sec->localCert = + ss->sec.localCert = CERT_DupCertificate(ss->serverCerts[sid->keaType].serverCert); ssl_GetXmitBufLock(ss); haveXmitBufLock = PR_TRUE; @@ -5271,7 +5259,7 @@ compression_found: if (sid) { /* we had a sid, but it's no longer valid, free it */ ++ssl3stats.hch_sid_cache_not_ok; - ss->sec->uncache(sid); + ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; } @@ -5282,7 +5270,7 @@ compression_found: errCode = PORT_GetError(); goto loser; /* memory error is set. */ } - ci->sid = sid; + ss->sec.ci.sid = sid; ssl3->hs.isResuming = PR_FALSE; ssl_GetXmitBufLock(ss); @@ -5439,7 +5427,7 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length) suite_found: ss->ssl3->hs.compression = compression_null; - ss->sec->send = ssl3_SendApplicationData; + ss->sec.send = ssl3_SendApplicationData; /* we don't even search for a cache hit here. It's just a miss. */ ++ssl3stats.hch_sid_cache_misses; @@ -5448,7 +5436,7 @@ suite_found: errCode = PORT_GetError(); goto loser; /* memory error is set. */ } - ss->sec->ci.sid = sid; + ss->sec.ci.sid = sid; /* do not worry about memory leak of sid since it now belongs to ci */ /* We have to update the handshake hashes before we can send stuff */ @@ -5500,7 +5488,6 @@ ssl3_SendServerHello(sslSocket *ss) SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(), ss->fd)); - PORT_Assert(ss->sec); PORT_Assert( ssl_HaveXmitBufLock(ss)); PORT_Assert( ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert( MSB(ss->version) == MSB(SSL_LIBRARY_VERSION_3_0)); @@ -5510,7 +5497,7 @@ ssl3_SendServerHello(sslSocket *ss) return SECFailure; } - sid = ss->sec->ci.sid; + sid = ss->sec.ci.sid; length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 + ((sid == NULL) ? 0: SSL3_SESSIONID_BYTES) + sizeof(ssl3CipherSuite) + 1; @@ -5784,7 +5771,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, PORT_Assert( ssl_HaveRecvBufLock(ss) ); PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) ); - if (ss->ssl3->hs.ws != wait_cert_verify || ss->sec->peerCert == NULL) { + if (ss->ssl3->hs.ws != wait_cert_verify || ss->sec.peerCert == NULL) { desc = unexpected_message; errCode = SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY; goto alert_loser; @@ -5798,7 +5785,7 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, isTLS = (PRBool)(ss->ssl3->prSpec->version > SSL_LIBRARY_VERSION_3_0); /* XXX verify that the key & kea match */ - rv = ssl3_VerifySignedHashes(hashes, ss->sec->peerCert, &signed_hash, + rv = ssl3_VerifySignedHashes(hashes, ss->sec.peerCert, &signed_hash, isTLS, ss->pkcs11PinArg); if (rv != SECSuccess) { errCode = PORT_GetError(); @@ -5836,7 +5823,7 @@ ssl3_HandleFortezzaClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PK11SymKey * tek = NULL; PK11SymKey * pms; PK11SymKey * Ks = NULL; - sslSessionID * sid = ss->sec->ci.sid; + sslSessionID * sid = ss->sec.ci.sid; ssl3CipherSpec * pwSpec = ss->ssl3->pwSpec; void * pwArg = ss->pkcs11PinArg; SECStatus rv; @@ -5868,10 +5855,10 @@ ssl3_HandleFortezzaClientKeyExchange(sslSocket *ss, SSL3Opaque *b, * from the card, but given these parameters, and *OUR* fortezza * card, we can always regenerate the same one on the fly. */ - if (ss->sec->peerCert != NULL) { + if (ss->sec.peerCert != NULL) { /* client-auth case */ - pubKey = CERT_ExtractPublicKey(ss->sec->peerCert); + pubKey = CERT_ExtractPublicKey(ss->sec.peerCert); if (pubKey == NULL) { SEND_ALERT PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); @@ -6261,11 +6248,11 @@ const ssl3KEADef * kea_def; #endif ) { serverKey = ss->stepDownKeyPair->privKey; - ss->sec->keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB; + ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB; } else { sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType; serverKey = sc->serverKey; - ss->sec->keaKeyBits = sc->serverKeyBits; + ss->sec.keaKeyBits = sc->serverKeyBits; } if (serverKey == NULL) { @@ -6274,7 +6261,7 @@ const ssl3KEADef * kea_def; return SECFailure; } - ss->sec->keaType = kea_def->exchKeyType; + ss->sec.keaType = kea_def->exchKeyType; switch (kea_def->exchKeyType) { case kt_rsa: @@ -6297,7 +6284,7 @@ const ssl3KEADef * kea_def; PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); return SECFailure; } - ss->ssl3->hs.ws = ss->sec->peerCert ? wait_cert_verify : wait_change_cipher; + ss->ssl3->hs.ws = ss->sec.peerCert ? wait_cert_verify : wait_change_cipher; return SECSuccess; } @@ -6333,18 +6320,18 @@ ssl3_SendCertificate(sslSocket *ss) PORT_Assert( ssl_HaveXmitBufLock(ss)); PORT_Assert( ssl_HaveSSL3HandshakeLock(ss)); - if (ss->sec->localCert) - CERT_DestroyCertificate(ss->sec->localCert); - if (ss->sec->isServer) { + if (ss->sec.localCert) + CERT_DestroyCertificate(ss->sec.localCert); + if (ss->sec.isServer) { sslServerCerts * sc = ss->serverCerts + ss->ssl3->hs.kea_def->exchKeyType; certChain = sc->serverCertChain; - ss->sec->authKeyBits = sc->serverKeyBits; - ss->sec->authAlgorithm = ss->ssl3->hs.kea_def->signKeyType; - ss->sec->localCert = CERT_DupCertificate(sc->serverCert); + ss->sec.authKeyBits = sc->serverKeyBits; + ss->sec.authAlgorithm = ss->ssl3->hs.kea_def->signKeyType; + ss->sec.localCert = CERT_DupCertificate(sc->serverCert); } else { certChain = ss->ssl3->clientCertChain; - ss->sec->localCert = CERT_DupCertificate(ss->ssl3->clientCertificate); + ss->sec.localCert = CERT_DupCertificate(ss->ssl3->clientCertificate); } if (certChain) { @@ -6400,12 +6387,11 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ssl3CertNode * certs = NULL; PRArenaPool * arena = NULL; ssl3State * ssl3 = ss->ssl3; - sslSecurityInfo *sec = ss->sec; CERTCertificate *cert; PRInt32 remaining = 0; PRInt32 size; SECStatus rv; - PRBool isServer = (PRBool)(!!sec->isServer); + PRBool isServer = (PRBool)(!!ss->sec.isServer); PRBool trusted = PR_FALSE; PRBool isTLS; SSL3AlertDescription desc = bad_certificate; @@ -6424,13 +6410,13 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) goto alert_loser; } - if (sec->peerCert != NULL) { - if (sec->peerKey) { - SECKEY_DestroyPublicKey(sec->peerKey); - sec->peerKey = NULL; + if (ss->sec.peerCert != NULL) { + if (ss->sec.peerKey) { + SECKEY_DestroyPublicKey(ss->sec.peerKey); + ss->sec.peerKey = NULL; } - CERT_DestroyCertificate(sec->peerCert); - sec->peerCert = NULL; + CERT_DestroyCertificate(ss->sec.peerCert); + ss->sec.peerCert = NULL; } ssl3_CleanupPeerCerts(ssl3); @@ -6487,9 +6473,9 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (rv != SECSuccess) goto loser; /* fatal alert already sent by ConsumeHandshake. */ - sec->peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, + ss->sec.peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, PR_FALSE, PR_TRUE); - if (sec->peerCert == NULL) { + if (ss->sec.peerCert == NULL) { /* We should report an alert if the cert was bad, but not if the * problem was just some local problem, like memory error. */ @@ -6542,7 +6528,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (remaining != 0) goto decode_loser; - SECKEY_UpdateCertPQG(sec->peerCert); + SECKEY_UpdateCertPQG(ss->sec.peerCert); /* * We're making a fortezza connection, and the card hasn't unloaded it's @@ -6551,7 +6537,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (!trusted) { CERTCertificate *ccert; - ccert = PK11_FindBestKEAMatch(sec->peerCert, ss->pkcs11PinArg); + ccert = PK11_FindBestKEAMatch(ss->sec.peerCert, ss->pkcs11PinArg); if (ccert) CERT_DestroyCertificate(ccert); } @@ -6582,7 +6568,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } /* start SSL Step Up, if appropriate */ - cert = sec->peerCert; + cert = ss->sec.peerCert; if (!isServer && ssl3_global_policy_some_restricted && ssl3->policy == SSL_ALLOWED && @@ -6595,18 +6581,18 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ssl3->hs.rehandshake = PR_TRUE; } - sec->ci.sid->peerCert = CERT_DupCertificate(sec->peerCert); + ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); - if (!sec->isServer) { + if (!ss->sec.isServer) { /* set the server authentication and key exchange types and sizes ** from the value in the cert. If the key exchange key is different, ** it will get fixed when we handle the server key exchange message. */ SECKEYPublicKey * pubKey = CERT_ExtractPublicKey(cert); - sec->authAlgorithm = ssl3->hs.kea_def->signKeyType; - sec->keaType = ssl3->hs.kea_def->exchKeyType; + ss->sec.authAlgorithm = ssl3->hs.kea_def->signKeyType; + ss->sec.keaType = ssl3->hs.kea_def->exchKeyType; if (pubKey) { - sec->keaKeyBits = sec->authKeyBits = + ss->sec.keaKeyBits = ss->sec.authKeyBits = SECKEY_PublicKeyStrength(pubKey) * BPB; SECKEY_DestroyPublicKey(pubKey); pubKey = NULL; @@ -6616,7 +6602,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ssl3->peerCertChain = certs; certs = NULL; arena = NULL; cert_block: - if (sec->isServer) { + if (ss->sec.isServer) { ssl3->hs.ws = wait_client_key; } else { ssl3->hs.ws = wait_cert_request; /* disallow server_key_exchange */ @@ -6684,9 +6670,9 @@ loser: ssl3->peerCertChain = certs; certs = NULL; arena = NULL; ssl3_CleanupPeerCerts(ssl3); - if (sec->peerCert != NULL) { - CERT_DestroyCertificate(sec->peerCert); - sec->peerCert = NULL; + if (ss->sec.peerCert != NULL) { + CERT_DestroyCertificate(ss->sec.peerCert); + ss->sec.peerCert = NULL; } (void)ssl_MapLowLevelError(errCode); return SECFailure; @@ -6715,15 +6701,15 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss) SET_ERROR_CODE return SECFailure; } - if (!ss->sec || !ss->ssl3) { + if (!ss->ssl3) { SET_ERROR_CODE return SECFailure; } - cert = ss->sec->peerCert; + cert = ss->sec.peerCert; /* Permit step up if user decided to accept the cert */ - if (!ss->sec->isServer && + if (!ss->sec.isServer && ssl3_global_policy_some_restricted && ssl3->policy == SSL_ALLOWED && anyRestrictedEnabled(ss) && @@ -6737,11 +6723,11 @@ ssl3_RestartHandshakeAfterServerCert(sslSocket *ss) if (ss->handshake != NULL) { ss->handshake = ssl_GatherRecord1stHandshake; - ss->sec->ci.sid->peerCert = CERT_DupCertificate(ss->sec->peerCert); + ss->sec.ci.sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); ssl_GetRecvBufLock(ss); if (ssl3->hs.msgState.buf != NULL) { - rv = ssl3_HandleRecord(ss, NULL, &ss->gather->buf); + rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf); } ssl_ReleaseRecvBufLock(ss); } @@ -6790,7 +6776,7 @@ ssl3_SendFinished(sslSocket *ss, PRInt32 flags) { ssl3CipherSpec *cwSpec; PRBool isTLS; - PRBool isServer = ss->sec->isServer; + PRBool isServer = ss->sec.isServer; SECStatus rv; SSL3Sender sender = isServer ? sender_server : sender_client; SSL3Finished hashes; @@ -6848,14 +6834,13 @@ static SECStatus ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, const SSL3Hashes *hashes) { - sslSecurityInfo * sec = ss->sec; ssl3State * ssl3 = ss->ssl3; - sslSessionID * sid = sec->ci.sid; + sslSessionID * sid = ss->sec.ci.sid; PK11SymKey * wrappingKey = NULL; PK11SlotInfo * symKeySlot; void * pwArg = ss->pkcs11PinArg; SECStatus rv; - PRBool isServer = sec->isServer; + PRBool isServer = ss->sec.isServer; PRBool isTLS; PRBool doStepUp; CK_MECHANISM_TYPE mechanism; @@ -6933,7 +6918,7 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length, /* Optimization: don't cache this connection if we're going to step up. */ if (doStepUp) { ssl_FreeSID(sid); - ss->sec->ci.sid = sid = NULL; + ss->sec.ci.sid = sid = NULL; ssl3->hs.rehandshake = PR_FALSE; rv = ssl3_SendClientHello(ss); xmit_loser: @@ -6946,8 +6931,8 @@ xmit_loser: /* The first handshake is now completed. */ ss->handshake = NULL; ss->firstHsDone = PR_TRUE; - ss->gather->writeOffset = 0; - ss->gather->readOffset = 0; + ss->gs.writeOffset = 0; + ss->gs.readOffset = 0; if (sid->cached == never_cached) { @@ -6957,13 +6942,13 @@ xmit_loser: sid->u.ssl3.policy = ssl3->policy; sid->u.ssl3.exchKeyType = ssl3->hs.kea_def->exchKeyType; sid->version = ss->version; - sid->authAlgorithm = sec->authAlgorithm; - sid->authKeyBits = sec->authKeyBits; - sid->keaType = sec->keaType; - sid->keaKeyBits = sec->keaKeyBits; + sid->authAlgorithm = ss->sec.authAlgorithm; + sid->authKeyBits = ss->sec.authKeyBits; + sid->keaType = ss->sec.keaType; + sid->keaKeyBits = ss->sec.keaKeyBits; sid->lastAccessTime = sid->creationTime = ssl_Time(); sid->expirationTime = sid->creationTime + ssl3_sid_timeout; - sid->localCert = CERT_DupCertificate(sec->localCert); + sid->localCert = CERT_DupCertificate(ss->sec.localCert); ssl_GetSpecReadLock(ss); /*************************************/ symKeySlot = PK11_GetSlotFromKey(ssl3->crSpec->master_secret); @@ -7041,7 +7026,7 @@ xmit_loser: * The connection continues normally however. */ if (!ss->noCache && rv == SECSuccess) { - (*sec->cache)(sid); + (*ss->sec.cache)(sid); } } ss->ssl3->hs.ws = idle_handshake; @@ -7078,7 +7063,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ssl3CipherSpec *rSpec = ss->ssl3->prSpec; if (type == finished) { - sender = ss->sec->isServer ? sender_client : sender_server; + sender = ss->sec.isServer ? sender_client : sender_server; rSpec = ss->ssl3->crSpec; } rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender); @@ -7130,7 +7115,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST); return SECFailure; } - if (ss->sec->isServer) { + if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST); return SECFailure; @@ -7138,7 +7123,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) rv = ssl3_HandleHelloRequest(ss); break; case client_hello: - if (!ss->sec->isServer) { + if (!ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO); return SECFailure; @@ -7146,7 +7131,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) rv = ssl3_HandleClientHello(ss, b, length); break; case server_hello: - if (ss->sec->isServer) { + if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO); return SECFailure; @@ -7157,7 +7142,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) rv = ssl3_HandleCertificate(ss, b, length); break; case server_key_exchange: - if (ss->sec->isServer) { + if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH); return SECFailure; @@ -7165,7 +7150,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) rv = ssl3_HandleServerKeyExchange(ss, b, length); break; case certificate_request: - if (ss->sec->isServer) { + if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST); return SECFailure; @@ -7178,7 +7163,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_DONE); return SECFailure; } - if (ss->sec->isServer) { + if (ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE); return SECFailure; @@ -7186,7 +7171,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) rv = ssl3_HandleServerHelloDone(ss); break; case certificate_verify: - if (!ss->sec->isServer) { + if (!ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY); return SECFailure; @@ -7194,7 +7179,7 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) rv = ssl3_HandleCertificateVerify(ss, b, length, &hashes); break; case client_key_exchange: - if (!ss->sec->isServer) { + if (!ss->sec.isServer) { (void)SSL3_SendAlert(ss, alert_fatal, unexpected_message); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH); return SECFailure; @@ -7467,7 +7452,7 @@ bad_pad: databuf->len -= crSpec->mac_size; rType = cText->type; rv = ssl3_ComputeRecordMAC( - crSpec, (ss->sec->isServer) ? crSpec->client.write_mac_context + crSpec, (ss->sec.isServer) ? crSpec->client.write_mac_context : crSpec->server.write_mac_context, rType, cText->version, crSpec->read_seq_num, databuf->buf, databuf->len, hash, &hashBytes); @@ -7633,7 +7618,7 @@ ssl3_InitState(sslSocket *ss) ssl3_InitCipherSpec(ss, ssl3->prSpec); ssl3->fortezza.tek = NULL; - ssl3->hs.ws = (ss->sec->isServer) ? wait_client_hello : wait_server_hello; + ssl3->hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; ssl_ReleaseSpecWriteLock(ss); /* @@ -7910,8 +7895,7 @@ ssl3_ConstructV2CipherSpecsHack(sslSocket *ss, unsigned char *cs, int *size) SECStatus ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache) { - sslSecurityInfo *sec = ss->sec; - sslSessionID * sid = ss->sec->ci.sid; + sslSessionID * sid = ss->sec.ci.sid; SECStatus rv; PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) ); @@ -7923,16 +7907,16 @@ ssl3_RedoHandshake(sslSocket *ss, PRBool flushCache) return SECFailure; } if (sid && flushCache) { - sec->uncache(sid); /* remove it from whichever cache it's in. */ + ss->sec.uncache(sid); /* remove it from whichever cache it's in. */ ssl_FreeSID(sid); /* dec ref count and free if zero. */ - ss->sec->ci.sid = NULL; + ss->sec.ci.sid = NULL; } ssl_GetXmitBufLock(ss); /**************************************/ /* start off a new handshake. */ - rv = (sec->isServer) ? ssl3_SendHelloRequest(ss) - : ssl3_SendClientHello(ss); + rv = (ss->sec.isServer) ? ssl3_SendHelloRequest(ss) + : ssl3_SendClientHello(ss); ssl_ReleaseXmitBufLock(ss); /**************************************/ return rv; diff --git a/security/nss/lib/ssl/ssl3gthr.c b/security/nss/lib/ssl/ssl3gthr.c index 2937e6c3c..92e1523b6 100644 --- a/security/nss/lib/ssl/ssl3gthr.c +++ b/security/nss/lib/ssl/ssl3gthr.c @@ -183,32 +183,31 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags) int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) { - sslGather * gs = ss->gather; SSL3Ciphertext cText; int rv; PORT_Assert( ssl_HaveRecvBufLock(ss) ); do { /* bring in the next sslv3 record. */ - rv = ssl3_GatherData(ss, gs, flags); + rv = ssl3_GatherData(ss, &ss->gs, flags); if (rv <= 0) { return rv; } /* decipher it, and handle it if it's a handshake. - * If it's application data, gs->buf will not be empty upon return. + * If it's application data, ss->gs.buf will not be empty upon return. */ - cText.type = (SSL3ContentType)gs->hdr[0]; - cText.version = (gs->hdr[1] << 8) | gs->hdr[2]; - cText.buf = &gs->inbuf; - rv = ssl3_HandleRecord(ss, &cText, &gs->buf); + cText.type = (SSL3ContentType)ss->gs.hdr[0]; + cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; + cText.buf = &ss->gs.inbuf; + rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf); if (rv < 0) { return ss->recvdCloseNotify ? 0 : rv; } - } while (ss->ssl3->hs.ws != idle_handshake && gs->buf.len == 0); + } while (ss->ssl3->hs.ws != idle_handshake && ss->gs.buf.len == 0); - gs->readOffset = 0; - gs->writeOffset = gs->buf.len; + ss->gs.readOffset = 0; + ss->gs.writeOffset = ss->gs.buf.len; return 1; } @@ -226,13 +225,12 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags) int ssl3_GatherAppDataRecord(sslSocket *ss, int flags) { - sslGather * gs = ss->gather; int rv; PORT_Assert( ssl_HaveRecvBufLock(ss) ); do { rv = ssl3_GatherCompleteHandshake(ss, flags); - } while (rv > 0 && gs->buf.len == 0); + } while (rv > 0 && ss->gs.buf.len == 0); return rv; } diff --git a/security/nss/lib/ssl/sslauth.c b/security/nss/lib/ssl/sslauth.c index f37b070ec..6be86ec9b 100644 --- a/security/nss/lib/ssl/sslauth.c +++ b/security/nss/lib/ssl/sslauth.c @@ -44,7 +44,6 @@ CERTCertificate * SSL_PeerCertificate(PRFileDesc *fd) { sslSocket *ss; - sslSecurityInfo *sec; ss = ssl_FindSocket(fd); if (!ss) { @@ -52,9 +51,8 @@ SSL_PeerCertificate(PRFileDesc *fd) SSL_GETPID(), fd)); return 0; } - sec = ss->sec; - if (ss->useSecurity && sec && sec->peerCert) { - return CERT_DupCertificate(sec->peerCert); + if (ss->useSecurity && ss->sec.peerCert) { + return CERT_DupCertificate(ss->sec.peerCert); } return 0; } @@ -64,7 +62,6 @@ CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd) { sslSocket *ss; - sslSecurityInfo *sec; ss = ssl_FindSocket(fd); if (!ss) { @@ -72,13 +69,12 @@ SSL_LocalCertificate(PRFileDesc *fd) SSL_GETPID(), fd)); return NULL; } - sec = ss->sec; - if (ss->useSecurity && sec ) { - if (sec->localCert) { - return CERT_DupCertificate(sec->localCert); + if (ss->useSecurity) { + if (ss->sec.localCert) { + return CERT_DupCertificate(ss->sec.localCert); } - if (sec->ci.sid && sec->ci.sid->localCert) { - return CERT_DupCertificate(sec->ci.sid->localCert); + if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) { + return CERT_DupCertificate(ss->sec.ci.sid->localCert); } } return NULL; @@ -92,7 +88,6 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, char **ip, char **sp) { sslSocket *ss; - sslSecurityInfo *sec; const char *cipherName; PRBool isDes = PR_FALSE; @@ -113,13 +108,11 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, } if (ss->useSecurity && ss->firstHsDone) { - PORT_Assert(ss->sec != 0); - sec = ss->sec; if (ss->version < SSL_LIBRARY_VERSION_3_0) { - cipherName = ssl_cipherName[sec->cipherType]; + cipherName = ssl_cipherName[ss->sec.cipherType]; } else { - cipherName = ssl3_cipherName[sec->cipherType]; + cipherName = ssl3_cipherName[ss->sec.cipherType]; } if (cipherName && PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE; /* do same key stuff for fortezza */ @@ -129,17 +122,17 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, } if (kp0) { - *kp0 = sec->keyBits; + *kp0 = ss->sec.keyBits; if (isDes) *kp0 = (*kp0 * 7) / 8; } if (kp1) { - *kp1 = sec->secretKeyBits; + *kp1 = ss->sec.secretKeyBits; if (isDes) *kp1 = (*kp1 * 7) / 8; } if (op) { - if (sec->keyBits == 0) { + if (ss->sec.keyBits == 0) { *op = SSL_SECURITY_STATUS_OFF; - } else if (sec->secretKeyBits < 90) { + } else if (ss->sec.secretKeyBits < 90) { *op = SSL_SECURITY_STATUS_ON_LOW; } else { @@ -150,7 +143,7 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, if (ip || sp) { CERTCertificate *cert; - cert = sec->peerCert; + cert = ss->sec.peerCert; if (cert) { if (ip) { *ip = CERT_NameToAscii(&cert->issuer); @@ -188,9 +181,6 @@ SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg) return SECFailure; } - if ((rv = ssl_CreateSecurityInfo(ss)) != 0) { - return rv; - } ss->authCertificate = func; ss->authCertificateArg = arg; @@ -212,9 +202,6 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func, return SECFailure; } - if ((rv = ssl_CreateSecurityInfo(ss)) != 0) { - return rv; - } ss->getClientAuthData = func; ss->getClientAuthDataArg = arg; return SECSuccess; @@ -234,9 +221,6 @@ SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) return SECFailure; } - if ((rv = ssl_CreateSecurityInfo(ss)) != 0) { - return rv; - } ss->pkcs11PinArg = arg; return SECSuccess; } @@ -266,7 +250,7 @@ SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) /* this may seem backwards, but isn't. */ certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; - rv = CERT_VerifyCertNow(handle, ss->sec->peerCert, checkSig, certUsage, + rv = CERT_VerifyCertNow(handle, ss->sec.peerCert, checkSig, certUsage, ss->pkcs11PinArg); if ( rv != SECSuccess || isServer ) @@ -278,7 +262,7 @@ SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) */ hostname = ss->url; if (hostname && hostname[0]) - rv = CERT_VerifyCertName(ss->sec->peerCert, hostname); + rv = CERT_VerifyCertName(ss->sec.peerCert, hostname); else rv = SECFailure; if (rv != SECSuccess) diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c index b4c395699..a1bfb4ce9 100644 --- a/security/nss/lib/ssl/sslcon.c +++ b/security/nss/lib/ssl/sslcon.c @@ -489,20 +489,15 @@ ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, static SECStatus ssl2_GetSendBuffer(sslSocket *ss, unsigned int len) { - sslConnectInfo *ci; SECStatus rv = SECSuccess; - PORT_Assert((ss->sec != 0)); - PORT_Assert(ssl_HaveXmitBufLock(ss)); - ci = &ss->sec->ci; - if (len < 128) { len = 128; } - if (len > ci->sendBuf.space) { - rv = sslBuffer_Grow(&ci->sendBuf, len); + if (len > ss->sec.ci.sendBuf.space) { + rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len); if (rv != SECSuccess) { SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes", SSL_GETPID(), ss->fd, len)); @@ -528,24 +523,21 @@ ssl2_GetSendBuffer(sslSocket *ss, unsigned int len) int ssl2_SendErrorMessage(sslSocket *ss, int error) { - sslSecurityInfo *sec; int rv; PRUint8 msg[SSL_HL_ERROR_HBYTES]; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); msg[0] = SSL_MT_ERROR; msg[1] = MSB(error); msg[2] = LSB(error); ssl_GetXmitBufLock(ss); /***************************************/ - sec = ss->sec; SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error)); ss->handshakeBegun = 1; - rv = (*sec->send)(ss, msg, sizeof(msg), 0); + rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0); if (rv >= 0) { rv = SECSuccess; } @@ -559,30 +551,26 @@ ssl2_SendErrorMessage(sslSocket *ss, int error) static SECStatus ssl2_SendClientFinishedMessage(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; SECStatus rv = SECSuccess; int sent; PRUint8 msg[1 + SSL_CONNECTIONID_BYTES]; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); ssl_GetXmitBufLock(ss); /***************************************/ - sec = ss->sec; - ci = &sec->ci; - if (ci->sentFinished == 0) { - ci->sentFinished = 1; + if (ss->sec.ci.sentFinished == 0) { + ss->sec.ci.sentFinished = 1; SSL_TRC(3, ("%d: SSL[%d]: sending client-finished", SSL_GETPID(), ss->fd)); msg[0] = SSL_MT_CLIENT_FINISHED; - PORT_Memcpy(msg+1, ci->connectionID, sizeof(ci->connectionID)); + PORT_Memcpy(msg+1, ss->sec.ci.connectionID, + sizeof(ss->sec.ci.connectionID)); - DUMP_MSG(29, (ss, msg, 1 + sizeof(ci->connectionID))); - sent = (*sec->send)(ss, msg, 1 + sizeof(ci->connectionID), 0); + DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID))); + sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0); rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; } ssl_ReleaseXmitBufLock(ss); /***************************************/ @@ -598,19 +586,14 @@ ssl2_SendClientFinishedMessage(sslSocket *ss) static SECStatus ssl2_SendServerVerifyMessage(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; PRUint8 * msg; int sendLen; int sent; SECStatus rv; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); ssl_GetXmitBufLock(ss); /***************************************/ - sec = ss->sec; - ci = &sec->ci; sendLen = 1 + SSL_CHALLENGE_BYTES; rv = ssl2_GetSendBuffer(ss, sendLen); @@ -618,12 +601,12 @@ ssl2_SendServerVerifyMessage(sslSocket *ss) goto done; } - msg = ci->sendBuf.buf; + msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_SERVER_VERIFY; - PORT_Memcpy(msg+1, ci->clientChallenge, SSL_CHALLENGE_BYTES); + PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); DUMP_MSG(29, (ss, msg, sendLen)); - sent = (*sec->send)(ss, msg, sendLen, 0); + sent = (*ss->sec.send)(ss, msg, sendLen, 0); rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; @@ -638,24 +621,19 @@ done: static SECStatus ssl2_SendServerFinishedMessage(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; sslSessionID * sid; PRUint8 * msg; int sendLen, sent; SECStatus rv = SECSuccess; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); ssl_GetXmitBufLock(ss); /***************************************/ - sec = ss->sec; - ci = &sec->ci; - if (ci->sentFinished == 0) { - ci->sentFinished = 1; - PORT_Assert(ci->sid != 0); - sid = ci->sid; + if (ss->sec.ci.sentFinished == 0) { + ss->sec.ci.sentFinished = 1; + PORT_Assert(ss->sec.ci.sid != 0); + sid = ss->sec.ci.sid; SSL_TRC(3, ("%d: SSL[%d]: sending server-finished", SSL_GETPID(), ss->fd)); @@ -666,25 +644,25 @@ ssl2_SendServerFinishedMessage(sslSocket *ss) goto done; } - msg = ci->sendBuf.buf; + msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_SERVER_FINISHED; PORT_Memcpy(msg+1, sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)); DUMP_MSG(29, (ss, msg, sendLen)); - sent = (*sec->send)(ss, msg, sendLen, 0); + sent = (*ss->sec.send)(ss, msg, sendLen, 0); if (sent < 0) { /* If send failed, it is now a bogus session-id */ - (*sec->uncache)(sid); + (*ss->sec.uncache)(sid); rv = (SECStatus)sent; } else if (!ss->noCache) { /* Put the sid in session-id cache, (may already be there) */ - (*sec->cache)(sid); + (*ss->sec.cache)(sid); rv = SECSuccess; } ssl_FreeSID(sid); - ci->sid = 0; + ss->sec.ci.sid = 0; } done: ssl_ReleaseXmitBufLock(ss); /***************************************/ @@ -702,17 +680,14 @@ ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, PRUint8 *ck, int ckLen, PRUint8 *ek, int ekLen) { - sslSecurityInfo *sec; PRUint8 * msg; int sendLen; int sent; SECStatus rv; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); ssl_GetXmitBufLock(ss); /***************************************/ - sec = ss->sec; sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen; rv = ssl2_GetSendBuffer(ss, sendLen); @@ -722,7 +697,7 @@ ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key", SSL_GETPID(), ss->fd)); - msg = sec->ci.sendBuf.buf; + msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_CLIENT_MASTER_KEY; msg[1] = cipher; msg[2] = MSB(keySize); @@ -738,7 +713,7 @@ ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen); DUMP_MSG(29, (ss, msg, sendLen)); - sent = (*sec->send)(ss, msg, sendLen, 0); + sent = (*ss->sec.send)(ss, msg, sendLen, 0); rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; done: ssl_ReleaseXmitBufLock(ss); /***************************************/ @@ -751,19 +726,14 @@ done: static SECStatus ssl2_SendCertificateRequestMessage(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; PRUint8 * msg; int sent; int sendLen; SECStatus rv; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); ssl_GetXmitBufLock(ss); /***************************************/ - sec = ss->sec; - ci = &sec->ci; sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES; rv = ssl2_GetSendBuffer(ss, sendLen); @@ -774,16 +744,16 @@ ssl2_SendCertificateRequestMessage(sslSocket *ss) SSL_GETPID(), ss->fd)); /* Generate random challenge for client to encrypt */ - PK11_GenerateRandom(ci->serverChallenge, SSL_CHALLENGE_BYTES); + PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); - msg = ci->sendBuf.buf; + msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_REQUEST_CERTIFICATE; msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION; - PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, ci->serverChallenge, - SSL_CHALLENGE_BYTES); + PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, + ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); DUMP_MSG(29, (ss, msg, sendLen)); - sent = (*sec->send)(ss, msg, sendLen, 0); + sent = (*ss->sec.send)(ss, msg, sendLen, 0); rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; done: ssl_ReleaseXmitBufLock(ss); /***************************************/ @@ -798,15 +768,12 @@ static int ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, SECItem *encCode) { - sslSecurityInfo *sec; PRUint8 *msg; int rv, sendLen; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); ssl_GetXmitBufLock(ss); /***************************************/ - sec = ss->sec; sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len; rv = ssl2_GetSendBuffer(ss, sendLen); @@ -816,7 +783,7 @@ ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, SSL_TRC(3, ("%d: SSL[%d]: sending certificate response", SSL_GETPID(), ss->fd)); - msg = sec->ci.sendBuf.buf; + msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_CLIENT_CERTIFICATE; msg[1] = SSL_CT_X509_CERTIFICATE; msg[2] = MSB(cert->len); @@ -828,7 +795,7 @@ ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, encCode->data, encCode->len); DUMP_MSG(29, (ss, msg, sendLen)); - rv = (*sec->send)(ss, msg, sendLen, 0); + rv = (*ss->sec.send)(ss, msg, sendLen, 0); if (rv >= 0) { rv = SECSuccess; } @@ -840,7 +807,7 @@ done: /******************************************************************** ** Send functions above this line must aquire & release the socket's ** xmitBufLock. -** All the ssl2_Send functions below this line are called vis ss->sec->send +** All the ssl2_Send functions below this line are called vis ss->sec.send ** and require that the caller hold the xmitBufLock. */ @@ -911,13 +878,11 @@ ssl2_CalcMAC(PRUint8 * result, static PRInt32 ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) { - sslSecurityInfo * sec = ss->sec; PRUint8 * out; int rv; int amount; int count = 0; - PORT_Assert(sec != 0); PORT_Assert( ssl_HaveXmitBufLock(ss) ); SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear", @@ -926,14 +891,14 @@ ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) while (len) { amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); - if (amount + 2 > sec->writeBuf.space) { - rv = sslBuffer_Grow(&sec->writeBuf, amount + 2); + if (amount + 2 > ss->sec.writeBuf.space) { + rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2); if (rv != SECSuccess) { count = rv; break; } } - out = sec->writeBuf.buf; + out = ss->sec.writeBuf.buf; /* ** Construct message. @@ -962,12 +927,12 @@ ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) count = SECFailure; } else { count += amount; - sec->sendSequence++; + ss->sec.sendSequence++; } break; } - sec->sendSequence++; + ss->sec.sendSequence++; in += amount; count += amount; len -= amount; @@ -984,7 +949,6 @@ ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) static PRInt32 ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) { - sslSecurityInfo *sec = ss->sec; PRUint8 * out; int rv; int count = 0; @@ -994,7 +958,6 @@ ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) int nout; int buflen; - PORT_Assert(sec != 0); PORT_Assert( ssl_HaveXmitBufLock(ss) ); SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher", @@ -1004,34 +967,34 @@ ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) while (len) { ssl_GetSpecReadLock(ss); /*************************************/ - macLen = sec->hash->length; + macLen = ss->sec.hash->length; amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); buflen = amount + 2 + macLen; - if (buflen > sec->writeBuf.space) { - rv = sslBuffer_Grow(&sec->writeBuf, buflen); + if (buflen > ss->sec.writeBuf.space) { + rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); if (rv != SECSuccess) { goto loser; } } - out = sec->writeBuf.buf; + out = ss->sec.writeBuf.buf; nout = amount + macLen; out[0] = 0x80 | MSB(nout); out[1] = LSB(nout); /* Calculate MAC */ rv = ssl2_CalcMAC(out+2, /* put MAC here */ - sec, + &ss->sec, in, amount, /* input addr & length */ 0); /* no padding */ if (rv != SECSuccess) goto loser; /* Encrypt MAC */ - rv = (*sec->enc)(sec->writecx, out+2, &nout, macLen, out+2, macLen); + rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen); if (rv) goto loser; /* Encrypt data from caller */ - rv = (*sec->enc)(sec->writecx, out+2+macLen, &nout, amount, in, amount); + rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount); if (rv) goto loser; ssl_ReleaseSpecReadLock(ss); /*************************************/ @@ -1061,12 +1024,12 @@ ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) count = SECFailure; } else { count += amount; - sec->sendSequence++; + ss->sec.sendSequence++; } goto done; } - sec->sendSequence++; + ss->sec.sendSequence++; in += amount; count += amount; len -= amount; @@ -1088,7 +1051,6 @@ loser: static PRInt32 ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) { - sslSecurityInfo *sec = ss->sec; PRUint8 * out; /* begining of output buffer. */ PRUint8 * op; /* next output byte goes here. */ int rv; /* value from funcs we called. */ @@ -1101,7 +1063,6 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) int nout; /* ciphertext size after header. */ int buflen; /* size of generated record. */ - PORT_Assert(sec != 0); PORT_Assert( ssl_HaveXmitBufLock(ss) ); SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher", @@ -1111,26 +1072,26 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) while (len) { ssl_GetSpecReadLock(ss); /*************************************/ - macLen = sec->hash->length; + macLen = ss->sec.hash->length; /* Figure out how much to send, including mac and padding */ amount = PR_MIN( len, MAX_BLOCK_CYPHER_LEN ); nout = amount + macLen; - padding = nout & (sec->blockSize - 1); + padding = nout & (ss->sec.blockSize - 1); if (padding) { hlen = 3; - padding = sec->blockSize - padding; + padding = ss->sec.blockSize - padding; nout += padding; } else { hlen = 2; } buflen = hlen + nout; - if (buflen > sec->writeBuf.space) { - rv = sslBuffer_Grow(&sec->writeBuf, buflen); + if (buflen > ss->sec.writeBuf.space) { + rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); if (rv != SECSuccess) { goto loser; } } - out = sec->writeBuf.buf; + out = ss->sec.writeBuf.buf; /* Construct header */ op = out; @@ -1145,7 +1106,7 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) /* Calculate MAC */ rv = ssl2_CalcMAC(op, /* MAC goes here. */ - sec, + &ss->sec, in, amount, /* intput addr, len */ padding); if (rv != SECSuccess) @@ -1162,7 +1123,7 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) } /* Encrypt result */ - rv = (*sec->enc)(sec->writecx, out+hlen, &nout, buflen-hlen, + rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen, out+hlen, op - (out + hlen)); if (rv) goto loser; @@ -1192,12 +1153,12 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) count = SECFailure; } else { count += amount; - sec->sendSequence++; + ss->sec.sendSequence++; } goto done; } - sec->sendSequence++; + ss->sec.sendSequence++; in += amount; count += amount; len -= amount; @@ -1221,15 +1182,11 @@ loser: static void ssl2_UseEncryptedSendFunc(sslSocket *ss) { - sslSecurityInfo *sec; - ssl_GetXmitBufLock(ss); - PORT_Assert(ss->sec != 0); - sec = ss->sec; - PORT_Assert(sec->hashcx != 0); + PORT_Assert(ss->sec.hashcx != 0); - ss->gather->encrypted = 1; - sec->send = (sec->blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream; + ss->gs.encrypted = 1; + ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream; ssl_ReleaseXmitBufLock(ss); } @@ -1239,7 +1196,7 @@ ssl2_UseEncryptedSendFunc(sslSocket *ss) void ssl2_UseClearSendFunc(sslSocket *ss) { - ss->sec->send = ssl2_SendClear; + ss->sec.send = ssl2_SendClear; } /************************************************************************ @@ -1290,7 +1247,6 @@ ssl_GatherRecord1stHandshake(sslSocket *ss) { int rv; - PORT_Assert((ss->sec != 0) && (ss->gather != 0)); PORT_Assert( ssl_Have1stHandshakeLock(ss) ); ssl_GetRecvBufLock(ss); @@ -1311,7 +1267,7 @@ ssl_GatherRecord1stHandshake(sslSocket *ss) if (rv == SECWouldBlock) { /* Progress is blocked waiting for callback completion. */ SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)", - SSL_GETPID(), ss->fd, ss->gather->remainder)); + SSL_GETPID(), ss->fd, ss->gs.remainder)); return SECWouldBlock; } if (rv == 0) { @@ -1322,7 +1278,7 @@ ssl_GatherRecord1stHandshake(sslSocket *ss) } SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes", - SSL_GETPID(), ss->fd, ss->gather->recordLen)); + SSL_GETPID(), ss->fd, ss->gs.recordLen)); ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/ return SECSuccess; @@ -1410,7 +1366,6 @@ ssl2_ProduceKeys(sslSocket * ss, writeKey->data = 0; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); rv = SECSuccess; cx = PK11_CreateDigestContext(SEC_OID_MD5); @@ -1467,8 +1422,6 @@ loser: static SECStatus ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) { - sslSecurityInfo * sec = NULL; - sslConnectInfo * ci; SECItem * rk = NULL; SECItem * wk = NULL; SECItem * param; @@ -1485,8 +1438,7 @@ ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) writeKey.data = 0; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); - if((ss->sec == 0) || (ss->sec->ci.sid == 0)) + if((ss->sec.ci.sid == 0)) goto sec_loser; /* don't crash if asserts are off */ /* Trying to cut down on all these switch statements that should be tables. @@ -1508,26 +1460,24 @@ ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) goto sec_loser; } - sec = ss->sec; - ci = &sec->ci; rk = isClient ? &readKey : &writeKey; wk = isClient ? &writeKey : &readKey; /* Produce the keys for this session */ rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey, - ci->clientChallenge, ci->connectionID, + ss->sec.ci.clientChallenge, ss->sec.ci.connectionID, cipherType); if (rv != SECSuccess) goto loser; PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len)); PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len)); - PORT_Memcpy(ci->readKey, readKey.data, readKey.len); - PORT_Memcpy(ci->writeKey, writeKey.data, writeKey.len); - ci->keySize = readKey.len; + PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len); + PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len); + ss->sec.ci.keySize = readKey.len; /* Setup the MAC */ - rv = ssl2_CreateMAC(sec, rk, wk, cipherType); + rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType); if (rv != SECSuccess) goto loser; @@ -1539,7 +1489,7 @@ ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) mechanism = ssl_Specs[cipherType].mechanism; /* set destructer before we call loser... */ - sec->destroy = (void (*)(void*, PRBool)) PK11_DestroyContext; + ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext; slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg); if (slot == NULL) goto loser; @@ -1567,23 +1517,23 @@ ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) PK11_FreeSlot(slot); rv = SECSuccess; - sec->enc = (SSLCipher) PK11_CipherOp; - sec->dec = (SSLCipher) PK11_CipherOp; - sec->readcx = (void *) readcx; - sec->writecx = (void *) writecx; - sec->blockSize = ssl_Specs[cipherType].blockSize; - sec->blockShift = ssl_Specs[cipherType].blockShift; - sec->cipherType = sid->u.ssl2.cipherType; - sec->keyBits = sid->u.ssl2.keyBits; - sec->secretKeyBits = sid->u.ssl2.secretKeyBits; + ss->sec.enc = (SSLCipher) PK11_CipherOp; + ss->sec.dec = (SSLCipher) PK11_CipherOp; + ss->sec.readcx = (void *) readcx; + ss->sec.writecx = (void *) writecx; + ss->sec.blockSize = ssl_Specs[cipherType].blockSize; + ss->sec.blockShift = ssl_Specs[cipherType].blockShift; + ss->sec.cipherType = sid->u.ssl2.cipherType; + ss->sec.keyBits = sid->u.ssl2.keyBits; + ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits; goto done; loser: - if (sec->destroy) { - if (readcx) (*sec->destroy)(readcx, PR_TRUE); - if (writecx) (*sec->destroy)(writecx, PR_TRUE); + if (ss->sec.destroy) { + if (readcx) (*ss->sec.destroy)(readcx, PR_TRUE); + if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE); } - sec->destroy = NULL; + ss->sec.destroy = NULL; if (slot) PK11_FreeSlot(slot); sec_loser: @@ -1628,7 +1578,6 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, PRUint8 *ca, unsigned int caLen) { PRUint8 *kk = NULL; - sslSecurityInfo * sec; sslSessionID * sid; PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */ unsigned int el1; /* length of RSA decrypted data in kbuf */ @@ -1640,10 +1589,9 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, PORT_Assert( ssl_Have1stHandshakeLock(ss) ); PORT_Assert( ssl_HaveRecvBufLock(ss) ); - PORT_Assert((ss->sec != 0) && (sc->serverKey != 0)); - sec = ss->sec; - PORT_Assert((sec->ci.sid != 0)); - sid = sec->ci.sid; + PORT_Assert((sc->serverKey != 0)); + PORT_Assert((ss->sec.ci.sid != 0)); + sid = ss->sec.ci.sid; keySize = (keyBits + 7) >> 3; /* Is the message just way too big? */ @@ -1760,8 +1708,8 @@ hide_loser: /* Fill in session-id */ rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen, keyBits, keyBits - (ckLen<<3), - sec->authAlgorithm, sec->authKeyBits, - sec->keaType, sec->keaKeyBits); + ss->sec.authAlgorithm, ss->sec.authKeyBits, + ss->sec.keaType, ss->sec.keaKeyBits); if (rv != SECSuccess) { goto loser; } @@ -1968,8 +1916,6 @@ ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen) CERTCertificate *cert = NULL; SECItem certItem; - PORT_Assert(ss->sec != 0); - certItem.data = certData; certItem.len = certLen; @@ -2001,7 +1947,7 @@ ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen) } #endif - ss->sec->peerCert = cert; + ss->sec.peerCert = cert; return SECSuccess; } @@ -2076,7 +2022,6 @@ static SECStatus ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) { sslSessionID * sid; - sslSecurityInfo * sec; PRUint8 * ca; /* points to iv data, or NULL if none. */ PRUint8 * ekbuf = 0; CERTCertificate * cert = 0; @@ -2096,15 +2041,13 @@ ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) PRUint8 iv [8]; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); eblock = NULL; - sec = ss->sec; - sid = sec->ci.sid; + sid = ss->sec.ci.sid; PORT_Assert(sid != 0); - cert = sec->peerCert; + cert = ss->sec.peerCert; serverKey = CERT_ExtractPublicKey(cert); if (!serverKey) { @@ -2115,10 +2058,10 @@ ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) goto loser2; } - sec->authAlgorithm = ssl_sign_rsa; - sec->keaType = ssl_kea_rsa; - sec->keaKeyBits = \ - sec->authKeyBits = SECKEY_PublicKeyStrength(serverKey) * BPB; + ss->sec.authAlgorithm = ssl_sign_rsa; + ss->sec.keaType = ssl_kea_rsa; + ss->sec.keaKeyBits = \ + ss->sec.authKeyBits = SECKEY_PublicKeyStrength(serverKey) * BPB; /* Choose a compatible cipher with the server */ nc = csLen / 3; @@ -2155,8 +2098,8 @@ ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) /* Fill in session-id */ rv = ssl2_FillInSID(sid, cipher, keyData, keyLen, ca, caLen, keyLen << 3, (keyLen - ckLen) << 3, - sec->authAlgorithm, sec->authKeyBits, - sec->keaType, sec->keaKeyBits); + ss->sec.authAlgorithm, ss->sec.authKeyBits, + ss->sec.keaType, ss->sec.keaKeyBits); if (rv != SECSuccess) { goto loser; } @@ -2230,38 +2173,29 @@ ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) static void ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s) { - sslSecurityInfo *sec; - sslSessionID *sid; - - PORT_Assert((ss->sec != 0)); - sec = ss->sec; - sid = sec->ci.sid; + sslSessionID *sid = ss->sec.ci.sid; /* Record entry in nonce cache */ if (sid->peerCert == NULL) { PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID)); - sid->peerCert = CERT_DupCertificate(sec->peerCert); + sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); } if (!ss->noCache) - (*sec->cache)(sid); + (*ss->sec.cache)(sid); } /* Called from ssl2_HandleMessage() */ static SECStatus ssl2_TriggerNextMessage(sslSocket *ss) { - sslConnectInfo * ci; SECStatus rv; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); - - ci = &ss->sec->ci; - if ((ci->requiredElements & CIS_HAVE_CERTIFICATE) && - !(ci->sentElements & CIS_HAVE_CERTIFICATE)) { - ci->sentElements |= CIS_HAVE_CERTIFICATE; + if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) && + !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) { + ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE; rv = ssl2_SendCertificateRequestMessage(ss); return rv; } @@ -2282,21 +2216,15 @@ ssl2_TriggerNextMessage(sslSocket *ss) static SECStatus ssl2_TryToFinish(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; SECStatus rv; char e, ef; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); - sec = ss->sec; - ci = &sec->ci; - - e = ci->elements; + e = ss->sec.ci.elements; ef = e | CIS_HAVE_FINISHED; - if ((ef & ci->requiredElements) == ci->requiredElements) { - if (sec->isServer) { + if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { + if (ss->sec.isServer) { /* Send server finished message if we already didn't */ rv = ssl2_SendServerFinishedMessage(ss); } else { @@ -2306,7 +2234,7 @@ ssl2_TryToFinish(sslSocket *ss) if (rv != SECSuccess) { return rv; } - if ((e & ci->requiredElements) == ci->requiredElements) { + if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { /* Totally finished */ ss->handshake = 0; return SECSuccess; @@ -2325,18 +2253,14 @@ ssl2_SignResponse(sslSocket *ss, SECItem *response) { SGNContext * sgn = NULL; - sslConnectInfo * ci; - sslSecurityInfo *sec; PRUint8 * challenge; unsigned int len; SECStatus rv = SECFailure; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - sec = ss->sec; - ci = &sec->ci; - challenge = ci->serverChallenge; - len = ci->serverChallengeLen; + challenge = ss->sec.ci.serverChallenge; + len = ss->sec.ci.serverChallengeLen; /* Sign the expected data... */ sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key); @@ -2345,17 +2269,17 @@ ssl2_SignResponse(sslSocket *ss, rv = SGN_Begin(sgn); if (rv != SECSuccess) goto done; - rv = SGN_Update(sgn, ci->readKey, ci->keySize); + rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize); if (rv != SECSuccess) goto done; - rv = SGN_Update(sgn, ci->writeKey, ci->keySize); + rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize); if (rv != SECSuccess) goto done; rv = SGN_Update(sgn, challenge, len); if (rv != SECSuccess) goto done; - rv = SGN_Update(sgn, - sec->peerCert->derCert.data, sec->peerCert->derCert.len); + rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, + ss->sec.peerCert->derCert.len); if (rv != SECSuccess) goto done; rv = SGN_End(sgn, response); @@ -2390,14 +2314,8 @@ ssl2_HandleRequestCertificate(sslSocket *ss) */ response.data = NULL; - PORT_Assert((ss->sec != 0)); - if (!ss->sec) { - PORT_SetError(PR_INVALID_ARGUMENT_ERROR); - return SECFailure; - } - /* get challenge info from connectionInfo */ - authType = ss->sec->ci.authType; + authType = ss->sec.ci.authType; if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) { SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(), @@ -2432,15 +2350,15 @@ ssl2_HandleRequestCertificate(sslSocket *ss) ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response); /* Now, remember the cert we sent. But first, forget any previous one. */ - if (ss->sec->localCert) { - CERT_DestroyCertificate(ss->sec->localCert); + if (ss->sec.localCert) { + CERT_DestroyCertificate(ss->sec.localCert); } - ss->sec->localCert = CERT_DupCertificate(cert); - PORT_Assert(!ss->sec->ci.sid->localCert); - if (ss->sec->ci.sid->localCert) { - CERT_DestroyCertificate(ss->sec->ci.sid->localCert); + ss->sec.localCert = CERT_DupCertificate(cert); + PORT_Assert(!ss->sec.ci.sid->localCert); + if (ss->sec.ci.sid->localCert) { + CERT_DestroyCertificate(ss->sec.ci.sid->localCert); } - ss->sec->ci.sid->localCert = cert; + ss->sec.ci.sid->localCert = cert; cert = NULL; goto done; @@ -2478,8 +2396,6 @@ ssl2_HandleClientCertificate(sslSocket * ss, PRUint8 * response, unsigned int responseLen) { - sslSecurityInfo *sec = ss->sec; - sslConnectInfo * ci; CERTCertificate *cert = NULL; SECKEYPublicKey *pubKey = NULL; VFYContext * vfy = NULL; @@ -2502,7 +2418,7 @@ ssl2_HandleClientCertificate(sslSocket * ss, } /* save the certificate, since the auth routine will need it */ - sec->peerCert = cert; + ss->sec.peerCert = cert; /* Extract the public key */ pubKey = CERT_ExtractPublicKey(cert); @@ -2522,14 +2438,13 @@ ssl2_HandleClientCertificate(sslSocket * ss, if (rv) goto loser; - ci = &sec->ci; - rv = VFY_Update(vfy, ci->readKey, ci->keySize); + rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize); if (rv) goto loser; - rv = VFY_Update(vfy, ci->writeKey, ci->keySize); + rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize); if (rv) goto loser; - rv = VFY_Update(vfy, ci->serverChallenge, SSL_CHALLENGE_BYTES); + rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); if (rv) goto loser; @@ -2549,7 +2464,7 @@ ssl2_HandleClientCertificate(sslSocket * ss, goto done; loser: - sec->peerCert = NULL; + ss->sec.peerCert = NULL; CERT_DestroyCertificate(cert); done: @@ -2571,9 +2486,6 @@ done: static SECStatus ssl2_HandleMessage(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; - sslGather * gs; PRUint8 * data; PRUint8 * cid; unsigned len, certType, certLen, responseLen; @@ -2581,67 +2493,66 @@ ssl2_HandleMessage(sslSocket *ss) int rv2; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0) && (ss->gather != 0)); ssl_GetRecvBufLock(ss); - sec = ss->sec; - gs = ss->gather; - ci = &sec->ci; - data = gs->buf.buf + gs->recordOffset; + data = ss->gs.buf.buf + ss->gs.recordOffset; - if (gs->recordLen < 1) { + if (ss->gs.recordLen < 1) { goto bad_peer; } SSL_TRC(3, ("%d: SSL[%d]: received %d message", SSL_GETPID(), ss->fd, data[0])); - DUMP_MSG(29, (ss, data, gs->recordLen)); + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); switch (data[0]) { case SSL_MT_CLIENT_FINISHED: - if (ci->elements & CIS_HAVE_FINISHED) { + if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { SSL_DBG(("%d: SSL[%d]: dup client-finished message", SSL_GETPID(), ss->fd)); goto bad_peer; } /* See if nonce matches */ - len = gs->recordLen - 1; + len = ss->gs.recordLen - 1; cid = data + 1; - if ((len != sizeof(ci->connectionID)) || - (PORT_Memcmp(ci->connectionID, cid, len) != 0)) { + if ((len != sizeof(ss->sec.ci.connectionID)) || + (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) { SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd)); PRINT_BUF(5, (ss, "sent connection-id", - ci->connectionID, sizeof(ci->connectionID))); + ss->sec.ci.connectionID, + sizeof(ss->sec.ci.connectionID))); PRINT_BUF(5, (ss, "rcvd connection-id", cid, len)); goto bad_peer; } SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d", - SSL_GETPID(), ss->fd, ci->requiredElements ^ ci->elements)); - ci->elements |= CIS_HAVE_FINISHED; + SSL_GETPID(), ss->fd, + ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); + ss->sec.ci.elements |= CIS_HAVE_FINISHED; break; case SSL_MT_SERVER_FINISHED: - if (ci->elements & CIS_HAVE_FINISHED) { + if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { SSL_DBG(("%d: SSL[%d]: dup server-finished message", SSL_GETPID(), ss->fd)); goto bad_peer; } - if (gs->recordLen - 1 != SSL2_SESSIONID_BYTES) { + if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) { SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d", - SSL_GETPID(), ss->fd, gs->recordLen)); + SSL_GETPID(), ss->fd, ss->gs.recordLen)); goto bad_peer; } ssl2_ClientRegSessionID(ss, data+1); SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d", - SSL_GETPID(), ss->fd, ci->requiredElements ^ ci->elements)); - ci->elements |= CIS_HAVE_FINISHED; + SSL_GETPID(), ss->fd, + ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); + ss->sec.ci.elements |= CIS_HAVE_FINISHED; break; case SSL_MT_REQUEST_CERTIFICATE: - len = gs->recordLen - 2; + len = ss->gs.recordLen - 2; if ((len != SSL_MIN_CHALLENGE_BYTES) || (len > SSL_MAX_CHALLENGE_BYTES)) { /* Bad challenge */ @@ -2651,9 +2562,9 @@ ssl2_HandleMessage(sslSocket *ss) } /* save auth request info */ - ci->authType = data[1]; - ci->serverChallengeLen = len; - PORT_Memcpy(ci->serverChallenge, data + 2, len); + ss->sec.ci.authType = data[1]; + ss->sec.ci.serverChallengeLen = len; + PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len); rv = ssl2_HandleRequestCertificate(ss); if (rv == SECWouldBlock) { @@ -2675,7 +2586,7 @@ ssl2_HandleMessage(sslSocket *ss) PORT_SetError(SSL_ERROR_BAD_SERVER); goto loser; } - if (gs->recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) { + if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) { SET_ERROR_CODE goto loser; } @@ -2696,7 +2607,7 @@ ssl2_HandleMessage(sslSocket *ss) SET_ERROR_CODE goto loser; } - ci->elements |= CIS_HAVE_CERTIFICATE; + ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE; break; case SSL_MT_ERROR: @@ -2733,13 +2644,13 @@ ssl2_HandleMessage(sslSocket *ss) SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x", SSL_GETPID(), ss->fd, data[0], - ci->requiredElements, ci->elements)); + ss->sec.ci.requiredElements, ss->sec.ci.elements)); rv = ssl2_TryToFinish(ss); if (rv != SECSuccess) goto loser; - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ssl_ReleaseRecvBufLock(ss); if (ss->handshake == 0) { @@ -2751,7 +2662,7 @@ ssl2_HandleMessage(sslSocket *ss) return ssl2_TriggerNextMessage(ss); bad_peer: - PORT_SetError(sec->isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER); + PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER); /* FALL THROUGH */ loser: @@ -2767,37 +2678,32 @@ ssl2_HandleMessage(sslSocket *ss) static SECStatus ssl2_HandleVerifyMessage(sslSocket *ss) { - sslConnectInfo * ci; - sslGather * gs; PRUint8 * data; SECStatus rv; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); ssl_GetRecvBufLock(ss); - PORT_Assert((ss->sec != 0) && (ss->gather != 0)); - ci = &ss->sec->ci; - gs = ss->gather; - data = gs->buf.buf + gs->recordOffset; - DUMP_MSG(29, (ss, data, gs->recordLen)); - if ((gs->recordLen != 1 + SSL_CHALLENGE_BYTES) || + data = ss->gs.buf.buf + ss->gs.recordOffset; + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); + if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) || (data[0] != SSL_MT_SERVER_VERIFY) || - PORT_Memcmp(data+1, ci->clientChallenge, SSL_CHALLENGE_BYTES)) { + PORT_Memcmp(data+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES)) { /* Bad server */ PORT_SetError(SSL_ERROR_BAD_SERVER); goto loser; } - ci->elements |= CIS_HAVE_VERIFY; + ss->sec.ci.elements |= CIS_HAVE_VERIFY; SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x", - SSL_GETPID(), ss->fd, ci->requiredElements, - ci->elements)); + SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, + ss->sec.ci.elements)); rv = ssl2_TryToFinish(ss); if (rv) goto loser; - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ssl_ReleaseRecvBufLock(ss); if (ss->handshake == 0) { @@ -2820,9 +2726,6 @@ ssl2_HandleVerifyMessage(sslSocket *ss) SECStatus ssl2_HandleServerHelloMessage(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; - sslGather * gs; sslSessionID * sid; PRUint8 * cert; PRUint8 * cs; @@ -2830,7 +2733,6 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) SECStatus rv; int needed, sidHit, certLen, csLen, cidLen, certType, err; - PORT_Assert((ss->sec != 0) && (ss->gather != 0)); PORT_Assert( ssl_Have1stHandshakeLock(ss) ); if (!ss->enableSSL2) { @@ -2840,19 +2742,16 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) ssl_GetRecvBufLock(ss); - sec = ss->sec; - ci = &sec->ci; - gs = ss->gather; - PORT_Assert(ci->sid != 0); - sid = ci->sid; + PORT_Assert(ss->sec.ci.sid != 0); + sid = ss->sec.ci.sid; - data = gs->buf.buf + gs->recordOffset; - DUMP_MSG(29, (ss, data, gs->recordLen)); + data = ss->gs.buf.buf + ss->gs.recordOffset; + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); /* Make sure first message has some data and is the server hello message */ - if ((gs->recordLen < SSL_HL_SERVER_HELLO_HBYTES) + if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES) || (data[0] != SSL_MT_SERVER_HELLO)) { - if ((data[0] == SSL_MT_ERROR) && (gs->recordLen == 3)) { + if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) { err = (data[1] << 8) | data[2]; if (err == SSL_PE_NO_CYPHERS) { PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); @@ -2890,7 +2789,8 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) } /* Save connection-id for later */ - PORT_Memcpy(ci->connectionID, cs + csLen, sizeof(ci->connectionID)); + PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, + sizeof(ss->sec.ci.connectionID)); /* See if session-id hit */ needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY; @@ -2905,12 +2805,12 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) /* Total winner. */ SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x " "port=0x%04x", - SSL_GETPID(), ss->fd, ci->peer, ci->port)); - sec->peerCert = CERT_DupCertificate(sid->peerCert); - sec->authAlgorithm = sid->authAlgorithm; - sec->authKeyBits = sid->authKeyBits; - sec->keaType = sid->keaType; - sec->keaKeyBits = sid->keaKeyBits; + SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port)); + ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); + ss->sec.authAlgorithm = sid->authAlgorithm; + ss->sec.authKeyBits = sid->authKeyBits; + ss->sec.keaType = sid->keaType; + ss->sec.keaKeyBits = sid->keaKeyBits; rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); if (rv != SECSuccess) { goto loser; @@ -2936,15 +2836,15 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) /* Forget our session-id - server didn't like it */ SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id", SSL_GETPID(), ss->fd)); - (*sec->uncache)(sid); + (*ss->sec.uncache)(sid); ssl_FreeSID(sid); - ci->sid = sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID)); + ss->sec.ci.sid = sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID)); if (!sid) { goto loser; } sid->references = 1; - sid->addr = ci->peer; - sid->port = ci->port; + sid->addr = ss->sec.ci.peer; + sid->port = ss->sec.ci.port; } /* decode the server's certificate */ @@ -2967,8 +2867,8 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) } /* Build up final list of required elements */ - ci->elements = CIS_HAVE_MASTER_KEY; - ci->requiredElements = needed; + ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; + ss->sec.ci.requiredElements = needed; if (!sidHit) { /* verify the server's certificate. if sidHit, don't check signatures */ @@ -3012,7 +2912,7 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) if (rv != SECSuccess) goto loser; - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ssl_ReleaseRecvBufLock(ss); @@ -3021,7 +2921,8 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) } SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x", - SSL_GETPID(), ss->fd, ci->requiredElements, ci->elements)); + SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, + ss->sec.ci.elements)); ss->handshake = ssl_GatherRecord1stHandshake; ss->nextHandshake = ssl2_HandleVerifyMessage; return SECSuccess; @@ -3041,8 +2942,6 @@ ssl2_HandleServerHelloMessage(sslSocket *ss) SECStatus ssl2_BeginClientHandshake(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo *ci; sslSessionID *sid; PRUint8 *msg; PRUint8 *cp; @@ -3053,14 +2952,11 @@ ssl2_BeginClientHandshake(sslSocket *ss) SECStatus rv; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0)); - sec = ss->sec; - sec->isServer = 0; - sec->sendSequence = 0; - sec->rcvSequence = 0; - ssl_ChooseSessionIDProcs(sec); - ci = &sec->ci; + ss->sec.isServer = 0; + ss->sec.sendSequence = 0; + ss->sec.rcvSequence = 0; + ssl_ChooseSessionIDProcs(&ss->sec); if (!ss->cipherSpecs) { rv = ssl2_ConstructCipherSpecs(ss); @@ -3104,14 +3000,15 @@ ssl2_BeginClientHandshake(sslSocket *ss) if (ss->noCache) { sid = NULL; } else { - sid = ssl_LookupSID(&ci->peer, ci->port, ss->peerID, ss->url); + sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, + ss->url); } while (sid) { /* this isn't really a loop */ /* if we're not doing this SID's protocol any more, drop it. */ if (((sid->version < SSL_LIBRARY_VERSION_3_0) && !ss->enableSSL2) || ((sid->version == SSL_LIBRARY_VERSION_3_0) && !ss->enableSSL3) || ((sid->version > SSL_LIBRARY_VERSION_3_0) && !ss->enableTLS)) { - sec->uncache(sid); + ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; break; @@ -3123,7 +3020,7 @@ ssl2_BeginClientHandshake(sslSocket *ss) break; } if (i >= ss->sizeCipherSpecs) { - sec->uncache(sid); + ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; break; @@ -3133,11 +3030,11 @@ ssl2_BeginClientHandshake(sslSocket *ss) PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID, sidLen)); ss->version = sid->version; - PORT_Assert(!sec->localCert); - if (sec->localCert) { - CERT_DestroyCertificate(sec->localCert); + PORT_Assert(!ss->sec.localCert); + if (ss->sec.localCert) { + CERT_DestroyCertificate(ss->sec.localCert); } - sec->localCert = CERT_DupCertificate(sid->localCert); + ss->sec.localCert = CERT_DupCertificate(sid->localCert); break; /* this isn't really a loop */ } if (!sid) { @@ -3148,8 +3045,8 @@ ssl2_BeginClientHandshake(sslSocket *ss) } sid->references = 1; sid->cached = never_cached; - sid->addr = ci->peer; - sid->port = ci->port; + sid->addr = ss->sec.ci.peer; + sid->port = ss->sec.ci.port; if (ss->peerID != NULL) { sid->peerID = PORT_Strdup(ss->peerID); } @@ -3157,15 +3054,14 @@ ssl2_BeginClientHandshake(sslSocket *ss) sid->urlSvrName = PORT_Strdup(ss->url); } } - ci->sid = sid; + ss->sec.ci.sid = sid; PORT_Assert(sid != NULL); if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->v2CompatibleHello) && (ss->enableSSL3 || ss->enableTLS)) { - PORT_Assert(ss->gather != NULL); - ss->gather->state = GS_INIT; + ss->gs.state = GS_INIT; ss->handshake = ssl_GatherRecord1stHandshake; /* ssl3_SendClientHello will override this if it succeeds. */ @@ -3193,7 +3089,7 @@ ssl2_BeginClientHandshake(sslSocket *ss) SSL_CHALLENGE_BYTES; /* Generate challenge bytes for server */ - PK11_GenerateRandom(ci->clientChallenge, SSL_CHALLENGE_BYTES); + PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); ssl_GetXmitBufLock(ss); /***************************************/ @@ -3202,7 +3098,7 @@ ssl2_BeginClientHandshake(sslSocket *ss) goto unlock_loser; /* Construct client-hello message */ - cp = msg = ci->sendBuf.buf; + cp = msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_CLIENT_HELLO; if ( ss->enableTLS ) { ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_1_TLS; @@ -3227,12 +3123,12 @@ ssl2_BeginClientHandshake(sslSocket *ss) PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen); cp += sidLen; } - PORT_Memcpy(cp, ci->clientChallenge, SSL_CHALLENGE_BYTES); + PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); /* Send it to the server */ DUMP_MSG(29, (ss, msg, sendLen)); ss->handshakeBegun = 1; - rv = (*sec->send)(ss, msg, sendLen, 0); + rv = (*ss->sec.send)(ss, msg, sendLen, 0); ssl_ReleaseXmitBufLock(ss); /***************************************/ @@ -3247,7 +3143,7 @@ ssl2_BeginClientHandshake(sslSocket *ss) /* Setup to receive servers hello message */ ssl_GetRecvBufLock(ss); - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ssl_ReleaseRecvBufLock(ss); ss->handshake = ssl_GatherRecord1stHandshake; @@ -3269,9 +3165,7 @@ loser: static SECStatus ssl2_HandleClientSessionKeyMessage(sslSocket *ss) { - sslConnectInfo * ci; PRUint8 * data; - sslGather * gs; unsigned int caLen; unsigned int ckLen; unsigned int ekLen; @@ -3279,16 +3173,13 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) int cipher; SECStatus rv; - PORT_Assert((ss->sec != 0) && (ss->gather != 0)); ssl_GetRecvBufLock(ss); - gs = ss->gather; - ci = &ss->sec->ci; - data = gs->buf.buf + gs->recordOffset; - DUMP_MSG(29, (ss, data, gs->recordLen)); + data = ss->gs.buf.buf + ss->gs.recordOffset; + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); - if ((gs->recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES) + if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES) || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) { goto bad_client; } @@ -3301,10 +3192,10 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keySize=%d ckLen=%d ekLen=%d caLen=%d", SSL_GETPID(), ss->fd, cipher, keySize, ckLen, ekLen, caLen)); - if (gs->recordLen < + if (ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) { SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d", - SSL_GETPID(), ss->fd, gs->recordLen)); + SSL_GETPID(), ss->fd, ss->gs.recordLen)); goto bad_client; } @@ -3314,14 +3205,14 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen); - ss->gather->recordLen = 0; /* we're done with this record. */ + ss->gs.recordLen = 0; /* we're done with this record. */ ssl_ReleaseRecvBufLock(ss); if (rv != SECSuccess) { goto loser; } - ci->elements |= CIS_HAVE_MASTER_KEY; + ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY; ssl2_UseEncryptedSendFunc(ss); /* Send server verify message now that keys are established */ @@ -3337,7 +3228,7 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) } SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d", - SSL_GETPID(), ss->fd, ci->requiredElements ^ ci->elements)); + SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); ss->handshake = ssl_GatherRecord1stHandshake; ss->nextHandshake = ssl2_HandleMessage; @@ -3381,10 +3272,6 @@ ssl2_RestartHandshakeAfterCertReq(sslSocket * ss, response.data = NULL; - PORT_Assert((ss->sec != 0)); - if (ss->sec == NULL) - return SECFailure; - /* generate error if no cert or key */ if ( ( cert == NULL ) || ( key == NULL ) ) { goto no_cert; @@ -3416,7 +3303,7 @@ ssl2_RestartHandshakeAfterCertReq(sslSocket * ss, /* continue handshake */ ssl_GetRecvBufLock(ss); - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ssl_ReleaseRecvBufLock(ss); ss->handshake = ssl_GatherRecord1stHandshake; @@ -3469,11 +3356,11 @@ ssl2_RestartHandshakeAfterServerCert(sslSocket *ss) /* handshake is not yet finished. */ SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x", - SSL_GETPID(), ss->fd, ss->sec->ci.requiredElements, - ss->sec->ci.elements)); + SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, + ss->sec.ci.elements)); ssl_GetRecvBufLock(ss); - ss->gather->recordLen = 0; /* mark it all used up. */ + ss->gs.recordLen = 0; /* mark it all used up. */ ssl_ReleaseRecvBufLock(ss); ss->handshake = ssl_GatherRecord1stHandshake; @@ -3491,9 +3378,6 @@ ssl2_RestartHandshakeAfterServerCert(sslSocket *ss) SECStatus ssl2_HandleClientHelloMessage(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo *ci; - sslGather *gs; sslSessionID *sid; sslServerCerts * sc; CERTCertificate *serverCert; @@ -3520,22 +3404,18 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) PRUint8 csImpl[sizeof implementedCipherSuites]; PORT_Assert( ssl_Have1stHandshakeLock(ss) ); - PORT_Assert((ss->sec != 0) && (ss->gather != 0)); - sec = ss->sec; - ci = &sec->ci; sc = ss->serverCerts + kt_rsa; serverCert = sc->serverCert; ssl_GetRecvBufLock(ss); - gs = ss->gather; - data = gs->buf.buf + gs->recordOffset; - DUMP_MSG(29, (ss, data, gs->recordLen)); + data = ss->gs.buf.buf + ss->gs.recordOffset; + DUMP_MSG(29, (ss, data, ss->gs.recordLen)); /* Make sure first message has some data and is the client hello message */ - if ((gs->recordLen < SSL_HL_CLIENT_HELLO_HBYTES) + if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES) || (data[0] != SSL_MT_CLIENT_HELLO)) { goto bad_client; } @@ -3553,17 +3433,17 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) if ((data[0] == SSL_MT_CLIENT_HELLO) && (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && (ss->enableSSL3 || ss->enableTLS)) { - rv = ssl3_HandleV2ClientHello(ss, data, gs->recordLen); + rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen); if (rv != SECFailure) { /* Success */ ss->handshake = NULL; ss->nextHandshake = ssl_GatherRecord1stHandshake; ss->securityHandshake = NULL; - ss->gather->state = GS_INIT; + ss->gs.state = GS_INIT; /* ssl3_HandleV3ClientHello has set ss->version, ** and has gotten us a brand new sid. */ - ss->sec->ci.sid->version = ss->version; + ss->sec.ci.sid->version = ss->version; } ssl_ReleaseRecvBufLock(ss); return rv; @@ -3594,10 +3474,10 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) challenge = sd + sdLen; PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen)); - if ((unsigned)gs->recordLen != + if ((unsigned)ss->gs.recordLen != SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) { SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d", - SSL_GETPID(), ss->fd, gs->recordLen, + SSL_GETPID(), ss->fd, ss->gs.recordLen, SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen)); goto bad_client; } @@ -3640,35 +3520,36 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) } /* Squirrel away the challenge for later */ - PORT_Memcpy(ci->clientChallenge, challenge, challengeLen); + PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen); /* Examine message and see if session-id is good */ - ci->elements = 0; + ss->sec.ci.elements = 0; if (sdLen > 0 && !ss->noCache) { SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x", - SSL_GETPID(), ss->fd, ci->peer.pr_s6_addr32[0], - ci->peer.pr_s6_addr32[1], ci->peer.pr_s6_addr32[2], - ci->peer.pr_s6_addr32[3])); - sid = (*ssl_sid_lookup)(&ci->peer, sd, sdLen, ss->dbHandle); + SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0], + ss->sec.ci.peer.pr_s6_addr32[1], + ss->sec.ci.peer.pr_s6_addr32[2], + ss->sec.ci.peer.pr_s6_addr32[3])); + sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle); } else { sid = NULL; } if (sid) { /* Got a good session-id. Short cut! */ SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)", - SSL_GETPID(), ss->fd, ci->peer, + SSL_GETPID(), ss->fd, ss->sec.ci.peer, ssl_Time() - sid->creationTime)); PRINT_BUF(1, (ss, "session-id value:", sd, sdLen)); - ci->sid = sid; - ci->elements = CIS_HAVE_MASTER_KEY; + ss->sec.ci.sid = sid; + ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; hit = 1; certLen = 0; csLen = 0; - sec->authAlgorithm = sid->authAlgorithm; - sec->authKeyBits = sid->authKeyBits; - sec->keaType = sid->keaType; - sec->keaKeyBits = sid->keaKeyBits; + ss->sec.authAlgorithm = sid->authAlgorithm; + ss->sec.authKeyBits = sid->authKeyBits; + ss->sec.keaType = sid->keaType; + ss->sec.keaKeyBits = sid->keaKeyBits; rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); if (rv != SECSuccess) { @@ -3689,11 +3570,11 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) goto loser; } sid->references = 1; - sid->addr = ci->peer; - sid->port = ci->port; + sid->addr = ss->sec.ci.peer; + sid->port = ss->sec.ci.port; /* Invent a session-id */ - ci->sid = sid; + ss->sec.ci.sid = sid; PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2); pid = SSL_GETPID(); @@ -3709,26 +3590,26 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) } sid->localCert = CERT_DupCertificate(serverCert); - sec->authAlgorithm = ssl_sign_rsa; - sec->keaType = ssl_kea_rsa; - sec->keaKeyBits = \ - sec->authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits; + ss->sec.authAlgorithm = ssl_sign_rsa; + ss->sec.keaType = ssl_kea_rsa; + ss->sec.keaKeyBits = \ + ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits; } /* server sids don't remember the local cert, so whether we found ** a sid or not, just "remember" we used the rsa server cert. */ - if (sec->localCert) { - CERT_DestroyCertificate(sec->localCert); + if (ss->sec.localCert) { + CERT_DestroyCertificate(ss->sec.localCert); } - sec->localCert = CERT_DupCertificate(serverCert); + ss->sec.localCert = CERT_DupCertificate(serverCert); /* Build up final list of required elements */ - ci->requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED; + ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED; if (ss->requestCertificate) { - ci->requiredElements |= CIS_HAVE_CERTIFICATE; + ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE; } - ci->sentElements = 0; + ss->sec.ci.sentElements = 0; /* Send hello message back to client */ sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen @@ -3743,7 +3624,7 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)", SSL_GETPID(), ss->fd, sendLen)); - msg = ci->sendBuf.buf; + msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_SERVER_HELLO; msg[1] = hit; msg[2] = SSL_CT_X509_CERTIFICATE; @@ -3761,19 +3642,19 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) if (csLen) { PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen); } - PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, ci->connectionID, - SSL_CONNECTIONID_BYTES); + PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, + ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES); DUMP_MSG(29, (ss, msg, sendLen)); ss->handshakeBegun = 1; - sent = (*sec->send)(ss, msg, sendLen, 0); + sent = (*ss->sec.send)(ss, msg, sendLen, 0); if (sent < 0) { goto loser; } ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0; - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ss->handshake = ssl_GatherRecord1stHandshake; if (hit) { /* Old SID Session key is good. Go encrypted */ @@ -3810,18 +3691,13 @@ ssl2_HandleClientHelloMessage(sslSocket *ss) SECStatus ssl2_BeginServerHandshake(sslSocket *ss) { - sslSecurityInfo *sec; - sslConnectInfo * ci; SECStatus rv; sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa; - PORT_Assert((ss->sec != 0)); - sec = ss->sec; - ci = &sec->ci; - sec->isServer = 1; - ssl_ChooseSessionIDProcs(sec); - sec->sendSequence = 0; - sec->rcvSequence = 0; + ss->sec.isServer = 1; + ssl_ChooseSessionIDProcs(&ss->sec); + ss->sec.sendSequence = 0; + ss->sec.rcvSequence = 0; /* don't turn on SSL2 if we don't have an RSA key and cert */ if (!rsaAuth->serverKey || !rsaAuth->serverCert) { @@ -3846,9 +3722,10 @@ ssl2_BeginServerHandshake(sslSocket *ss) ** immediately. This way the random number generator is always ** rolling around, every time we get a connection. */ - PK11_GenerateRandom(ci->connectionID, sizeof(ci->connectionID)); + PK11_GenerateRandom(ss->sec.ci.connectionID, + sizeof(ss->sec.ci.connectionID)); - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ss->handshake = ssl_GatherRecord1stHandshake; ss->nextHandshake = ssl2_HandleClientHelloMessage; return SECSuccess; diff --git a/security/nss/lib/ssl/sslgathr.c b/security/nss/lib/ssl/sslgathr.c index 1d316db84..9f06a25e3 100644 --- a/security/nss/lib/ssl/sslgathr.c +++ b/security/nss/lib/ssl/sslgathr.c @@ -47,7 +47,7 @@ static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss); ** first gathers the header (2 or 3 bytes long depending on the value of ** the most significant bit in the first byte) then gathers up the data ** for the record into gs->buf. This code handles non-blocking I/O -** and is to be called multiple times until sec->recordLen != 0. +** and is to be called multiple times until ss->sec.recordLen != 0. ** This function decrypts the gathered record in place, in gs_buf. * * Caller must hold RecvBufLock. @@ -83,7 +83,6 @@ static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss); int ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) { - sslSecurityInfo *sec = ss->sec; unsigned char * bp; unsigned char * pBuf; int nb, err, rv; @@ -104,7 +103,7 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) gs->readOffset = 0; } if (gs->encrypted) { - PORT_Assert(sec != 0); + PORT_Assert(ss->sec.hash != 0); } pBuf = gs->buf.buf; @@ -221,7 +220,7 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) if (gs->encrypted) { gs->state = GS_MAC; gs->recordLen = gs->count - gs->recordPadding - - sec->hash->length; + - ss->sec.hash->length; } else { gs->state = GS_DATA; gs->recordLen = gs->count; @@ -250,11 +249,11 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) * If this is a block cipher, this will detect records * that are not a multiple of the blocksize in length. */ - if (gs->count & (sec->blockSize - 1)) { + if (gs->count & (ss->sec.blockSize - 1)) { /* This is an error. Sender is misbehaving */ SSL_DBG(("%d: SSL[%d]: sender, count=%d blockSize=%d", SSL_GETPID(), ss->fd, gs->count, - sec->blockSize)); + ss->sec.blockSize)); PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING); rv = SECFailure; goto spec_locked_done; @@ -269,7 +268,7 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) /* Decrypt the portion of data that we just recieved. ** Decrypt it in place. */ - rv = (*sec->dec)(sec->readcx, pBuf, &nout, gs->offset, + rv = (*ss->sec.dec)(ss->sec.readcx, pBuf, &nout, gs->offset, pBuf, gs->offset); if (rv != SECSuccess) { goto spec_locked_done; @@ -280,9 +279,9 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) ** ** Prepare MAC by resetting it and feeding it the shared secret */ - macLen = sec->hash->length; + macLen = ss->sec.hash->length; if (gs->offset >= macLen) { - uint32 sequenceNumber = sec->rcvSequence++; + uint32 sequenceNumber = ss->sec.rcvSequence++; unsigned char seq[4]; seq[0] = (unsigned char) (sequenceNumber >> 24); @@ -290,23 +289,23 @@ ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags) seq[2] = (unsigned char) (sequenceNumber >> 8); seq[3] = (unsigned char) (sequenceNumber); - (*sec->hash->begin)(sec->hashcx); - (*sec->hash->update)(sec->hashcx, sec->rcvSecret.data, - sec->rcvSecret.len); - (*sec->hash->update)(sec->hashcx, pBuf + macLen, - gs->offset - macLen); - (*sec->hash->update)(sec->hashcx, seq, 4); - (*sec->hash->end)(sec->hashcx, mac, &macLen, macLen); + (*ss->sec.hash->begin)(ss->sec.hashcx); + (*ss->sec.hash->update)(ss->sec.hashcx, ss->sec.rcvSecret.data, + ss->sec.rcvSecret.len); + (*ss->sec.hash->update)(ss->sec.hashcx, pBuf + macLen, + gs->offset - macLen); + (*ss->sec.hash->update)(ss->sec.hashcx, seq, 4); + (*ss->sec.hash->end)(ss->sec.hashcx, mac, &macLen, macLen); } - PORT_Assert(macLen == sec->hash->length); + PORT_Assert(macLen == ss->sec.hash->length); ssl_ReleaseSpecReadLock(ss); /******************************/ if (PORT_Memcmp(mac, pBuf, macLen) != 0) { /* MAC's didn't match... */ SSL_DBG(("%d: SSL[%d]: mac check failed, seq=%d", - SSL_GETPID(), ss->fd, sec->rcvSequence)); + SSL_GETPID(), ss->fd, ss->sec.rcvSequence)); PRINT_BUF(1, (ss, "computed mac:", mac, macLen)); PRINT_BUF(1, (ss, "received mac:", pBuf, macLen)); PORT_SetError(SSL_ERROR_BAD_MAC_READ); @@ -358,7 +357,7 @@ spec_locked_done: gs->recordPadding = 0; gs->state = GS_INIT; - ++sec->rcvSequence; + ++ss->sec.rcvSequence; PRINT_BUF(50, (ss, "recv clear record:", pBuf + gs->recordOffset, gs->recordLen)); @@ -374,7 +373,7 @@ spec_locked_done: ** first gathers the header (2 or 3 bytes long depending on the value of ** the most significant bit in the first byte) then gathers up the data ** for the record into the readBuf. This code handles non-blocking I/O -** and is to be called multiple times until sec->recordLen != 0. +** and is to be called multiple times until ss->sec.recordLen != 0. * * Returns +1 when it has gathered a complete SSLV2 record. * Returns 0 if it hits EOF. @@ -388,7 +387,7 @@ spec_locked_done: int ssl2_GatherRecord(sslSocket *ss, int flags) { - return ssl2_GatherData(ss, ss->gather, flags); + return ssl2_GatherData(ss, &ss->gs, flags); } /* @@ -420,16 +419,16 @@ ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs, unsigned int count) } /* Caller should hold RecvBufLock. */ -sslGather * -ssl_NewGather(void) +SECStatus +ssl_InitGather(sslGather *gs) { - sslGather *gs; + SECStatus status; - gs = (sslGather*) PORT_ZAlloc(sizeof(sslGather)); - if (gs) { - gs->state = GS_INIT; - } - return gs; + gs->state = GS_INIT; + gs->writeOffset = 0; + gs->readOffset = 0; + status = sslBuffer_Grow(&gs->buf, 4096); + return status; } /* Caller must hold RecvBufLock. */ @@ -439,7 +438,6 @@ ssl_DestroyGather(sslGather *gs) if (gs) { /* the PORT_*Free functions check for NULL pointers. */ PORT_ZFree(gs->buf.buf, gs->buf.space); PORT_Free(gs->inbuf.buf); - PORT_Free(gs); } } @@ -447,16 +445,15 @@ ssl_DestroyGather(sslGather *gs) static SECStatus ssl2_HandleV3HandshakeRecord(sslSocket *ss) { - sslGather * gs = ss->gather; SECStatus rv; - SSL3ProtocolVersion version = (gs->hdr[1] << 8) | gs->hdr[2]; + SSL3ProtocolVersion version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2]; PORT_Assert( ssl_HaveRecvBufLock(ss) ); PORT_Assert( ssl_Have1stHandshakeLock(ss) ); /* We've read in 3 bytes, there are 2 more to go in an ssl3 header. */ - gs->remainder = 2; - gs->count = 0; + ss->gs.remainder = 2; + ss->gs.count = 0; /* Clearing these handshake pointers ensures that * ssl_Do1stHandshake won't call ssl2_HandleMessage when we return. @@ -473,7 +470,7 @@ ssl2_HandleV3HandshakeRecord(sslSocket *ss) return rv; } - ss->sec->send = ssl3_SendApplicationData; + ss->sec.send = ssl3_SendApplicationData; return SECSuccess; } diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index a6d063959..a1d09e814 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -285,130 +285,6 @@ typedef struct sslServerCertsStr { unsigned int serverKeyBits; } sslServerCerts; -/* -** SSL Socket struct -** -** Protection: XXX -*/ -struct sslSocketStr { - PRFileDesc * fd; - - /* Pointer to operations vector for this socket */ - const sslSocketOps * ops; - - /* State flags */ - unsigned int useSocks : 1; - unsigned int useSecurity : 1; - unsigned int requestCertificate : 1; - unsigned int requireCertificate : 2; - unsigned int handshakeAsClient : 1; - unsigned int handshakeAsServer : 1; - unsigned int enableSSL2 : 1; - - unsigned int enableSSL3 : 1; - unsigned int enableTLS : 1; - unsigned int clientAuthRequested: 1; - unsigned int noCache : 1; - unsigned int fdx : 1; /* simultaneous R/W threads */ - unsigned int v2CompatibleHello : 1; /* Send v3+ client hello in v2 format */ - unsigned int detectRollBack : 1; /* Detect rollback to SSL v3 */ - unsigned int firstHsDone : 1; /* first handshake is complete. */ - - unsigned int recvdCloseNotify : 1; /* received SSL EOF. */ - unsigned int lastWriteBlocked : 1; - unsigned int TCPconnected : 1; - unsigned int handshakeBegun : 1; - unsigned int delayDisabled : 1; /* Nagle delay disabled */ - - /* version of the protocol to use */ - SSL3ProtocolVersion version; - SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */ - - /* Non-zero if security is enabled */ - sslSecurityInfo *sec; - - /* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */ - const char *url; /* ssl 2 & 3 */ - - /* Gather object used for gathering data */ - sslGather * gather; /*recvBufLock*/ - - sslHandshakeFunc handshake; /*firstHandshakeLock*/ - sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/ - sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/ - - sslBuffer saveBuf; /*xmitBufLock*/ - sslBuffer pendingBuf; /*xmitBufLock*/ - - /* the following variable is only used with socks or other proxies. */ - char * peerID; /* String uniquely identifies target server. */ - - ssl3State * ssl3; - unsigned char * cipherSpecs; - unsigned int sizeCipherSpecs; -const unsigned char * preferredCipher; - - /* Configuration state for server sockets */ - /* server cert and key for each KEA type */ - sslServerCerts serverCerts[kt_kea_size]; - - ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */ - - /* Callbacks */ - SSLAuthCertificate authCertificate; - void *authCertificateArg; - SSLGetClientAuthData getClientAuthData; - void *getClientAuthDataArg; - SSLBadCertHandler handleBadCert; - void *badCertArg; - SSLHandshakeCallback handshakeCallback; - void *handshakeCallbackData; - void *pkcs11PinArg; - - PRIntervalTime rTimeout; /* timeout for NSPR I/O */ - PRIntervalTime wTimeout; /* timeout for NSPR I/O */ - PRIntervalTime cTimeout; /* timeout for NSPR I/O */ - - PZLock * recvLock; /* lock against multiple reader threads. */ - PZLock * sendLock; /* lock against multiple sender threads. */ - - PZMonitor * recvBufLock; /* locks low level recv buffers. */ - PZMonitor * xmitBufLock; /* locks low level xmit buffers. */ - - /* Only one thread may operate on the socket until the initial handshake - ** is complete. This Monitor ensures that. Since SSL2 handshake is - ** only done once, this is also effectively the SSL2 handshake lock. - */ - PZMonitor * firstHandshakeLock; - - /* This monitor protects the ssl3 handshake state machine data. - ** Only one thread (reader or writer) may be in the ssl3 handshake state - ** machine at any time. */ - PZMonitor * ssl3HandshakeLock; - - /* reader/writer lock, protects the secret data needed to encrypt and MAC - ** outgoing records, and to decrypt and MAC check incoming ciphertext - ** records. */ - NSSRWLock * specLock; - - /* handle to perm cert db (and implicitly to the temp cert db) used - ** with this socket. - */ - CERTCertDBHandle * dbHandle; - - PRThread * writerThread; /* thread holds SSL_LOCK_WRITER lock */ - - PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */ - - PRUint16 allowedByPolicy; /* copy of global policy bits. */ - PRUint16 maybeAllowedByPolicy; /* copy of global policy bits. */ - PRUint16 chosenPreference; /* SSL2 cipher preferences. */ - - sslHandshakingType handshaking; - - ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED]; - -}; #define SSL_LOCK_RANK_SPEC 255 #define SSL_LOCK_RANK_GLOBAL NSS_RWLOCK_RANK_NONE @@ -510,124 +386,6 @@ typedef SECStatus (*SSLCipher)(void * context, typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit); -/* - * SSL2 buffers used in SSL3. - * writeBuf in the SecurityInfo maintained by sslsecur.c is used - * to hold the data just about to be passed to the kernel - * sendBuf in the ConnectInfo maintained by sslcon.c is used - * to hold handshake messages as they are accumulated - */ - -/* -** This is "ci", as in "ss->sec->ci". -** -** Protection: All the variables in here are protected by -** firstHandshakeLock AND (in ssl3) ssl3HandshakeLock -*/ -struct sslConnectInfoStr { - /* outgoing handshakes appended to this. */ - sslBuffer sendBuf; /*xmitBufLock*/ /* ssl 2 & 3 */ - - PRIPv6Addr peer; /* ssl 2 & 3 */ - unsigned short port; /* ssl 2 & 3 */ - - sslSessionID *sid; /* ssl 2 & 3 */ - - /* see CIS_HAVE defines below for the bit values in *elements. */ - char elements; /* ssl2 only */ - char requiredElements; /* ssl2 only */ - char sentElements; /* ssl2 only */ - - char sentFinished; /* ssl2 only */ - - /* Length of server challenge. Used by client when saving challenge */ - int serverChallengeLen; /* ssl2 only */ - /* type of authentication requested by server */ - unsigned char authType; /* ssl2 only */ - - /* Challenge sent by client to server in client-hello message */ - /* SSL3 gets a copy of this. See ssl3_StartHandshakeHash(). */ - unsigned char clientChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl 2 & 3 */ - - /* Connection-id sent by server to client in server-hello message */ - unsigned char connectionID[SSL_CONNECTIONID_BYTES]; /* ssl2 only */ - - /* Challenge sent by server to client in request-certificate message */ - unsigned char serverChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl2 only */ - - /* Information kept to handle a request-certificate message */ - unsigned char readKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */ - unsigned char writeKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */ - unsigned keySize; /* ssl2 only */ -}; - -/* bit values for ci->elements, ci->requiredElements, sentElements. */ -#define CIS_HAVE_MASTER_KEY 0x01 -#define CIS_HAVE_CERTIFICATE 0x02 -#define CIS_HAVE_FINISHED 0x04 -#define CIS_HAVE_VERIFY 0x08 - -/* Note: The entire content of this struct and whatever it points to gets - * blown away by SSL_ResetHandshake(). This is "sec" as in "ss->sec". - * - * Unless otherwise specified below, the contents of this struct are - * protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. - */ -struct sslSecurityInfoStr { - sslSendFunc send; /*xmitBufLock*/ /* ssl 2 & 3 */ - int isServer; /* Spec Lock?*/ /* ssl 2 & 3 */ - sslBuffer writeBuf; /*xmitBufLock*/ /* ssl 2 & 3 */ - - int cipherType; /* ssl 2 & 3 */ - int keyBits; /* ssl 2 & 3 */ - int secretKeyBits; /* ssl 2 & 3 */ - CERTCertificate *localCert; /* ssl 2 & 3 */ - CERTCertificate *peerCert; /* ssl 2 & 3 */ - SECKEYPublicKey *peerKey; /* ssl3 only */ - - SSLSignType authAlgorithm; - PRUint32 authKeyBits; - SSLKEAType keaType; - PRUint32 keaKeyBits; - - /* - ** Procs used for SID cache (nonce) management. - ** Different implementations exist for clients/servers - ** The lookup proc is only used for servers. Baloney! - */ - sslSessionIDCacheFunc cache; /* ssl 2 & 3 */ - sslSessionIDUncacheFunc uncache; /* ssl 2 & 3 */ - - /* - ** everything below here is for ssl2 only. - ** This stuff is equivalent to SSL3's "spec", and is protected by the - ** same "Spec Lock" as used for SSL3's specs. - */ - uint32 sendSequence; /*xmitBufLock*/ /* ssl2 only */ - uint32 rcvSequence; /*recvBufLock*/ /* ssl2 only */ - - /* Hash information; used for one-way-hash functions (MD2, MD5, etc.) */ - const SECHashObject *hash; /* Spec Lock */ /* ssl2 only */ - void *hashcx; /* Spec Lock */ /* ssl2 only */ - - SECItem sendSecret; /* Spec Lock */ /* ssl2 only */ - SECItem rcvSecret; /* Spec Lock */ /* ssl2 only */ - - /* Session cypher contexts; one for each direction */ - void *readcx; /* Spec Lock */ /* ssl2 only */ - void *writecx; /* Spec Lock */ /* ssl2 only */ - SSLCipher enc; /* Spec Lock */ /* ssl2 only */ - SSLCipher dec; /* Spec Lock */ /* ssl2 only */ - void (*destroy)(void *, PRBool); /* Spec Lock */ /* ssl2 only */ - - /* Blocking information for the session cypher */ - int blockShift; /* Spec Lock */ /* ssl2 only */ - int blockSize; /* Spec Lock */ /* ssl2 only */ - - /* These are used during a connection handshake */ - sslConnectInfo ci; /* ssl 2 & 3 */ - -}; /* ** ssl3State and CipherSpec structs @@ -963,6 +721,261 @@ typedef struct SSLWrappedSymWrappingKeyStr { PRUint16 wrapIVLen; } SSLWrappedSymWrappingKey; + + + + + + + + + +/* + * SSL2 buffers used in SSL3. + * writeBuf in the SecurityInfo maintained by sslsecur.c is used + * to hold the data just about to be passed to the kernel + * sendBuf in the ConnectInfo maintained by sslcon.c is used + * to hold handshake messages as they are accumulated + */ + +/* +** This is "ci", as in "ss->sec->ci". +** +** Protection: All the variables in here are protected by +** firstHandshakeLock AND (in ssl3) ssl3HandshakeLock +*/ +struct sslConnectInfoStr { + /* outgoing handshakes appended to this. */ + sslBuffer sendBuf; /*xmitBufLock*/ /* ssl 2 & 3 */ + + PRIPv6Addr peer; /* ssl 2 & 3 */ + unsigned short port; /* ssl 2 & 3 */ + + sslSessionID *sid; /* ssl 2 & 3 */ + + /* see CIS_HAVE defines below for the bit values in *elements. */ + char elements; /* ssl2 only */ + char requiredElements; /* ssl2 only */ + char sentElements; /* ssl2 only */ + + char sentFinished; /* ssl2 only */ + + /* Length of server challenge. Used by client when saving challenge */ + int serverChallengeLen; /* ssl2 only */ + /* type of authentication requested by server */ + unsigned char authType; /* ssl2 only */ + + /* Challenge sent by client to server in client-hello message */ + /* SSL3 gets a copy of this. See ssl3_StartHandshakeHash(). */ + unsigned char clientChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl 2 & 3 */ + + /* Connection-id sent by server to client in server-hello message */ + unsigned char connectionID[SSL_CONNECTIONID_BYTES]; /* ssl2 only */ + + /* Challenge sent by server to client in request-certificate message */ + unsigned char serverChallenge[SSL_MAX_CHALLENGE_BYTES]; /* ssl2 only */ + + /* Information kept to handle a request-certificate message */ + unsigned char readKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */ + unsigned char writeKey[SSL_MAX_MASTER_KEY_BYTES]; /* ssl2 only */ + unsigned keySize; /* ssl2 only */ +}; + +/* bit values for ci->elements, ci->requiredElements, sentElements. */ +#define CIS_HAVE_MASTER_KEY 0x01 +#define CIS_HAVE_CERTIFICATE 0x02 +#define CIS_HAVE_FINISHED 0x04 +#define CIS_HAVE_VERIFY 0x08 + +/* Note: The entire content of this struct and whatever it points to gets + * blown away by SSL_ResetHandshake(). This is "sec" as in "ss->sec". + * + * Unless otherwise specified below, the contents of this struct are + * protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. + */ +struct sslSecurityInfoStr { + sslSendFunc send; /*xmitBufLock*/ /* ssl 2 & 3 */ + int isServer; /* Spec Lock?*/ /* ssl 2 & 3 */ + sslBuffer writeBuf; /*xmitBufLock*/ /* ssl 2 & 3 */ + + int cipherType; /* ssl 2 & 3 */ + int keyBits; /* ssl 2 & 3 */ + int secretKeyBits; /* ssl 2 & 3 */ + CERTCertificate *localCert; /* ssl 2 & 3 */ + CERTCertificate *peerCert; /* ssl 2 & 3 */ + SECKEYPublicKey *peerKey; /* ssl3 only */ + + SSLSignType authAlgorithm; + PRUint32 authKeyBits; + SSLKEAType keaType; + PRUint32 keaKeyBits; + + /* + ** Procs used for SID cache (nonce) management. + ** Different implementations exist for clients/servers + ** The lookup proc is only used for servers. Baloney! + */ + sslSessionIDCacheFunc cache; /* ssl 2 & 3 */ + sslSessionIDUncacheFunc uncache; /* ssl 2 & 3 */ + + /* + ** everything below here is for ssl2 only. + ** This stuff is equivalent to SSL3's "spec", and is protected by the + ** same "Spec Lock" as used for SSL3's specs. + */ + uint32 sendSequence; /*xmitBufLock*/ /* ssl2 only */ + uint32 rcvSequence; /*recvBufLock*/ /* ssl2 only */ + + /* Hash information; used for one-way-hash functions (MD2, MD5, etc.) */ + const SECHashObject *hash; /* Spec Lock */ /* ssl2 only */ + void *hashcx; /* Spec Lock */ /* ssl2 only */ + + SECItem sendSecret; /* Spec Lock */ /* ssl2 only */ + SECItem rcvSecret; /* Spec Lock */ /* ssl2 only */ + + /* Session cypher contexts; one for each direction */ + void *readcx; /* Spec Lock */ /* ssl2 only */ + void *writecx; /* Spec Lock */ /* ssl2 only */ + SSLCipher enc; /* Spec Lock */ /* ssl2 only */ + SSLCipher dec; /* Spec Lock */ /* ssl2 only */ + void (*destroy)(void *, PRBool); /* Spec Lock */ /* ssl2 only */ + + /* Blocking information for the session cypher */ + int blockShift; /* Spec Lock */ /* ssl2 only */ + int blockSize; /* Spec Lock */ /* ssl2 only */ + + /* These are used during a connection handshake */ + sslConnectInfo ci; /* ssl 2 & 3 */ + +}; + + +/* +** SSL Socket struct +** +** Protection: XXX +*/ +struct sslSocketStr { + PRFileDesc * fd; + + /* Pointer to operations vector for this socket */ + const sslSocketOps * ops; + + /* State flags */ + unsigned int useSocks : 1; + unsigned int useSecurity : 1; + unsigned int requestCertificate : 1; + unsigned int requireCertificate : 2; + unsigned int handshakeAsClient : 1; + unsigned int handshakeAsServer : 1; + unsigned int enableSSL2 : 1; + + unsigned int enableSSL3 : 1; + unsigned int enableTLS : 1; + unsigned int clientAuthRequested: 1; + unsigned int noCache : 1; + unsigned int fdx : 1; /* simultaneous R/W threads */ + unsigned int v2CompatibleHello : 1; /* Send v3+ client hello in v2 format */ + unsigned int detectRollBack : 1; /* Detect rollback to SSL v3 */ + unsigned int firstHsDone : 1; /* first handshake is complete. */ + + unsigned int recvdCloseNotify : 1; /* received SSL EOF. */ + unsigned int lastWriteBlocked : 1; + unsigned int TCPconnected : 1; + unsigned int handshakeBegun : 1; + unsigned int delayDisabled : 1; /* Nagle delay disabled */ + + /* version of the protocol to use */ + SSL3ProtocolVersion version; + SSL3ProtocolVersion clientHelloVersion; /* version sent in client hello. */ + + sslSecurityInfo sec; /* not a pointer any more */ + + /* protected by firstHandshakeLock AND (in ssl3) ssl3HandshakeLock. */ + const char *url; /* ssl 2 & 3 */ + + /* Gather object used for gathering data */ + sslGather gs; /*recvBufLock*/ + + sslHandshakeFunc handshake; /*firstHandshakeLock*/ + sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/ + sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/ + + sslBuffer saveBuf; /*xmitBufLock*/ + sslBuffer pendingBuf; /*xmitBufLock*/ + + /* the following variable is only used with socks or other proxies. */ + char * peerID; /* String uniquely identifies target server. */ + + ssl3State * ssl3; + unsigned char * cipherSpecs; + unsigned int sizeCipherSpecs; +const unsigned char * preferredCipher; + + /* Configuration state for server sockets */ + /* server cert and key for each KEA type */ + sslServerCerts serverCerts[kt_kea_size]; + + ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */ + + /* Callbacks */ + SSLAuthCertificate authCertificate; + void *authCertificateArg; + SSLGetClientAuthData getClientAuthData; + void *getClientAuthDataArg; + SSLBadCertHandler handleBadCert; + void *badCertArg; + SSLHandshakeCallback handshakeCallback; + void *handshakeCallbackData; + void *pkcs11PinArg; + + PRIntervalTime rTimeout; /* timeout for NSPR I/O */ + PRIntervalTime wTimeout; /* timeout for NSPR I/O */ + PRIntervalTime cTimeout; /* timeout for NSPR I/O */ + + PZLock * recvLock; /* lock against multiple reader threads. */ + PZLock * sendLock; /* lock against multiple sender threads. */ + + PZMonitor * recvBufLock; /* locks low level recv buffers. */ + PZMonitor * xmitBufLock; /* locks low level xmit buffers. */ + + /* Only one thread may operate on the socket until the initial handshake + ** is complete. This Monitor ensures that. Since SSL2 handshake is + ** only done once, this is also effectively the SSL2 handshake lock. + */ + PZMonitor * firstHandshakeLock; + + /* This monitor protects the ssl3 handshake state machine data. + ** Only one thread (reader or writer) may be in the ssl3 handshake state + ** machine at any time. */ + PZMonitor * ssl3HandshakeLock; + + /* reader/writer lock, protects the secret data needed to encrypt and MAC + ** outgoing records, and to decrypt and MAC check incoming ciphertext + ** records. */ + NSSRWLock * specLock; + + /* handle to perm cert db (and implicitly to the temp cert db) used + ** with this socket. + */ + CERTCertDBHandle * dbHandle; + + PRThread * writerThread; /* thread holds SSL_LOCK_WRITER lock */ + + PRUint16 shutdownHow; /* See ssl_SHUTDOWN defines below. */ + + PRUint16 allowedByPolicy; /* copy of global policy bits. */ + PRUint16 maybeAllowedByPolicy; /* copy of global policy bits. */ + PRUint16 chosenPreference; /* SSL2 cipher preferences. */ + + sslHandshakingType handshaking; + + ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED]; + +}; + + + /* All the global data items declared here should be protected using the ** ssl_global_data_lock, which is a reader/writer lock. */ @@ -1035,6 +1048,7 @@ extern PRFileDesc *ssl_FindTop(sslSocket *ss); /* Gather funcs. */ extern sslGather * ssl_NewGather(void); +extern SECStatus ssl_InitGather(sslGather *gs); extern void ssl_DestroyGather(sslGather *gs); extern int ssl2_GatherData(sslSocket *ss, sslGather *gs, int flags); extern int ssl2_GatherRecord(sslSocket *ss, int flags); @@ -1047,6 +1061,7 @@ extern int ssl2_StartGatherBytes(sslSocket *ss, sslGather *gs, extern SECStatus ssl_CreateSecurityInfo(sslSocket *ss); extern SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os); +extern void ssl_ResetSecurityInfo(sslSecurityInfo *sec); extern void ssl_DestroySecurityInfo(sslSecurityInfo *sec); extern sslSocket * ssl_DupSocket(sslSocket *old); diff --git a/security/nss/lib/ssl/sslinfo.c b/security/nss/lib/ssl/sslinfo.c index 5d344ae37..94314433c 100644 --- a/security/nss/lib/ssl/sslinfo.c +++ b/security/nss/lib/ssl/sslinfo.c @@ -40,7 +40,6 @@ SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) { sslSocket * ss; - sslSecurityInfo *sec; SSLChannelInfo inf; sslSessionID * sid; @@ -58,14 +57,13 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) memset(&inf, 0, sizeof inf); inf.length = PR_MIN(sizeof inf, len); - sec = ss->sec; - if (ss->useSecurity && ss->firstHsDone && sec) { - sid = sec->ci.sid; + if (ss->useSecurity && ss->firstHsDone) { + sid = ss->sec.ci.sid; inf.protocolVersion = ss->version; - inf.authKeyBits = ss->sec->authKeyBits; - inf.keaKeyBits = ss->sec->keaKeyBits; + inf.authKeyBits = ss->sec.authKeyBits; + inf.keaKeyBits = ss->sec.keaKeyBits; if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */ - inf.cipherSuite = ss->sec->cipherType | 0xff00; + inf.cipherSuite = ss->sec.cipherType | 0xff00; } else if (ss->ssl3) { /* SSL3 and TLS */ /* XXX These should come from crSpec */ diff --git a/security/nss/lib/ssl/sslnonce.c b/security/nss/lib/ssl/sslnonce.c index 2aed0f287..36dd7f073 100644 --- a/security/nss/lib/ssl/sslnonce.c +++ b/security/nss/lib/ssl/sslnonce.c @@ -209,7 +209,7 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID, /* ** Add an sid to the cache or return a previously cached entry to the cache. -** Although this is static, it is called via ss->sec->cache(). +** Although this is static, it is called via ss->sec.cache(). */ static void CacheSID(sslSessionID *sid) @@ -309,7 +309,7 @@ UncacheSID(sslSessionID *zap) /* If sid "zap" is in the cache, * removes sid from cache, and decrements reference count. * Although this function is static, it is called externally via - * ss->sec->uncache(). + * ss->sec.uncache(). */ static void LockAndUncacheSID(sslSessionID *zap) diff --git a/security/nss/lib/ssl/sslreveal.c b/security/nss/lib/ssl/sslreveal.c index dcba7c3ef..44ae47810 100644 --- a/security/nss/lib/ssl/sslreveal.c +++ b/security/nss/lib/ssl/sslreveal.c @@ -54,8 +54,8 @@ SSL_RevealCert(PRFileDesc * fd) /* CERT_DupCertificate increases reference count and returns pointer to * the same cert */ - if (sslsocket && sslsocket->sec) - cert = CERT_DupCertificate(sslsocket->sec->peerCert); + if (sslsocket && sslsocket->sec.peerCert) + cert = CERT_DupCertificate(sslsocket->sec.peerCert); return cert; } diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c index 9fabf5e6b..0949d5679 100644 --- a/security/nss/lib/ssl/sslsecur.c +++ b/security/nss/lib/ssl/sslsecur.c @@ -117,8 +117,6 @@ ssl_Do1stHandshake(sslSocket *ss) int rv = SECSuccess; int loopCount = 0; - PORT_Assert(ss->gather != 0); - do { PORT_Assert( ssl_Have1stHandshakeLock(ss) ); PORT_Assert( !ssl_HaveRecvBufLock(ss) ); @@ -136,23 +134,22 @@ ssl_Do1stHandshake(sslSocket *ss) } if (ss->handshake == 0) { ssl_GetRecvBufLock(ss); - ss->gather->recordLen = 0; + ss->gs.recordLen = 0; ssl_ReleaseRecvBufLock(ss); SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd)); /* call handshake callback for ssl v2 */ /* for v3 this is done in ssl3_HandleFinished() */ - if ((ss->sec != NULL) && /* used SSL */ - (ss->handshakeCallback != NULL) && /* has callback */ + if ((ss->handshakeCallback != NULL) && /* has callback */ (!ss->firstHsDone) && /* only first time */ (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */ ss->firstHsDone = PR_TRUE; (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); } ss->firstHsDone = PR_TRUE; - ss->gather->writeOffset = 0; - ss->gather->readOffset = 0; + ss->gs.writeOffset = 0; + ss->gs.readOffset = 0; break; } rv = (*ss->handshake)(ss); @@ -201,7 +198,7 @@ SECStatus SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) { sslSocket *ss; - SECStatus rv; + SECStatus status; PRNetAddr addr; ss = ssl_FindSocket(s); @@ -233,21 +230,16 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) ss->securityHandshake = 0; ssl_GetRecvBufLock(ss); - ss->gather->state = GS_INIT; - ss->gather->writeOffset = 0; - ss->gather->readOffset = 0; + status = ssl_InitGather(&ss->gs); ssl_ReleaseRecvBufLock(ss); /* - ** Blow away old security state and get a fresh setup. This way if - ** ssl was used to connect to the first point in communication, ssl - ** can be used for the next layer. + ** Blow away old security state and get a fresh setup. */ - if (ss->sec) { - ssl_DestroySecurityInfo(ss->sec); - ss->sec = 0; - } - rv = ssl_CreateSecurityInfo(ss); + ssl_GetXmitBufLock(ss); + ssl_ResetSecurityInfo(&ss->sec); + status = ssl_CreateSecurityInfo(ss); + ssl_ReleaseXmitBufLock(ss); ssl_ReleaseSSL3HandshakeLock(ss); ssl_Release1stHandshakeLock(ss); @@ -258,7 +250,7 @@ SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) SSL_UNLOCK_WRITER(ss); SSL_UNLOCK_READER(ss); - return rv; + return status; } /* For SSLv2, does nothing but return an error. @@ -328,7 +320,6 @@ SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb, ssl_Get1stHandshakeLock(ss); ssl_GetSSL3HandshakeLock(ss); - PORT_Assert(ss->sec); ss->handshakeCallback = cb; ss->handshakeCallbackData = client_data; @@ -500,16 +491,13 @@ ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf, sslSendFunc send) static int DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) { - sslGather * gs; int rv; int amount; int available; ssl_GetRecvBufLock(ss); - PORT_Assert((ss->sec != 0) && (ss->gather != 0)); - gs = ss->gather; - available = gs->writeOffset - gs->readOffset; + available = ss->gs.writeOffset - ss->gs.readOffset; if (available == 0) { /* Get some more data */ if (ss->version >= SSL_LIBRARY_VERSION_3_0) { @@ -541,7 +529,7 @@ DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) } /* See if any clear data is now available */ - available = gs->writeOffset - gs->readOffset; + available = ss->gs.writeOffset - ss->gs.readOffset; if (available == 0) { /* ** No partial data is available. Force error code to @@ -560,9 +548,9 @@ DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) /* Dole out clear data to reader */ amount = PR_MIN(len, available); - PORT_Memcpy(out, gs->buf.buf + gs->readOffset, amount); + PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount); if (!(flags & MSG_PEEK)) { - gs->readOffset += amount; + ss->gs.readOffset += amount; } rv = amount; @@ -620,7 +608,6 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, { SECStatus rv; sslSocket *ss; - sslSecurityInfo *sec; sslServerCerts *sc; ss = ssl_FindSocket(fd); @@ -628,16 +615,6 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, return SECFailure; } - if ((rv = ssl_CreateSecurityInfo(ss)) != SECSuccess) { - return rv; - } - - sec = ss->sec; - if (sec == NULL) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - /* Both key and cert must have a value or be NULL */ /* Passing a value of NULL will turn off key exchange algorithms that were * previously turned on */ @@ -735,120 +712,72 @@ loser: SECStatus ssl_CreateSecurityInfo(sslSocket *ss) { - sslSecurityInfo * sec = (sslSecurityInfo *)0; - sslGather * gs = (sslGather * )0; - int rv; - - unsigned char padbuf[MAX_BLOCK_CYPHER_SIZE]; - - if (ss->sec) { - return SECSuccess; - } - - /* Force the global RNG to generate some random data that we never use */ - PK11_GenerateRandom(padbuf, sizeof padbuf); - - ss->sec = sec = (sslSecurityInfo*) PORT_ZAlloc(sizeof(sslSecurityInfo)); - if (!sec) { - goto loser; - } + SECStatus status; /* initialize sslv2 socket to send data in the clear. */ ssl2_UseClearSendFunc(ss); - sec->blockSize = 1; - sec->blockShift = 0; + ss->sec.blockSize = 1; + ss->sec.blockShift = 0; - ssl_GetRecvBufLock(ss); - if ((gs = ss->gather) == 0) { - ss->gather = gs = ssl_NewGather(); - if (!gs) { - goto loser; - } - } - - rv = sslBuffer_Grow(&gs->buf, 4096); - if (rv) { - goto loser; - } - ssl_ReleaseRecvBufLock(ss); - - ssl_GetXmitBufLock(ss); - rv = sslBuffer_Grow(&sec->writeBuf, 4096); - if (rv) { - goto loser; - } - ssl_ReleaseXmitBufLock(ss); + ssl_GetXmitBufLock(ss); + status = sslBuffer_Grow(&ss->sec.writeBuf, 4096); + ssl_ReleaseXmitBufLock(ss); - SSL_TRC(5, ("%d: SSL[%d]: security info created", SSL_GETPID(), ss->fd)); - return SECSuccess; - - loser: - if (sec) { - PORT_Free(sec); - ss->sec = sec = (sslSecurityInfo *)0; - } - if (gs) { - ssl_DestroyGather(gs); - ss->gather = gs = (sslGather *)0; - } - return SECFailure; + return status; } -/* XXX We should handle errors better in this function. */ -/* This function assumes that none of the pointers in ss need to be -** freed. -*/ SECStatus ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) { - sslSecurityInfo *sec, *osec; int rv; - rv = ssl_CreateSecurityInfo(ss); - if (rv < 0) { - goto loser; - } - sec = ss->sec; - osec = os->sec; - - sec->send = osec->send; - sec->isServer = osec->isServer; - sec->keyBits = osec->keyBits; - sec->secretKeyBits = osec->secretKeyBits; + ss->sec.send = os->sec.send; + ss->sec.isServer = os->sec.isServer; + ss->sec.keyBits = os->sec.keyBits; + ss->sec.secretKeyBits = os->sec.secretKeyBits; - sec->peerCert = CERT_DupCertificate(osec->peerCert); + ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert); + if (os->sec.peerCert && !ss->sec.peerCert) + goto loser; - sec->cache = osec->cache; - sec->uncache = osec->uncache; + ss->sec.cache = os->sec.cache; + ss->sec.uncache = os->sec.uncache; /* we don't dup the connection info. */ - sec->sendSequence = osec->sendSequence; - sec->rcvSequence = osec->rcvSequence; + ss->sec.sendSequence = os->sec.sendSequence; + ss->sec.rcvSequence = os->sec.rcvSequence; - if (osec->hash && osec->hashcx) { - sec->hash = osec->hash; - sec->hashcx = osec->hash->clone(osec->hashcx); + if (os->sec.hash && os->sec.hashcx) { + ss->sec.hash = os->sec.hash; + ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx); + if (os->sec.hashcx && !ss->sec.hashcx) + goto loser; } else { - sec->hash = NULL; - sec->hashcx = NULL; + ss->sec.hash = NULL; + ss->sec.hashcx = NULL; } - SECITEM_CopyItem(0, &sec->sendSecret, &osec->sendSecret); - SECITEM_CopyItem(0, &sec->rcvSecret, &osec->rcvSecret); + SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret); + if (os->sec.sendSecret.data && !ss->sec.sendSecret.data) + goto loser; + SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret); + if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data) + goto loser; - PORT_Assert(osec->readcx == 0); - sec->readcx = osec->readcx; /* XXX wrong if readcx != 0 */ - PORT_Assert(osec->writecx == 0); - sec->writecx = osec->writecx; /* XXX wrong if writecx != 0 */ - sec->destroy = 0; /* XXX wrong if either cx != 0*/ + /* XXX following code is wrong if either cx != 0 */ + PORT_Assert(os->sec.readcx == 0); + PORT_Assert(os->sec.writecx == 0); + ss->sec.readcx = os->sec.readcx; + ss->sec.writecx = os->sec.writecx; + ss->sec.destroy = 0; - sec->enc = osec->enc; - sec->dec = osec->dec; + ss->sec.enc = os->sec.enc; + ss->sec.dec = os->sec.dec; - sec->blockShift = osec->blockShift; - sec->blockSize = osec->blockSize; + ss->sec.blockShift = os->sec.blockShift; + ss->sec.blockSize = os->sec.blockSize; return SECSuccess; @@ -856,57 +785,69 @@ loser: return SECFailure; } +/* Reset sec back to its initial state. +** Caller holds any relevant locks. +*/ +void +ssl_ResetSecurityInfo(sslSecurityInfo *sec) +{ + /* Destroy MAC */ + if (sec->hash && sec->hashcx) { + (*sec->hash->destroy)(sec->hashcx, PR_TRUE); + sec->hashcx = NULL; + sec->hash = NULL; + } + SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); + SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); + + /* Destroy ciphers */ + if (sec->destroy) { + (*sec->destroy)(sec->readcx, PR_TRUE); + (*sec->destroy)(sec->writecx, PR_TRUE); + sec->readcx = NULL; + sec->writecx = NULL; + } else { + PORT_Assert(sec->readcx == 0); + PORT_Assert(sec->writecx == 0); + } + sec->readcx = 0; + sec->writecx = 0; + + if (sec->localCert) { + CERT_DestroyCertificate(sec->localCert); + sec->localCert = NULL; + } + if (sec->peerCert) { + CERT_DestroyCertificate(sec->peerCert); + sec->peerCert = NULL; + } + if (sec->peerKey) { + SECKEY_DestroyPublicKey(sec->peerKey); + sec->peerKey = NULL; + } + + /* cleanup the ci */ + if (sec->ci.sid != NULL) { + ssl_FreeSID(sec->ci.sid); + } + PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); + memset(&sec->ci, 0, sizeof sec->ci); +} + /* ** Called from SSL_ResetHandshake (above), and ** from ssl_FreeSocket in sslsock.c +** Caller should hold relevant locks (e.g. XmitBufLock) */ void ssl_DestroySecurityInfo(sslSecurityInfo *sec) { - if (sec != 0) { - /* Destroy MAC */ - if (sec->hash && sec->hashcx) { - (*sec->hash->destroy)(sec->hashcx, PR_TRUE); - sec->hashcx = 0; - } - SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); - SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); - - /* Destroy ciphers */ - if (sec->destroy) { - (*sec->destroy)(sec->readcx, PR_TRUE); - (*sec->destroy)(sec->writecx, PR_TRUE); - } else { - PORT_Assert(sec->readcx == 0); - PORT_Assert(sec->writecx == 0); - } - sec->readcx = 0; - sec->writecx = 0; + ssl_ResetSecurityInfo(sec); - /* etc. */ - PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); - sec->writeBuf.buf = 0; + PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); + sec->writeBuf.buf = 0; - if (sec->localCert) { - CERT_DestroyCertificate(sec->localCert); - sec->localCert = NULL; - } - if (sec->peerCert) { - CERT_DestroyCertificate(sec->peerCert); - sec->peerCert = NULL; - } - if (sec->peerKey) { - SECKEY_DestroyPublicKey(sec->peerKey); - sec->peerKey = NULL; - } - - PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); - if (sec->ci.sid != NULL) { - ssl_FreeSID(sec->ci.sid); - } - - PORT_ZFree(sec, sizeof *sec); - } + memset(sec, 0, sizeof *sec); } /************************************************************************/ @@ -917,8 +858,6 @@ ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa) PRFileDesc *osfd = ss->fd->lower; int rv; - PORT_Assert(ss->sec != 0); - if ( ss->handshakeAsServer ) { ss->securityHandshake = ssl2_BeginServerHandshake; ss->handshaking = sslHandshakingAsServer; @@ -1007,8 +946,7 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) sslSecurityInfo *sec; int rv = 0; - PORT_Assert(ss->sec != 0); - sec = ss->sec; + sec = &ss->sec; if (ss->shutdownHow & ssl_SHUTDOWN_RCV) { PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); @@ -1063,12 +1001,8 @@ ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len) int ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) { - sslSecurityInfo *sec; int rv = 0; - PORT_Assert(ss->sec != 0); - sec = ss->sec; - if (ss->shutdownHow & ssl_SHUTDOWN_SEND) { PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); return PR_FAILURE; @@ -1124,7 +1058,7 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) * ssl3_SendApplicationData */ ssl_GetXmitBufLock(ss); - rv = (*sec->send)(ss, buf, len, flags); + rv = (*ss->sec.send)(ss, buf, len, flags); ssl_ReleaseXmitBufLock(ss); ss->writerThread = NULL; return rv; @@ -1149,9 +1083,6 @@ SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg) return SECFailure; } - if ((rv = ssl_CreateSecurityInfo(ss)) != 0) { - return rv; - } ss->handleBadCert = f; ss->badCertArg = arg; @@ -1208,13 +1139,9 @@ SSL_DataPending(PRFileDesc *fd) ssl_Get1stHandshakeLock(ss); ssl_GetSSL3HandshakeLock(ss); - /* Create ss->sec if it doesn't already exist. */ - rv = ssl_CreateSecurityInfo(ss); - if (rv == SECSuccess) { - ssl_GetRecvBufLock(ss); - rv = ss->gather->writeOffset - ss->gather->readOffset; - ssl_ReleaseRecvBufLock(ss); - } + ssl_GetRecvBufLock(ss); + rv = ss->gs.writeOffset - ss->gs.readOffset; + ssl_ReleaseRecvBufLock(ss); ssl_ReleaseSSL3HandshakeLock(ss); ssl_Release1stHandshakeLock(ss); @@ -1233,8 +1160,8 @@ SSL_InvalidateSession(PRFileDesc *fd) ssl_Get1stHandshakeLock(ss); ssl_GetSSL3HandshakeLock(ss); - if (ss->sec && ss->sec->ci.sid) { - ss->sec->uncache(ss->sec->ci.sid); + if (ss->sec.ci.sid) { + ss->sec.uncache(ss->sec.ci.sid); rv = SECSuccess; } @@ -1249,24 +1176,25 @@ SSL_GetSessionID(PRFileDesc *fd) { sslSocket * ss; SECItem * item = NULL; - sslSessionID * sid; ss = ssl_FindSocket(fd); if (ss) { ssl_Get1stHandshakeLock(ss); ssl_GetSSL3HandshakeLock(ss); - if (ss->useSecurity && ss->firstHsDone && ss->sec && ss->sec->ci.sid) { - sid = ss->sec->ci.sid; + if (ss->useSecurity && ss->firstHsDone && ss->sec.ci.sid) { item = (SECItem *)PORT_Alloc(sizeof(SECItem)); - if (sid->version < SSL_LIBRARY_VERSION_3_0) { - item->len = SSL2_SESSIONID_BYTES; - item->data = (unsigned char*)PORT_Alloc(item->len); - PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); - } else { - item->len = sid->u.ssl3.sessionIDLength; - item->data = (unsigned char*)PORT_Alloc(item->len); - PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); + if (item) { + sslSessionID * sid = ss->sec.ci.sid; + if (sid->version < SSL_LIBRARY_VERSION_3_0) { + item->len = SSL2_SESSIONID_BYTES; + item->data = (unsigned char*)PORT_Alloc(item->len); + PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); + } else { + item->len = sid->u.ssl3.sessionIDLength; + item->data = (unsigned char*)PORT_Alloc(item->len); + PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); + } } } diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 7486dadf2..610f5db61 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -305,19 +305,94 @@ loser: return NULL; } -/* - * free an sslSocket struct, and all the stuff that hangs off of it - */ -void -ssl_FreeSocket(sslSocket *ss) +static void +ssl_DestroyLocks(sslSocket *ss) +{ + + /* Destroy locks. */ + if (ss->firstHandshakeLock) { + PZ_DestroyMonitor(ss->firstHandshakeLock); + ss->firstHandshakeLock = NULL; + } + if (ss->ssl3HandshakeLock) { + PZ_DestroyMonitor(ss->ssl3HandshakeLock); + ss->ssl3HandshakeLock = NULL; + } + if (ss->specLock) { + NSSRWLock_Destroy(ss->specLock); + ss->specLock = NULL; + } + + if (ss->recvLock) { + PZ_DestroyLock(ss->recvLock); + ss->recvLock = NULL; + } + if (ss->sendLock) { + PZ_DestroyLock(ss->sendLock); + ss->sendLock = NULL; + } + if (ss->xmitBufLock) { + PZ_DestroyMonitor(ss->xmitBufLock); + ss->xmitBufLock = NULL; + } + if (ss->recvBufLock) { + PZ_DestroyMonitor(ss->recvBufLock); + ss->recvBufLock = NULL; + } +} + +/* Caller holds any relevant locks */ +static void +ssl_DestroySocketContents(sslSocket *ss) { /* "i" should be of type SSLKEAType, but CC on IRIX complains during * the for loop. */ int i; - sslSocket *fs; + /* Free up socket */ + ssl_DestroySecurityInfo(&ss->sec); + + ssl3_DestroySSL3Info(ss->ssl3); + + PORT_Free(ss->saveBuf.buf); + PORT_Free(ss->pendingBuf.buf); + ssl_DestroyGather(&ss->gs); + + if (ss->peerID != NULL) + PORT_Free(ss->peerID); + if (ss->url != NULL) + PORT_Free((void *)ss->url); /* CONST */ + if (ss->cipherSpecs) { + PORT_Free(ss->cipherSpecs); + ss->cipherSpecs = NULL; + ss->sizeCipherSpecs = 0; + } + + /* Clean up server configuration */ + for (i=kt_null; i < kt_kea_size; i++) { + sslServerCerts * sc = ss->serverCerts + i; + if (sc->serverCert != NULL) + CERT_DestroyCertificate(sc->serverCert); + if (sc->serverCertChain != NULL) + CERT_DestroyCertificateList(sc->serverCertChain); + if (sc->serverKey != NULL) + SECKEY_DestroyPrivateKey(sc->serverKey); + } + if (ss->stepDownKeyPair) { + ssl3_FreeKeyPair(ss->stepDownKeyPair); + ss->stepDownKeyPair = NULL; + } +} + +/* + * free an sslSocket struct, and all the stuff that hangs off of it + */ +void +ssl_FreeSocket(sslSocket *ss) +{ #ifdef DEBUG + sslSocket *fs; sslSocket lSock; #endif @@ -337,37 +412,10 @@ ssl_FreeSocket(sslSocket *ss) *fs = *ss; /* Copy the old socket structure, */ PORT_Memset(ss, 0x1f, sizeof *ss); /* then blast the old struct ASAP. */ #else - fs = ss; +#define fs ss #endif - /* Free up socket */ - ssl_DestroySecurityInfo(fs->sec); - ssl3_DestroySSL3Info(fs->ssl3); - PORT_Free(fs->saveBuf.buf); - PORT_Free(fs->pendingBuf.buf); - if (fs->gather) { - ssl_DestroyGather(fs->gather); - } - if (fs->peerID != NULL) - PORT_Free(fs->peerID); - if (fs->url != NULL) - PORT_Free((void *)fs->url); /* CONST */ - - /* Clean up server configuration */ - for (i=kt_null; i < kt_kea_size; i++) { - sslServerCerts * sc = fs->serverCerts + i; - if (sc->serverCert != NULL) - CERT_DestroyCertificate(sc->serverCert); - if (sc->serverCertChain != NULL) - CERT_DestroyCertificateList(sc->serverCertChain); - if (sc->serverKey != NULL) - SECKEY_DestroyPrivateKey(sc->serverKey); - } - if (fs->stepDownKeyPair) { - ssl3_FreeKeyPair(fs->stepDownKeyPair); - fs->stepDownKeyPair = NULL; - } - + ssl_DestroySocketContents(fs); /* Release all the locks acquired above. */ SSL_UNLOCK_READER(fs); @@ -378,45 +426,12 @@ ssl_FreeSocket(sslSocket *ss) ssl_ReleaseXmitBufLock(fs); ssl_ReleaseSpecWriteLock(fs); - /* Destroy locks. */ - if (fs->firstHandshakeLock) { - PZ_DestroyMonitor(fs->firstHandshakeLock); - fs->firstHandshakeLock = NULL; - } - if (fs->ssl3HandshakeLock) { - PZ_DestroyMonitor(fs->ssl3HandshakeLock); - fs->ssl3HandshakeLock = NULL; - } - if (fs->specLock) { - NSSRWLock_Destroy(fs->specLock); - fs->specLock = NULL; - } - - if (fs->recvLock) { - PZ_DestroyLock(fs->recvLock); - fs->recvLock = NULL; - } - if (fs->sendLock) { - PZ_DestroyLock(fs->sendLock); - fs->sendLock = NULL; - } - if (fs->xmitBufLock) { - PZ_DestroyMonitor(fs->xmitBufLock); - fs->xmitBufLock = NULL; - } - if (fs->recvBufLock) { - PZ_DestroyMonitor(fs->recvBufLock); - fs->recvBufLock = NULL; - } - if (fs->cipherSpecs) { - PORT_Free(fs->cipherSpecs); - fs->cipherSpecs = NULL; - fs->sizeCipherSpecs = 0; - } + ssl_DestroyLocks(fs); PORT_Free(ss); /* free the caller's copy, not ours. */ return; } +#undef fs /************************************************************************/ SECStatus @@ -446,13 +461,6 @@ PrepareSocket(sslSocket *ss) { SECStatus rv = SECSuccess; - if (ss->useSecurity) { - rv = ssl_CreateSecurityInfo(ss); - if (rv != SECSuccess) { - return rv; - } - } - ssl_ChooseOps(ss); return rv; } @@ -1272,15 +1280,11 @@ ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr) SECStatus ssl_GetPeerInfo(sslSocket *ss) { - sslConnectInfo * ci; - PRNetAddr sin; - int rv; PRFileDesc * osfd; - - PORT_Assert((ss->sec != 0)); + int rv; + PRNetAddr sin; osfd = ss->fd->lower; - ci = &ss->sec->ci; PORT_Memset(&sin, 0, sizeof(sin)); rv = osfd->methods->getpeername(osfd, &sin); @@ -1288,14 +1292,15 @@ ssl_GetPeerInfo(sslSocket *ss) return SECFailure; } ss->TCPconnected = 1; - /* we have to mask off the high byte because AIX is lame */ - if ((sin.inet.family & 0xff) == PR_AF_INET) { - PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ci->peer); - ci->port = sin.inet.port; + if (sin.inet.family == PR_AF_INET) { + PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ss->sec.ci.peer); + ss->sec.ci.port = sin.inet.port; + } else if (sin.ipv6.family == PR_AF_INET6) { + ss->sec.ci.peer = sin.ipv6.ip; + ss->sec.ci.port = sin.ipv6.port; } else { - PORT_Assert(sin.ipv6.family == PR_AF_INET6); - ci->peer = sin.ipv6.ip; - ci->port = sin.ipv6.port; + PORT_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR); + return SECFailure; } return SECSuccess; } @@ -1796,14 +1801,11 @@ ssl_NewSocket(void) { sslSocket *ss; #ifdef DEBUG +#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS) static int firsttime = 1; -#endif -#ifdef DEBUG -#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS) if (firsttime) { firsttime = 0; - { char *ev = getenv("SSLDEBUG"); if (ev && ev[0]) { @@ -1831,6 +1833,7 @@ ssl_NewSocket(void) * complains during the for loop. */ int i; + SECStatus status; ss->useSecurity = ssl_defaults.useSecurity; ss->useSocks = PR_FALSE; @@ -1877,14 +1880,31 @@ ssl_NewSocket(void) ssl3_InitSocketPolicy(ss); ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL); + if (!ss->firstHandshakeLock) goto loser; ss->ssl3HandshakeLock = PZ_NewMonitor(nssILockSSL); + if (!ss->ssl3HandshakeLock) goto loser; ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL); + if (!ss->specLock) goto loser; ss->recvBufLock = PZ_NewMonitor(nssILockSSL); + if (!ss->recvBufLock) goto loser; ss->xmitBufLock = PZ_NewMonitor(nssILockSSL); + if (!ss->xmitBufLock) goto loser; ss->writerThread = NULL; if (ssl_lock_readers) { ss->recvLock = PZ_NewLock(nssILockSSL); + if (!ss->recvLock) goto loser; ss->sendLock = PZ_NewLock(nssILockSSL); + if (!ss->sendLock) goto loser; + } + status = ssl_CreateSecurityInfo(ss); + if (status != SECSuccess) goto loser; + status = ssl_InitGather(&ss->gs); + if (status != SECSuccess) { +loser: + ssl_DestroySocketContents(ss); + ssl_DestroyLocks(ss); + PORT_Free(ss); + ss = NULL; } } return ss; diff --git a/security/nss/makefile.win b/security/nss/makefile.win index fcde6c6f7..332059a3f 100644 --- a/security/nss/makefile.win +++ b/security/nss/makefile.win @@ -78,6 +78,7 @@ all:: export libs install install:: moz_import install_roots depend:: + $(GMAKE) -C lib $(GMAKE_FLAGS) clean export libs install clobber clobber_all clean:: !if "$(MOZ_BITS)" == "16" |