diff options
author | saul.edwards%sun.com <devnull@localhost> | 2003-12-10 22:18:16 +0000 |
---|---|---|
committer | saul.edwards%sun.com <devnull@localhost> | 2003-12-10 22:18:16 +0000 |
commit | a2c774e24f030c9d522432380cb5782a90e5c3e4 (patch) | |
tree | d2fd3a60e51b4ea797f292893e8309e307b0396a | |
parent | 421562498d32729fe5f6113316b6100e72ff94bc (diff) | |
download | nss-hg-a2c774e24f030c9d522432380cb5782a90e5c3e4.tar.gz |
Bringing 3.3.4.2 up to date with 3.3.8; neuter the cert7 upgrade.
68 files changed, 3426 insertions, 970 deletions
diff --git a/security/nss/Makefile b/security/nss/Makefile index 21a54fbe5..89992328e 100644 --- a/security/nss/Makefile +++ b/security/nss/Makefile @@ -110,10 +110,6 @@ endif nss_RelEng_bld: build_coreconf import all -ifeq ($(OS_ARCH),SunOS) -solarispkg: - @echo Making Solaris packages. - rm -rf pkg/$(OBJDIR) - cp -r pkg/solaris pkg/$(OBJDIR) - $(MAKE) -C pkg/$(OBJDIR) publish -endif +package: + $(MAKE) -C pkg publish + diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk index 4f486e938..920f82120 100644 --- a/security/nss/cmd/platlibs.mk +++ b/security/nss/cmd/platlibs.mk @@ -110,6 +110,10 @@ EXTRA_LIBS += \ $(DIST)/lib/libdbm.$(LIB_SUFFIX) \ $(NULL) +ifeq ($(OS_ARCH), SunOS) +EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib' -R '$$ORIGIN/..' +endif + ifeq ($(OS_ARCH), AIX) EXTRA_SHARED_LIBS += -brtl endif diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c index 895ba5f56..aba39f3b0 100644 --- a/security/nss/cmd/selfserv/selfserv.c +++ b/security/nss/cmd/selfserv/selfserv.c @@ -88,6 +88,10 @@ static int handle_connection( PRFileDesc *, PRFileDesc *, int ); static const char envVarName[] = { SSL_ENV_VAR_NAME }; static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" }; +static PRBool logStats = PR_FALSE; +static int logPeriod = 30; +static PRUint32 loggerOps = 0; + const int ssl2CipherSuites[] = { SSL_EN_RC4_128_WITH_MD5, /* A */ @@ -114,6 +118,17 @@ const int ssl3CipherSuites[] = { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */ SSL_RSA_WITH_RC4_128_SHA, /* n */ + TLS_DHE_DSS_WITH_RC4_128_SHA, /* o */ + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* p */ + SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* q */ + SSL_DHE_RSA_WITH_DES_CBC_SHA, /* r */ + SSL_DHE_DSS_WITH_DES_CBC_SHA, /* s */ + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* t */ + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* u */ + TLS_RSA_WITH_AES_128_CBC_SHA, /* v */ + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* w */ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* x */ + TLS_RSA_WITH_AES_256_CBC_SHA, /* y */ 0 }; @@ -157,7 +172,7 @@ Usage(const char *progName) "Usage: %s -n rsa_nickname -p port [-3DRTmrvx] [-w password] [-t threads]\n" " [-i pid_file] [-c ciphers] [-d dbdir] [-f fortezza_nickname] \n" -" [-M maxProcs] \n" +" [-L [seconds]] [-M maxProcs] \n" "-3 means disable SSL v3\n" "-D means disable Nagle delays in TCP\n" "-T means disable TLS\n" @@ -170,6 +185,7 @@ Usage(const char *progName) " 4 -r's mean request and require, cert on second handshake.\n" "-v means verbose output\n" "-x means use export policy.\n" +"-L seconds means log statistics every 'seconds' seconds (default=30).\n" "-M maxProcs tells how many processes to run in a multi-process server\n" "-t threads -- specify the number of threads to use for connections.\n" "-i pid_file file to write the process id of selfserve\n" @@ -195,6 +211,8 @@ Usage(const char *progName) "l SSL3 RSA EXPORT WITH DES CBC SHA\t(new)\n" "m SSL3 RSA EXPORT WITH RC4 56 SHA\t(new)\n" "n SSL3 RSA WITH RC4 128 SHA\n" +"v TLS_RSA_WITH_AES_128_CBC_SHA\n" +"y TLS_RSA_WITH_AES_256_CBC_SHA\n" ,progName); } @@ -490,6 +508,36 @@ terminateWorkerThreads(void) PR_Free(threads); } +static void +logger(void *arg) +{ + PRFloat64 seconds; + PRFloat64 opsPerSec; + PRIntervalTime period; + PRIntervalTime previousTime; + PRIntervalTime latestTime; + PRUint32 previousOps; + PRUint32 ops; + PRIntervalTime logPeriodTicks = PR_SecondsToInterval(logPeriod); + PRFloat64 secondsPerTick = 1.0 / (PRFloat64)PR_TicksPerSecond(); + + previousOps = loggerOps; + previousTime = PR_IntervalNow(); + + for (;;) { + PR_Sleep(logPeriodTicks); + latestTime = PR_IntervalNow(); + ops = loggerOps; + period = latestTime - previousTime; + seconds = (PRFloat64) period*secondsPerTick; + opsPerSec = (ops - previousOps) / seconds; + printf("%.2f ops/second, %d threads\n", + opsPerSec, threadCount); + fflush(stdout); + previousOps = ops; + previousTime = latestTime; + } +} /************************************************************************** ** End thread management routines. @@ -979,6 +1027,10 @@ do_accepts( VLOG(("selfserv: do_accept: Got connection\n")); + if (logStats) { + loggerOps++; + } + PZ_Lock(qLock); while (PR_CLIST_IS_EMPTY(&freeJobs) && !stopping) { PZ_WaitCondVar(freeListNotEmptyCv, PR_INTERVAL_NO_TIMEOUT); @@ -1288,6 +1340,7 @@ main(int argc, char **argv) PRBool useExportPolicy = PR_FALSE; PLOptState *optstate; PLOptStatus status; + PRThread *loggerThread; tmp = strrchr(argv[0], '/'); @@ -1297,7 +1350,7 @@ main(int argc, char **argv) PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); - optstate = PL_CreateOptState(argc, argv, "2:3DM:RTc:d:p:mn:hi:f:rt:vw:x"); + optstate = PL_CreateOptState(argc, argv, "2:3DL:M:RTc:d:p:mn:hi:f:rt:vw:x"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { ++optionsFound; switch(optstate->option) { @@ -1307,6 +1360,16 @@ main(int argc, char **argv) case 'D': noDelay = PR_TRUE; break; + case 'L': + logStats = PR_TRUE; + if (optstate->value == NULL) { + logPeriod = 30; + } else { + logPeriod = PORT_Atoi(optstate->value); + if (logPeriod <= 0) logPeriod = 30; + } + break; + case 'M': maxProcs = PORT_Atoi(optstate->value); if (maxProcs < 1) maxProcs = 1; @@ -1496,6 +1559,17 @@ main(int argc, char **argv) /* allocate the array of thread slots, and launch the worker threads. */ rv = launch_threads(&jobLoop, 0, 0, requestCert); + if (rv == SECSuccess && logStats) { + loggerThread = PR_CreateThread(PR_USER_THREAD, + logger, NULL, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, 0); + if (loggerThread == NULL) { + fprintf(stderr, "selfserv: Failed to launch logger thread!\n"); + rv = SECFailure; + } + } + if ( rv == SECSuccess) { server_main(listen_sock, requestCert, privKey, cert); } diff --git a/security/nss/cmd/signtool/util.c b/security/nss/cmd/signtool/util.c index 8f8717864..cdc289915 100644 --- a/security/nss/cmd/signtool/util.c +++ b/security/nss/cmd/signtool/util.c @@ -284,10 +284,17 @@ void VerifyCertDir(char *dir, char *keyName) { char fn [FNSIZE]; + PRStatus hasDB; - sprintf (fn, "%s/cert7.db", dir); + sprintf (fn, "%s/cert8.db", dir); + hasDB = PR_Access (fn, PR_ACCESS_EXISTS); - if (PR_Access (fn, PR_ACCESS_EXISTS)) + if (hasDB == PR_FAILURE) { + sprintf (fn, "%s/cert7.db", dir); + hasDB = PR_Access (fn, PR_ACCESS_EXISTS); + } + + if (hasDB == PR_FAILURE) { PR_fprintf(errorFD, "%s: No certificate database in \"%s\"\n", PROGRAM_NAME, dir); diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c index 157fff1e2..78c5d4c8a 100644 --- a/security/nss/cmd/strsclnt/strsclnt.c +++ b/security/nss/cmd/strsclnt/strsclnt.c @@ -99,6 +99,17 @@ int ssl3CipherSuites[] = { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */ SSL_RSA_WITH_RC4_128_SHA, /* n */ + TLS_DHE_DSS_WITH_RC4_128_SHA, /* o */ + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* p */ + SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* q */ + SSL_DHE_RSA_WITH_DES_CBC_SHA, /* r */ + SSL_DHE_DSS_WITH_DES_CBC_SHA, /* s */ + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* t */ + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* u */ + TLS_RSA_WITH_AES_128_CBC_SHA, /* v */ + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* w */ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* x */ + TLS_RSA_WITH_AES_256_CBC_SHA, /* y */ 0 }; diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c index 5817c39ef..a511e03e0 100644 --- a/security/nss/cmd/tstclnt/tstclnt.c +++ b/security/nss/cmd/tstclnt/tstclnt.c @@ -92,6 +92,17 @@ int ssl3CipherSuites[] = { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, /* l */ TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, /* m */ SSL_RSA_WITH_RC4_128_SHA, /* n */ + TLS_DHE_DSS_WITH_RC4_128_SHA, /* o */ + SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* p */ + SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* q */ + SSL_DHE_RSA_WITH_DES_CBC_SHA, /* r */ + SSL_DHE_DSS_WITH_DES_CBC_SHA, /* s */ + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* t */ + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* u */ + TLS_RSA_WITH_AES_128_CBC_SHA, /* v */ + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* w */ + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* x */ + TLS_RSA_WITH_AES_256_CBC_SHA, /* y */ 0 }; @@ -190,6 +201,17 @@ static void Usage(const char *progName) "l SSL3 RSA EXPORT WITH DES CBC SHA\t(new)\n" "m SSL3 RSA EXPORT WITH RC4 56 SHA\t(new)\n" "n SSL3 RSA WITH RC4 128 SHA\n" +"o TLS DHE DSS WITH RC4 128 SHA\n" +"p SSL3 DHE RSA WITH 3DES EDE CBC SHA\n" +"q SSL3 DHE DSS WITH 3DES EDE CBC SHA\n" +"r SSL3 DHE RSA WITH DES CBC SHA\n" +"s SSL3 DHE DSS WITH DES CBC SHA\n" +"t TLS_DHE_DSS_WITH_AES_128_CBC_SHA\n" +"u TLS_DHE_RSA_WITH_AES_128_CBC_SHA\n" +"v TLS_RSA_WITH_AES_128_CBC_SHA\n" +"w TLS_DHE_DSS_WITH_AES_256_CBC_SHA\n" +"x TLS_DHE_RSA_WITH_AES_256_CBC_SHA\n" +"y TLS_RSA_WITH_AES_256_CBC_SHA\n" ); exit(1); } diff --git a/security/nss/lib/certdb/alg1485.c b/security/nss/lib/certdb/alg1485.c index dfa4e2f1c..409b17a69 100644 --- a/security/nss/lib/certdb/alg1485.c +++ b/security/nss/lib/certdb/alg1485.c @@ -438,7 +438,8 @@ CERT_ParseRFC1485AVA(PRArenaPool *arena, char **pbp, char *endptr, } else if (Is7Bit((unsigned char *)valBuf, valLen)) { vt = SEC_ASN1_T61_STRING; } else { - vt = SEC_ASN1_UNIVERSAL_STRING; + /* according to RFC3280, UTF8String is preferred encoding */ + vt = SEC_ASN1_UTF8_STRING; } } a = CERT_CreateAVA(arena, n2k->kind, vt, (char *) valBuf); diff --git a/security/nss/lib/certdb/cdbhdl.h b/security/nss/lib/certdb/cdbhdl.h index c195eb308..6a9f11409 100644 --- a/security/nss/lib/certdb/cdbhdl.h +++ b/security/nss/lib/certdb/cdbhdl.h @@ -54,4 +54,8 @@ struct CERTCertDBHandleStr { PZMonitor *dbMon; }; +DB * +dbsopen(const char *dbname, int flags, int mode, DBTYPE type, + const void *userData); + #endif diff --git a/security/nss/lib/certdb/certdb.h b/security/nss/lib/certdb/certdb.h index 2d75ee8b5..7da572099 100644 --- a/security/nss/lib/certdb/certdb.h +++ b/security/nss/lib/certdb/certdb.h @@ -41,7 +41,8 @@ */ /* version number of certificate database */ -#define CERT_DB_FILE_VERSION 7 +#define CERT_DB_FILE_VERSION 8 +#define CERT_DB_V7_FILE_VERSION 7 #ifdef USE_NS_ROOTS #define CERT_DB_CONTENT_VERSION 28 #else @@ -69,7 +70,8 @@ typedef enum { certDBEntryTypeRevocation = 4, certDBEntryTypeKeyRevocation = 5, certDBEntryTypeSMimeProfile = 6, - certDBEntryTypeContentVersion = 7 + certDBEntryTypeContentVersion = 7, + certDBEntryTypeBlob = 8 } certDBEntryType; typedef struct { diff --git a/security/nss/lib/certdb/dbmshim.c b/security/nss/lib/certdb/dbmshim.c new file mode 100644 index 000000000..b469a80f4 --- /dev/null +++ b/security/nss/lib/certdb/dbmshim.c @@ -0,0 +1,671 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1994-2000 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* + * Berkeley DB 1.85 Shim code to handle blobs. + * + * $Id$ + */ + +#include "prerror.h" +#include "prprf.h" +#include "cert.h" +#include "mcom_db.h" +#include "certdb.h" +#include "secitem.h" +#include "secder.h" + +/* Call to PK11_FreeSlot below */ + +#include "secasn1.h" +#include "secerr.h" +#include "nssb64.h" +#include "blapi.h" +#include "sechash.h" + +#ifdef macintosh +#define PATH_SEPARATOR ":" +#else +#define PATH_SEPARATOR "/" +#endif + +#define NO_RDONLY O_RDONLY +#define NO_RDWR O_RDWR +#define NO_CREATE (O_RDWR | O_CREAT | O_TRUNC) + +/* + * Blob block: + * Byte 0 CERTDB Version -+ -+ + * Byte 1 certDBEntryTypeBlob | BLOB_HEAD_LEN | + * Byte 2 flags (always '0'); | | + * Byte 3 reserved (always '0'); -+ | + * Byte 4 LSB length | <--BLOB_LENGTH_START | BLOB_BUF_LEN + * Byte 5 . | | + * Byte 6 . | BLOB_LENGTH_LEN | + * Byte 7 MSB length | | + * Byte 8 blob_filename -+ -+ <-- BLOB_NAME_START | + * Byte 9 . | BLOB_NAME_LEN | + * . . | | + * Byte 37 . -+ -+ + */ +#define DBS_BLOCK_SIZE (16*1024) /* 16 k */ +#define DBS_MAX_ENTRY_SIZE (DBS_BLOCK_SIZE - (2048)) /* 14 k */ +#define DBS_CACHE_SIZE DBS_BLOCK_SIZE*8 +#define ROUNDDIV(x,y) (x+(y-1))/y +#define BLOB_HEAD_LEN 4 +#define BLOB_LENGTH_START BLOB_HEAD_LEN +#define BLOB_LENGTH_LEN 4 +#define BLOB_NAME_START BLOB_LENGTH_START+BLOB_LENGTH_LEN +#define BLOB_NAME_LEN 1+ROUNDDIV(SHA1_LENGTH,3)*4+1 +#define BLOB_BUF_LEN BLOB_HEAD_LEN+BLOB_LENGTH_LEN+BLOB_NAME_LEN + +/* a Shim data structure. This data structure has a db built into it. */ +typedef struct DBSStr DBS; + +struct DBSStr { + DB db; + char *blobdir; + int mode; + PRBool readOnly; + PRFileMap *dbs_mapfile; + unsigned char *dbs_addr; + PRUint32 dbs_len; + char staticBlobArea[BLOB_BUF_LEN]; +}; + + + +/* + * return true if the Datablock contains a blobtype + */ +static PRBool +dbs_IsBlob(DBT *blobData) +{ + unsigned char *addr = (unsigned char *)blobData->data; + if (blobData->size < BLOB_BUF_LEN) { + return PR_FALSE; + } + return addr && ((certDBEntryType) addr[1] == certDBEntryTypeBlob); +} + +/* + * extract the filename in the blob of the real data set. + * This value is not malloced (does not need to be freed by the caller. + */ +static const char * +dbs_getBlobFileName(DBT *blobData) +{ + char *addr = (char *)blobData->data; + + return &addr[BLOB_NAME_START]; +} + +/* + * extract the size of the actual blob from the blob record + */ +static PRUint32 +dbs_getBlobSize(DBT *blobData) +{ + unsigned char *addr = (unsigned char *)blobData->data; + + return (PRUint32)(addr[BLOB_LENGTH_START+3] << 24) | + (addr[BLOB_LENGTH_START+2] << 16) | + (addr[BLOB_LENGTH_START+1] << 8) | + addr[BLOB_LENGTH_START]; +} + + +/* We are using base64 data for the filename, but base64 data can include a + * '/' which is interpreted as a path separator on many platforms. Replace it + * with an inocuous '-'. We don't need to convert back because we never actual + * decode the filename. + */ + +static void +dbs_replaceSlash(char *cp, int len) +{ + while (len--) { + if (*cp == '/') *cp = '-'; + cp++; + } +} + +/* + * create a blob record from a key, data and return it in blobData. + * NOTE: The data element is static data (keeping with the dbm model). + */ +static void +dbs_mkBlob(DBS *dbsp,const DBT *key, const DBT *data, DBT *blobData) +{ + unsigned char sha1_data[SHA1_LENGTH]; + char *b = dbsp->staticBlobArea; + PRUint32 length = data->size; + SECItem sha1Item; + + b[0] = CERT_DB_FILE_VERSION; /* certdb version number */ + b[1] = (char) certDBEntryTypeBlob; /* type */ + b[2] = 0; /* flags */ + b[3] = 0; /* reserved */ + b[BLOB_LENGTH_START] = length & 0xff; + b[BLOB_LENGTH_START+1] = (length >> 8) & 0xff; + b[BLOB_LENGTH_START+2] = (length >> 16) & 0xff; + b[BLOB_LENGTH_START+3] = (length >> 24) & 0xff; + sha1Item.data = sha1_data; + sha1Item.len = SHA1_LENGTH; + SHA1_HashBuf(sha1_data,key->data,key->size); + b[BLOB_NAME_START]='b'; /* Make sure we start with a alpha */ + NSSBase64_EncodeItem(NULL,&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1,&sha1Item); + b[BLOB_BUF_LEN-1] = 0; + dbs_replaceSlash(&b[BLOB_NAME_START+1],BLOB_NAME_LEN-1); + blobData->data = b; + blobData->size = BLOB_BUF_LEN; + return; +} + + +/* + * construct a path to the actual blob. The string returned must be + * freed by the caller with PR_smprintf_free. + * + * Note: this file does lots of consistancy checks on the DBT. The + * routines that call this depend on these checks, so they don't worry + * about them (success of this routine implies a good blobdata record). + */ +static char * +dbs_getBlobFilePath(char *blobdir,DBT *blobData) +{ + const char *name; + + if (blobdir == NULL) { + PR_SetError(SEC_ERROR_BAD_DATABASE,0); + return NULL; + } + if (!dbs_IsBlob(blobData)) { + PR_SetError(SEC_ERROR_BAD_DATABASE,0); + return NULL; + } + name = dbs_getBlobFileName(blobData); + if (!name || *name == 0) { + PR_SetError(SEC_ERROR_BAD_DATABASE,0); + return NULL; + } + return PR_smprintf("%s" PATH_SEPARATOR "%s", blobdir, name); +} + +/* + * Delete a blob file pointed to by the blob record. + */ +static void +dbs_removeBlob(DBS *dbsp, DBT *blobData) +{ + char *file; + + file = dbs_getBlobFilePath(dbsp->blobdir, blobData); + if (!file) { + return; + } + PR_Delete(file); + PR_smprintf_free(file); +} + +/* + * Directory modes are slightly different, the 'x' bit needs to be on to + * access them. Copy all the read bits to 'x' bits + */ +static int +dbs_DirMode(int mode) +{ + int x_bits = (mode >> 2) & 0111; + return mode | x_bits; +} + +/* + * write a data blob to it's file. blobdData is the blob record that will be + * stored in the database. data is the actual data to go out on disk. + */ +static int +dbs_writeBlob(DBS *dbsp, int mode, DBT *blobData, const DBT *data) +{ + char *file = NULL; + PRFileDesc *filed; + PRStatus status; + int len; + int error = 0; + + file = dbs_getBlobFilePath(dbsp->blobdir, blobData); + if (!file) { + goto loser; + } + if (PR_Access(dbsp->blobdir, PR_ACCESS_EXISTS) != PR_SUCCESS) { + status = PR_MkDir(dbsp->blobdir,dbs_DirMode(mode)); + if (status != PR_SUCCESS) { + goto loser; + } + } + filed = PR_OpenFile(file,PR_CREATE_FILE|PR_TRUNCATE|PR_WRONLY, mode); + if (filed == NULL) { + error = PR_GetError(); + goto loser; + } + len = PR_Write(filed,data->data,data->size); + error = PR_GetError(); + PR_Close(filed); + if (len < (int)data->size) { + goto loser; + } + PR_smprintf_free(file); + return 0; + +loser: + if (file) { + PR_Delete(file); + PR_smprintf_free(file); + } + /* don't let close or delete reset the error */ + PR_SetError(error,0); + return -1; +} + + +/* + * we need to keep a address map in memory between calls to DBM. + * remember what we have mapped can close it when we get another dbm + * call. + * + * NOTE: Not all platforms support mapped files. This code is designed to + * detect this at runtime. If map files aren't supported the OS will indicate + * this by failing the PR_Memmap call. In this case we emulate mapped files + * by just reading in the file into regular memory. We signal this state by + * making dbs_mapfile NULL and dbs_addr non-NULL. + */ + +static void +dbs_freemap(DBS *dbsp) +{ + if (dbsp->dbs_mapfile) { + PR_MemUnmap(dbsp->dbs_addr,dbsp->dbs_len); + PR_CloseFileMap(dbsp->dbs_mapfile); + dbsp->dbs_mapfile = NULL; + dbsp->dbs_addr = NULL; + dbsp->dbs_len = 0; + } else if (dbsp->dbs_addr) { + PORT_Free(dbsp->dbs_addr); + dbsp->dbs_addr = NULL; + dbsp->dbs_len = 0; + } + return; +} + +static void +dbs_setmap(DBS *dbsp, PRFileMap *mapfile, unsigned char *addr, PRUint32 len) +{ + dbsp->dbs_mapfile = mapfile; + dbsp->dbs_addr = addr; + dbsp->dbs_len = len; +} + +/* + * platforms that cannot map the file need to read it into a temp buffer. + */ +static unsigned char * +dbs_EmulateMap(PRFileDesc *filed, int len) +{ + unsigned char *addr; + PRInt32 dataRead; + + addr = PORT_Alloc(len); + if (addr == NULL) { + return NULL; + } + + dataRead = PR_Read(filed,addr,len); + if (dataRead != len) { + PORT_Free(addr); + if (dataRead > 0) { + /* PR_Read didn't set an error, we need to */ + PR_SetError(SEC_ERROR_BAD_DATABASE,0); + } + return NULL; + } + + return addr; +} + + +/* + * pull a database record off the disk + * data points to the blob record on input and the real record (if we could + * read it) on output. if there is an error data is not modified. + */ +static int +dbs_readBlob(DBS *dbsp, DBT *data) +{ + char *file = NULL; + PRFileDesc *filed = NULL; + PRFileMap *mapfile = NULL; + unsigned char *addr = NULL; + int error; + int len = -1; + + file = dbs_getBlobFilePath(dbsp->blobdir, data); + if (!file) { + goto loser; + } + filed = PR_OpenFile(file,PR_RDONLY,0); + PR_smprintf_free(file); file = NULL; + if (filed == NULL) { + goto loser; + } + + len = dbs_getBlobSize(data); + mapfile = PR_CreateFileMap(filed, len, PR_PROT_READONLY); + if (mapfile == NULL) { + /* USE PR_GetError instead of PORT_GetError here + * because we are getting the error from PR_xxx + * function */ + if (PR_GetError() != PR_NOT_IMPLEMENTED_ERROR) { + goto loser; + } + addr = dbs_EmulateMap(filed, len); + } else { + addr = PR_MemMap(mapfile, 0, len); + } + if (addr == NULL) { + goto loser; + } + PR_Close(filed); + dbs_setmap(dbsp,mapfile,addr,len); + + data->data = addr; + data->size = len; + return 0; + +loser: + /* preserve the error code */ + error = PR_GetError(); + if (addr) { + if (mapfile) { + PORT_Assert(len != -1); + PR_MemUnmap(addr,len); + } else { + PORT_Free(addr); + } + } + if (mapfile) { + PR_CloseFileMap(mapfile); + } + if (filed) { + PR_Close(filed); + } + PR_SetError(error,0); + return -1; +} + +/* + * actual DBM shims + */ +static int +dbs_get(const DB *dbs, const DBT *key, DBT *data, unsigned int flags) +{ + int ret; + DBS *dbsp = (DBS *)dbs; + DB *db = (DB *)dbs->internal; + + + dbs_freemap(dbsp); + + ret = (* db->get)(db, key, data, flags); + if ((ret == 0) && dbs_IsBlob(data)) { + ret = dbs_readBlob(dbsp,data); + } + + return(ret); +} + +static int +dbs_put(const DB *dbs, DBT *key, const DBT *data, unsigned int flags) +{ + DBT blob; + int ret = 0; + DBS *dbsp = (DBS *)dbs; + DB *db = (DB *)dbs->internal; + + dbs_freemap(dbsp); + + /* If the db is readonly, just pass the data down to rdb and let it fail */ + if (!dbsp->readOnly) { + DBT oldData; + int ret1; + + /* make sure the current record is deleted if it's a blob */ + ret1 = (*db->get)(db,key,&oldData,0); + if ((ret1 == 0) && flags == R_NOOVERWRITE) { + /* let DBM return the error to maintain consistancy */ + return (* db->put)(db, key, data, flags); + } + if ((ret1 == 0) && dbs_IsBlob(&oldData)) { + dbs_removeBlob(dbsp, &oldData); + } + + if (data->size > DBS_MAX_ENTRY_SIZE) { + dbs_mkBlob(dbsp,key,data,&blob); + ret = dbs_writeBlob(dbsp, dbsp->mode, &blob, data); + data = &blob; + } + } + + if (ret == 0) { + ret = (* db->put)(db, key, data, flags); + } + return(ret); +} + +static int +dbs_sync(const DB *dbs, unsigned int flags) +{ + DB *db = (DB *)dbs->internal; + DBS *dbsp = (DBS *)dbs; + + dbs_freemap(dbsp); + + return (* db->sync)(db, flags); +} + +static int +dbs_del(const DB *dbs, const DBT *key, unsigned int flags) +{ + int ret; + DBS *dbsp = (DBS *)dbs; + DB *db = (DB *)dbs->internal; + + dbs_freemap(dbsp); + + if (!dbsp->readOnly) { + DBT oldData; + ret = (*db->get)(db,key,&oldData,0); + if ((ret == 0) && dbs_IsBlob(&oldData)) { + dbs_removeBlob(dbsp,&oldData); + } + } + + return (* db->del)(db, key, flags); +} + +static int +dbs_seq(const DB *dbs, DBT *key, DBT *data, unsigned int flags) +{ + int ret; + DBS *dbsp = (DBS *)dbs; + DB *db = (DB *)dbs->internal; + + dbs_freemap(dbsp); + + ret = (* db->seq)(db, key, data, flags); + if ((ret == 0) && dbs_IsBlob(data)) { + /* don't return a blob read as an error so traversals keep going */ + (void) dbs_readBlob(dbsp,data); + } + + return(ret); +} + +static int +dbs_close(DB *dbs) +{ + DBS *dbsp = (DBS *)dbs; + DB *db = (DB *)dbs->internal; + int ret; + + dbs_freemap(dbsp); + ret = (* db->close)(db); + PORT_Free(dbsp->blobdir); + PORT_Free(dbsp); + return ret; +} + +static int +dbs_fd(const DB *dbs) +{ + DB *db = (DB *)dbs->internal; + + return (* db->fd)(db); +} + +/* + * the naming convention we use is + * change the .xxx into .dir. (for nss it's always .db); + * if no .extension exists or is equal to .dir, add a .dir + * the returned data must be freed. + */ +#define DIRSUFFIX ".dir" +static char * +dbs_mkBlobDirName(const char *dbname) +{ + int dbname_len = PORT_Strlen(dbname); + int dbname_end = dbname_len; + const char *cp; + char *blobDir = NULL; + + /* scan back from the end looking for either a directory separator, a '.', + * or the end of the string. NOTE: Windows should check for both separators + * here. For now this is safe because we know NSS always uses a '.' + */ + for (cp = &dbname[dbname_len]; + (cp > dbname) && (*cp != '.') && (*cp != *PATH_SEPARATOR) ; + cp--) + /* Empty */ ; + if (*cp == '.') { + dbname_end = cp - dbname; + if (PORT_Strcmp(cp,DIRSUFFIX) == 0) { + dbname_end = dbname_len; + } + } + blobDir = PORT_ZAlloc(dbname_end+sizeof(DIRSUFFIX)); + if (blobDir == NULL) { + return NULL; + } + PORT_Memcpy(blobDir,dbname,dbname_end); + PORT_Memcpy(&blobDir[dbname_end],DIRSUFFIX,sizeof(DIRSUFFIX)); + return blobDir; +} + +#define DBM_DEFAULT 0 +static const HASHINFO dbs_hashInfo = { + DBS_BLOCK_SIZE, /* bucket size, must be greater than = to + * or maximum entry size (+ header) + * we allow before blobing */ + DBM_DEFAULT, /* Fill Factor */ + DBM_DEFAULT, /* number of elements */ + DBS_CACHE_SIZE, /* cache size */ + DBM_DEFAULT, /* hash function */ + DBM_DEFAULT, /* byte order */ +}; + +/* + * the open function. NOTE: this is the only exposed function in this file. + * everything else is called through the function table pointer. + */ +DB * +dbsopen(const char *dbname, int flags, int mode, DBTYPE type, + const void *userData) +{ + DB *db = NULL,*dbs = NULL; + DBS *dbsp = NULL; + + /* NOTE: we are overriding userData with dbs_hashInfo. since all known + * callers pass 0, this is ok, otherwise we should merge the two */ + + dbsp = (DBS *)PORT_ZAlloc(sizeof(DBS)); + if (!dbsp) { + return NULL; + } + dbs = &dbsp->db; + + dbsp->blobdir=dbs_mkBlobDirName(dbname); + if (dbsp->blobdir == NULL) { + goto loser; + } + dbsp->mode = mode; + dbsp->readOnly = (PRBool)(flags == NO_RDONLY); + dbsp->dbs_mapfile = NULL; + dbsp->dbs_addr = NULL; + dbsp->dbs_len = 0; + + /* the real dbm call */ + db = dbopen(dbname, flags, mode, type, &dbs_hashInfo); + if (db == NULL) { + goto loser; + } + dbs->internal = (void *) db; + dbs->type = type; + dbs->close = dbs_close; + dbs->get = dbs_get; + dbs->del = dbs_del; + dbs->put = dbs_put; + dbs->seq = dbs_seq; + dbs->sync = dbs_sync; + dbs->fd = dbs_fd; + + return dbs; +loser: + if (db) { + (*db->close)(db); + } + if (dbsp && dbsp->blobdir) { + PORT_Free(dbsp->blobdir); + } + if (dbsp) { + PORT_Free(dbsp); + } + return NULL; +} diff --git a/security/nss/lib/certdb/genname.c b/security/nss/lib/certdb/genname.c index 9fe969e3a..9ee7126a3 100644 --- a/security/nss/lib/certdb/genname.c +++ b/security/nss/lib/certdb/genname.c @@ -193,17 +193,27 @@ CERT_CreateGeneralNameList(CERTGeneralName *name) { } list = (CERTGeneralNameList *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralNameList)); + if (!list) + goto loser; if (name != NULL) { list->name = (CERTGeneralName *) PORT_ArenaZAlloc(arena, sizeof(CERTGeneralName)); + if (!list->name) + goto loser; list->name->l.next = list->name->l.prev = &list->name->l; CERT_CopyGeneralName(arena, list->name, name); } list->lock = PZ_NewLock(nssILockList); + if (!list->lock) + goto loser; list->arena = arena; list->refCount = 1; done: return list; + +loser: + PORT_FreeArena(arena, PR_FALSE); + return NULL; } CERTGeneralName * @@ -244,7 +254,6 @@ SECItem * cert_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PRArenaPool *arena) { - PORT_Assert(arena); if (arena == NULL) { goto loser; @@ -290,9 +299,12 @@ cert_EncodeGeneralName(CERTGeneralName *genName, SECItem *dest, PRArenaPool *are case certDirectoryName: if (genName->derDirectoryName.data == NULL) { /* The field hasn't been encoded yet. */ + SECItem * pre_dest = SEC_ASN1EncodeItem (arena, &(genName->derDirectoryName), &(genName->name.directoryName), CERT_NameTemplate); + if (!pre_dest) + goto loser; } if (genName->derDirectoryName.data == NULL) { goto loser; @@ -433,12 +445,12 @@ cert_DecodeGeneralNames (PRArenaPool *arena, } currentName->l.next = head; currentName->l.prev = tail; - tail = &(currentName->l); - (cert_get_prev_general_name(currentName))->l.next = tail; + tail = head->prev = tail->next = &(currentName->l); encodedGenName++; } - (cert_get_next_general_name(currentName))->l.prev = tail; - return cert_get_next_general_name(currentName); + if (currentName) { + return cert_get_next_general_name(currentName); + } loser: return NULL; } @@ -570,10 +582,10 @@ cert_DecodeNameConstraint(PRArenaPool *arena, SECStatus rv = SECSuccess; CERTGeneralName *temp; - - PORT_Assert(arena); constraint = (CERTNameConstraint *) PORT_ArenaZAlloc(arena, sizeof(CERTNameConstraint)); + if (!constraint) + goto loser; rv = SEC_ASN1DecodeItem(arena, constraint, CERTNameConstraintTemplate, encodedConstraint); if (rv != SECSuccess) { goto loser; @@ -605,6 +617,7 @@ cert_DecodeNameConstraintSubTree(PRArenaPool *arena, CERTNameConstraint *next = NULL; int i = 0; + PORT_Assert(arena); while (subTree[i] != NULL) { current = cert_DecodeNameConstraint(arena, subTree[i]); if (current == NULL) { @@ -621,14 +634,6 @@ cert_DecodeNameConstraintSubTree(PRArenaPool *arena, first->l.prev = &(current->l); return first; loser: - if (first) { - current = first; - do { - next = cert_get_next_name_constraint(current); - PORT_Free(current); - current = next; - }while (current != first); - } return NULL; } @@ -707,6 +712,8 @@ CERT_CopyGeneralName(PRArenaPool *arena, rv = SECITEM_CopyItem(arena, &dest->name.other, &src->name.other); } } + if (rv != SECSuccess) + return rv; src = cert_get_next_general_name(src); /* if there is only one general name, we shouldn't do this */ if (src != srcHead) { @@ -718,6 +725,8 @@ CERT_CopyGeneralName(PRArenaPool *arena, temp = (CERTGeneralName *) PORT_ZAlloc(sizeof(CERTGeneralName)); } + if (!temp) + return SECFailure; temp->l.next = &destHead->l; temp->l.prev = &dest->l; destHead->l.prev = &temp->l; @@ -842,7 +851,7 @@ CERT_AddNameConstraint(CERTNameConstraint *list, SECStatus -CERT_GetNameConstriantByType (CERTNameConstraint *constraints, +CERT_GetNameConstraintByType (CERTNameConstraint *constraints, CERTGeneralNameType type, CERTNameConstraint **returnList, PRArenaPool *arena) @@ -968,41 +977,72 @@ loser: return NULL; } +/* This function does very basic regular expression matching. +** The only wildcard character is "*", which matches any substring. +** constraint is the regular expression. name is to be tested against it. +** return SECSuccess on match, SECFailure otherwise. Does not set error. +*/ static SECStatus -compareNameToConstraint(char *name, char *constraint, PRBool substring) +compareNameToConstraint(const char *name, const char *constraint, int level) { + PRBool substring = PR_FALSE; SECStatus rv; - if (*constraint == '\0' && *name == '\0') { - return SECSuccess; + while (*name == *constraint && *constraint != '\0' && *constraint != '*') { + ++name; + ++constraint; } - if (*constraint == '*') { - return compareNameToConstraint(name, constraint + 1, PR_TRUE); + if (*constraint == '\0' && *name == '\0') + return SECSuccess; + + while (*constraint == '*') { + ++constraint; + substring = PR_TRUE; } - if (substring) { - if (*constraint == '\0') { - return SECSuccess; - } - while (*name != *constraint) { - if (*name == '\0') { - return SECFailure; - } - name++; - } - rv = compareNameToConstraint(name + 1, constraint + 1, PR_FALSE); - if (rv == SECSuccess) { - return rv; - } - name++; - } else { - if (*name == *constraint) { + + if (!substring) + return SECFailure; + + if (*constraint == '\0') + return SECSuccess; + + if (++level > 20) + return SECFailure; /* prevent stack overflow */ + + do { + while (*name != *constraint && *name != '\0') name++; - constraint++; - } else { + if (*name == '\0') return SECFailure; - } - } - return compareNameToConstraint(name, constraint, substring); + + /* recurse */ + rv = compareNameToConstraint(name + 1, constraint + 1, level); + + ++name; + } while (rv != SECSuccess); + return rv; +} + +#define compareN2C(n,c) compareNameToConstraint((n),(c),0) + +/* This isn't right for items containing UCS2 or UCS4. +** Those should be converted to UTF8 rather than merely strncpy'ed. +** But it's not clear that we can tell what the encoding is here. +*/ +static char * +secItem2String(PLArenaPool *arena, SECItem *item) +{ + char * cPtr; + if (arena) + cPtr = PORT_ArenaAlloc(arena, item->len + 1); + else + cPtr = PORT_Alloc(item->len + 1); + if (cPtr) { + if (item->len) + PORT_Strncpy(cPtr, (char *)item->data, item->len); + cPtr[item->len] = '\0'; + } + return cPtr; } SECStatus @@ -1011,234 +1051,247 @@ cert_CompareNameWithConstraints(CERTGeneralName *name, PRBool excluded) { SECStatus rv = SECSuccess; - char *nameString = NULL; - char *constraintString = NULL; + char *nString = NULL; + char *cString = NULL; int start; int end; - int tag; - CERTRDN **nameRDNS, *nameRDN; - CERTRDN **constraintRDNS, *constraintRDN; - CERTAVA **nameAVAS, *nameAVA; - CERTAVA **constraintAVAS, *constraintAVA; + CERTRDN **nRDNs, *nRDN; + CERTAVA **nAVAs, *nAVA; CERTNameConstraint *current; - SECItem *avaValue; - CERTName constraintName; CERTName certName; SECComparison status = SECEqual; - PRArenaPool *certNameArena; - PRArenaPool *constraintNameArena; + PRArenaPool *nArena; + + if (!constraints) + return SECSuccess; + + nArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!nArena) + return SECFailure; certName.arena = NULL; - certName.rdns = NULL; - constraintName.arena = NULL; - constraintName.rdns = NULL; - if (constraints != NULL) { - current = constraints; - if (name->type == certDirectoryName) { - certNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(certNameArena, &certName, &name->name.directoryName); - nameRDNS = certName.rdns; - for (;;) { - nameRDN = *nameRDNS++; - nameAVAS = nameRDN->avas; - for(;;) { - nameAVA = *nameAVAS++; - tag = CERT_GetAVATag(nameAVA); - if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS || - tag == SEC_OID_RFC1274_MAIL) { - avaValue = CERT_DecodeAVAValue(&nameAVA->value); - nameString = (char*)PORT_ZAlloc(avaValue->len + 1); - nameString = PORT_Strncpy(nameString, (char *) avaValue->data, avaValue->len); - start = 0; - while(nameString[start] != '@' && nameString[start + 1] != '\0') { - start++; - } + certName.rdns = NULL; + + /* Phase 1. If the name is a Directory Name, look through all the + ** AVAs in all the RDNs for any that are email addresses. + ** Subject all email addresses to all RFC822 email address constraints. + */ + if (name->type == certDirectoryName) { + rv = CERT_CopyName(nArena, &certName, &name->name.directoryName); + if (rv != SECSuccess) + goto loser; + nRDNs = certName.rdns; + while (nRDNs && *nRDNs) { /* loop over RDNs */ + nRDN = *nRDNs++; + nAVAs = nRDN->avas; + while (nAVAs && *nAVAs) { /* loop over AVAs */ + int tag; + nAVA = *nAVAs++; + tag = CERT_GetAVATag(nAVA); + if ( tag == SEC_OID_PKCS9_EMAIL_ADDRESS || + tag == SEC_OID_RFC1274_MAIL) { /* email AVA */ + SECItem *avaValue; + avaValue = CERT_DecodeAVAValue(&nAVA->value); + if (!avaValue) + goto loser; + nString = secItem2String(nArena, avaValue); + SECITEM_FreeItem(avaValue, PR_TRUE); + if (!nString) + goto loser; + start = 0; + while (nString[start] != '@' && nString[start] != '\0') { + start++; + } + if (nString[start]) start++; - do{ - if (current->name.type == certRFC822Name) { - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, - PR_FALSE); - - if (constraintString != NULL) { - PORT_Free(constraintString); - constraintString = NULL; - } - if (nameString != NULL) { - PORT_Free(nameString); - nameString = NULL; - } - if (rv == SECSuccess && excluded == PR_TRUE) { + current = constraints; + do { /* loop over constraints */ + if (current->name.type == certRFC822Name) { + cString = + secItem2String(nArena, ¤t->name.name.other); + if (!cString) + goto loser; + rv = compareN2C(nString + start, cString); + if (rv == SECSuccess) { + if (excluded) goto found; - } - if (rv == SECSuccess && excluded == PR_FALSE) { - break; - } + break; /* out of loop over constraints. */ } - current = cert_get_next_name_constraint(current); - } while (current != constraints); - } - if (rv != SECSuccess && excluded == PR_FALSE) { - goto loser; - } - if (*nameAVAS == NULL) { - break; - } - } - if (*nameRDNS == NULL) { - break; + } /* email address constraint */ + current = cert_get_next_name_constraint(current); + } while (current != constraints); /*loop over constraints*/ + } /* handle one email AVA */ + if (rv != SECSuccess && excluded == PR_FALSE) { + goto no_match; } } - } - current = constraints; - do { - switch (name->type) { - case certDNSName: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certRFC822Name: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - start = 0; - while(nameString[start] != '@' && nameString[start + 1] != '\0') { - start++; - } + } /* loop over RDNs */ + } /* name->type == certDirectoryName */ + + /* Phase 2. loop over all constratints for this name. */ + current = constraints; + do { + switch (name->type) { + + case certDNSName: + PORT_Assert(name->type == current->name.type); + nString = secItem2String(nArena, &name->name.other); + if (!nString) + goto loser; + cString = secItem2String(nArena, ¤t->name.name.other); + if (!cString) + goto loser; + rv = compareN2C(nString, cString); + break; + + case certRFC822Name: + PORT_Assert(name->type == current->name.type); + nString = secItem2String(nArena, &name->name.other); + if (!nString) + goto loser; + start = 0; + while (nString[start] != '@' && + nString[start] != '\0') { start++; - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); - } - break; - case certURI: - nameString = (char*)PORT_ZAlloc(name->name.other.len + 1); - nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, - name->name.other.len); - start = 0; - while(PORT_Strncmp(nameString + start, "://", 3) != 0 && - nameString[start + 3] != '\0') { - start++; - } + } + if (nString[start]) + start++; + cString = secItem2String(nArena, ¤t->name.name.other); + if (!cString) + goto loser; + rv = compareN2C(nString + start, cString); + break; + + case certURI: + PORT_Assert(name->type == current->name.type); + nString = secItem2String(nArena, &name->name.other); + if (!nString) + goto loser; + /* XXX This URI hostname parsing is wrong because it doesn't + ** handle user name and password strings that can come + ** before the host name. + */ + start = 0; + while(nString[start] != 0 && + PORT_Strncmp(nString + start, "://", 3) != 0 ) { + start++; + } + if (nString[start]) start +=3; - end = 0; - while(nameString[start + end] != '/' && - nameString[start + end] != '\0') { - end++; - } - nameString[start + end] = '\0'; - constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1); - constraintString = PORT_Strncpy(constraintString, - (char *) current->name.name.other.data, - current->name.name.other.len); - rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE); - if (nameString != NULL) { - PORT_Free(nameString); - } - if (constraintString != NULL) { - PORT_Free(constraintString); + end = 0; + while(nString[start + end] != '/' && + nString[start + end] != ':' && + nString[start + end] != '\0') { + end++; + } + nString[start + end] = '\0'; + cString = secItem2String(nArena, ¤t->name.name.other); + if (!cString) + goto loser; + rv = compareN2C(nString + start, cString); + break; + + case certDirectoryName: + PORT_Assert(current->name.type == certDirectoryName || \ + current->name.type == certRFC822Name); + if (current->name.type == certRFC822Name) + goto next_constraint; /* already handled in phase 1. */ + if (current->name.type == certDirectoryName) { + PRArenaPool *cArena; + CERTRDN **cRDNs, *cRDN; + CERTAVA **cAVAs, *cAVA; + CERTName constraintName; + + constraintName.arena = NULL; + constraintName.rdns = NULL; + + cArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!cArena) + goto loser; + rv = CERT_CopyName(cArena, &constraintName, + ¤t->name.name.directoryName); + if (rv != SECSuccess) { + PORT_FreeArena(cArena, PR_FALSE); + goto loser; } - break; - case certDirectoryName: - if (current->name.type == certDirectoryName) { - constraintNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(constraintNameArena, &constraintName, ¤t->name.name.directoryName); - constraintRDNS = constraintName.rdns; - for (;;) { - constraintRDN = *constraintRDNS++; - constraintAVAS = constraintRDN->avas; - for(;;) { - constraintAVA = *constraintAVAS++; - certNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - CERT_CopyName(certNameArena, &certName, &name->name.directoryName); - nameRDNS = certName.rdns; - for (;;) { - nameRDN = *nameRDNS++; - nameAVAS = nameRDN->avas++; - for(;;) { - nameAVA = *nameAVAS++; - status = CERT_CompareAVA(constraintAVA, nameAVA); - if (status == SECEqual || *nameAVAS == NULL) { - break; - } - } - if (status == SECEqual || *nameRDNS == NULL) { + cRDNs = constraintName.rdns; + while (cRDNs && *cRDNs) { /* loop over constraint RDNs */ + cRDN = *cRDNs++; + cAVAs = cRDN->avas; + while (cAVAs && *cAVAs) { /* loop over constraint AVAs */ + cAVA = *cAVAs++; + + /* certName was initialized in Phase 1. */ + PORT_Assert(certName.arena != NULL); + + nRDNs = certName.rdns; + while (nRDNs && *nRDNs) { /* loop over name RDNs */ + nRDN = *nRDNs++; + nAVAs = nRDN->avas; + while (nAVAs && *nAVAs) { /* loop over name AVAs */ + nAVA = *nAVAs++; + status = CERT_CompareAVA(cAVA, nAVA); + if (status == SECEqual) break; - } - } - if (status != SECEqual || *constraintAVAS == NULL) { + } /* loop over name AVAs */ + if (status == SECEqual) break; - } - } - if (status != SECEqual || *constraintRDNS == NULL) { + } /* loop over name RDNs */ + if (status != SECEqual) break; - } - } - if (status == SECEqual) { - if (excluded == PR_FALSE) { - goto found; - } else { - goto loser; - } - } - break; - } else if (current->name.type == certRFC822Name) { - current = cert_get_next_name_constraint(current); - continue; - } - default: - /* other types are not supported */ - if (excluded) { - goto found; - } else { - goto loser; + } /* loop over AVAs in constraint */ + if (status != SECEqual) + break; + } /* loop over RDNs in constraint */ + PORT_FreeArena(cArena, PR_FALSE); + if (status == SECEqual) { + if (!excluded) + goto found; + goto no_match; } + break; } - if (rv == SECSuccess && status == SECEqual) { - goto found; - } - current = cert_get_next_name_constraint(current); - } while (current !=constraints); - } else { - goto found; - } -loser: - if (certName.arena) { - CERT_DestroyName(&certName); - } - if (constraintName.arena) { - CERT_DestroyName(&constraintName); - } + goto loser; +#ifdef NOTYET + case certOtherName: /* type 1 */ + case certX400Address: /* type 4 */ + case certEDIPartyName: /* type 6 */ + case certIPAddress: /* type 8 */ + case certRegisterID: /* type 9 */ + PORT_Assert(name->type == current->name.type); + if (name->type == current->name.type && + name->name.other.len == current->name.name.other.len && + !memcmp(name->name.other.data, current->name.name.other.data, + name->name.other.len)) + rv = SECSuccess; + else + rv = SECFailure; + break; +#endif + default: + /* non-standard types are not supported */ + goto loser; + } + if (rv == SECSuccess && status == SECEqual) { + goto found; + } +next_constraint: + current = cert_get_next_name_constraint(current); + } while (current !=constraints); + +no_match: + if (nArena) + PORT_FreeArena(nArena, PR_FALSE); return SECFailure; + +loser: + if (nArena) + PORT_FreeArena(nArena, PR_FALSE); + return excluded ? SECSuccess : SECFailure; + found: - if (certName.arena) { - CERT_DestroyName(&certName); - } - if (constraintName.arena) { - CERT_DestroyName(&constraintName); - } + if (nArena) + PORT_FreeArena(nArena, PR_FALSE); return SECSuccess; } @@ -1269,7 +1322,7 @@ CERT_CompareNameSpace(CERTCertificate *cert, } do { if (constraints->excluded != NULL) { - rv = CERT_GetNameConstriantByType(constraints->excluded, currentName->type, + rv = CERT_GetNameConstraintByType(constraints->excluded, currentName->type, &matchingConstraints, arena); if (rv != SECSuccess) { goto loser; @@ -1283,7 +1336,7 @@ CERT_CompareNameSpace(CERTCertificate *cert, } } if (constraints->permited != NULL) { - rv = CERT_GetNameConstriantByType(constraints->permited, currentName->type, + rv = CERT_GetNameConstraintByType(constraints->permited, currentName->type, &matchingConstraints, arena); if (rv != SECSuccess) { goto loser; diff --git a/security/nss/lib/certdb/manifest.mn b/security/nss/lib/certdb/manifest.mn index 1cb6ff4b7..578faeea4 100644 --- a/security/nss/lib/certdb/manifest.mn +++ b/security/nss/lib/certdb/manifest.mn @@ -56,6 +56,7 @@ CSRCS = \ $(CERTINIT) \ certxutl.c \ crl.c \ + dbmshim.c \ genname.c \ pcertdb.c \ polcyxtn.c \ diff --git a/security/nss/lib/certdb/pcertdb.c b/security/nss/lib/certdb/pcertdb.c index f6601d4cb..c7463e52b 100644 --- a/security/nss/lib/certdb/pcertdb.c +++ b/security/nss/lib/certdb/pcertdb.c @@ -238,7 +238,11 @@ ReadDBEntry(CERTCertDBHandle *handle, certDBEntryCommon *entry, goto loser; } buf = (unsigned char *)data.data; - if ( buf[0] != (unsigned char)CERT_DB_FILE_VERSION ) { + /* version 7 uses the shame scheme, we may be using a v7 db if we + * opened the dbs readonly + */ + if ( !((buf[0] == (unsigned char)CERT_DB_FILE_VERSION) || + (buf[0] == (unsigned char)CERT_DB_V7_FILE_VERSION)) ) { PORT_SetError(SEC_ERROR_BAD_DATABASE); goto loser; } @@ -445,6 +449,7 @@ DecodeDBCertEntry(certDBEntryCert *entry, SECItem *dbentry) lenoff = 3; break; case 7: + case 8: headerlen = DB_CERT_ENTRY_HEADER_LEN; lenoff = 6; break; @@ -3200,6 +3205,9 @@ RemovePermSubjectNode(CERTCertificate *cert) /* if the subject had an email record, then delete it too */ DeleteDBSMimeEntry(cert->dbhandle, subjectList->entry->emailAddr); } + if ( subjectList->entry->nickname ) { + DeleteDBNicknameEntry(cert->dbhandle, subjectList->entry->nickname); + } DestroyDBEntry((certDBEntry *)subjectList->entry); subjectList->entry = NULL; @@ -3218,11 +3226,12 @@ AddPermSubjectNode(CERTCertificate *cert, char *nickname) CERTSubjectList *subjectList; certDBEntrySubject *entry; SECItem *newCertKeys, *newKeyIDs; - int i; + int i, new_i; SECStatus rv; CERTCertificate *cmpcert; unsigned int nnlen; int ncerts; + PRBool added = PR_FALSE; subjectList = cert->subjectList; @@ -3264,27 +3273,32 @@ AddPermSubjectNode(CERTCertificate *cert, char *nickname) return(SECFailure); } - for ( i = 0; i < ncerts; i++ ) { + for ( i = 0, new_i = 0; i < ncerts; i++ ) { cmpcert = CERT_FindCertByKeyNoLocking(cert->dbhandle, &entry->certKeys[i]); PORT_Assert(cmpcert); + /* The entry has been corrupted, remove it from the list */ + if (!cmpcert) { + continue; + } if ( CERT_IsNewer(cert, cmpcert) ) { /* insert before cmpcert */ - rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[i], + rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i], &cert->certKey); if ( rv != SECSuccess ) { return(SECFailure); } - rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[i], + rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i], &cert->subjectKeyID); if ( rv != SECSuccess ) { return(SECFailure); } - /* copy the rest of the entry */ - for ( ; i < ncerts; i++ ) { - newCertKeys[i+1] = entry->certKeys[i]; - newKeyIDs[i+1] = entry->keyIDs[i]; + new_i++; + /* copy the rest of the entries */ + for ( ; i < ncerts; i++, new_i++ ) { + newCertKeys[new_i] = entry->certKeys[i]; + newKeyIDs[new_i] = entry->keyIDs[i]; } /* update certKeys and keyIDs */ @@ -3292,33 +3306,36 @@ AddPermSubjectNode(CERTCertificate *cert, char *nickname) entry->keyIDs = newKeyIDs; /* increment count */ - entry->ncerts++; + entry->ncerts = new_i; + added = PR_TRUE; break; } /* copy this cert entry */ - newCertKeys[i] = entry->certKeys[i]; - newKeyIDs[i] = entry->keyIDs[i]; + newCertKeys[new_i] = entry->certKeys[i]; + newKeyIDs[new_i] = entry->keyIDs[i]; + new_i++; } - if ( entry->ncerts == ncerts ) { + if ( !added ) { /* insert new one at end */ - rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[ncerts], + rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i], &cert->certKey); if ( rv != SECSuccess ) { return(SECFailure); } - rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[ncerts], + rv = SECITEM_CopyItem(entry->common.arena, &newKeyIDs[new_i], &cert->subjectKeyID); if ( rv != SECSuccess ) { return(SECFailure); } + new_i++; /* update certKeys and keyIDs */ entry->certKeys = newCertKeys; entry->keyIDs = newKeyIDs; /* increment count */ - entry->ncerts++; + entry->ncerts = new_i; } } else { /* need to make a new DB entry */ @@ -3357,6 +3374,7 @@ __CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, for( i = 0; i < entry->ncerts; i++ ) { cert = CERT_FindCertByKey(handle, &entry->certKeys[i]); + if (!cert) continue; rv = (* cb)(cert, cbarg); CERT_DestroyCertificate(cert); if ( rv == SECFailure ) { @@ -3605,14 +3623,9 @@ CERT_AddPermNickname(CERTCertificate *cert, char *nickname) CERT_LockDB(cert->dbhandle); - PORT_Assert(cert->nickname == NULL); PORT_Assert(cert->isperm); PORT_Assert(cert->subjectList != NULL); PORT_Assert(cert->subjectList->entry != NULL); - - if ( cert->nickname != NULL ) { - goto done; - } if ( cert->subjectList == NULL ) { goto loser; @@ -3646,7 +3659,6 @@ CERT_AddPermNickname(CERTCertificate *cert, char *nickname) } } -done: CERT_UnlockDB(cert->dbhandle); return(SECSuccess); loser: @@ -3767,6 +3779,144 @@ loser: return(NULL); } +/* forward declaration */ +static SECStatus +UpdateV7DB(CERTCertDBHandle *handle, DB *updatedb); + +/* + * version 8 uses the same schema as version 7. The only differences are + * 1) version 8 db uses the blob shim to store data entries > 32k. + * 2) version 8 db sets the db block size to 32k. + * both of these are dealt with by the handle. + */ + +static SECStatus +UpdateV8DB(CERTCertDBHandle *handle, DB *updatedb) +{ + return UpdateV7DB(handle,updatedb); +} + + +/* + * we could just blindly sequence through reading key data pairs and writing + * them back out, but some cert.db's have gotten quite large and may have some + * subtle corruption problems, so instead we cycle through the certs and + * CRL's and S/MIME profiles and rebuild our subject lists from those records. + */ +static SECStatus +UpdateV7DB(CERTCertDBHandle *handle, DB *updatedb) +{ + DBT key, data; + int ret; + CERTCertificate *cert; + PRBool isKRL = PR_FALSE; + certDBEntryType entryType; + SECItem dbEntry, dbKey; + certDBEntryRevocation crlEntry; + certDBEntryCert certEntry; + certDBEntrySMime smimeEntry; + SECStatus rv; + + ret = (* updatedb->seq)(updatedb, &key, &data, R_FIRST); + + if ( ret ) { + return(SECFailure); + } + + do { + unsigned char *dataBuf = (unsigned char *)data.data; + unsigned char *keyBuf = (unsigned char *)key.data; + dbEntry.data = &dataBuf[SEC_DB_ENTRY_HEADER_LEN]; + dbEntry.len = data.size - SEC_DB_ENTRY_HEADER_LEN; + entryType = (certDBEntryType) keyBuf[0]; + dbKey.data = &keyBuf[SEC_DB_KEY_HEADER_LEN]; + dbKey.len = key.size - SEC_DB_KEY_HEADER_LEN; + if ((dbEntry.len <= 0) || (dbKey.len <= 0)) { + continue; + } + + switch (entryType) { + /* these entries will get regenerated as we read the + * rest of the data from the database */ + case certDBEntryTypeVersion: + case certDBEntryTypeSubject: + case certDBEntryTypeContentVersion: + case certDBEntryTypeNickname: + /*default: */ + break; + + case certDBEntryTypeCert: + /* decode Entry */ + certEntry.common.version = (unsigned int)dataBuf[0]; + certEntry.common.type = entryType; + certEntry.common.flags = (unsigned int)dataBuf[2]; + certEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (certEntry.common.arena == NULL) { + break; + } + rv = DecodeDBCertEntry(&certEntry,&dbEntry); + if (rv != SECSuccess) { + break; + } + /* should we check for existing duplicates? */ + cert = CERT_DecodeDERCertificate(&certEntry.derCert, PR_FALSE, + certEntry.nickname); + if (cert) { + AddCertToPermDB(handle, cert, certEntry.nickname, + &certEntry.trust); + CERT_DestroyCertificate(cert); + } + /* free data allocated by the decode */ + PORT_FreeArena(certEntry.common.arena, PR_FALSE); + certEntry.common.arena = NULL; + break; + + case certDBEntryTypeKeyRevocation: + isKRL = PR_TRUE; + /* fall through */ + case certDBEntryTypeRevocation: + crlEntry.common.version = (unsigned int)dataBuf[0]; + crlEntry.common.type = entryType; + crlEntry.common.flags = (unsigned int)dataBuf[2]; + crlEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (crlEntry.common.arena == NULL) { + break; + } + rv = DecodeDBCrlEntry(&crlEntry,&dbEntry); + if (rv != SECSuccess) { + break; + } + + rv = WriteDBCrlEntry(handle, &crlEntry); + if (rv != SECSuccess) { + break; + } + /* free data allocated by the decode */ + PORT_FreeArena(crlEntry.common.arena, PR_FALSE); + crlEntry.common.arena = NULL; + break; + + case certDBEntryTypeSMimeProfile: + smimeEntry.common.version = (unsigned int)dataBuf[0]; + smimeEntry.common.type = entryType; + smimeEntry.common.flags = (unsigned int)dataBuf[2]; + smimeEntry.common.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + rv = DecodeDBSMimeEntry(&smimeEntry,&dbEntry,(char *)dbKey.data); + /* decode entry */ + WriteDBSMimeEntry(handle, &smimeEntry); + PORT_FreeArena(smimeEntry.common.arena, PR_FALSE); + smimeEntry.common.arena = NULL; + break; + } + } while ( (* updatedb->seq)(updatedb, &key, &data, R_NEXT) == 0 ); + + (* updatedb->close)(updatedb); + + /* a database update is a good time to go back and verify the integrity of + * the keys and certs */ + return(SECSuccess); +} + /* * NOTE - Version 6 DB did not go out to the real world in a release, * so we can remove this function in a later release. @@ -4254,7 +4404,7 @@ SEC_OpenPermCertDB(CERTCertDBHandle *handle, PRBool readOnly, /* * first open the permanent file based database. */ - handle->permCertDB = dbopen( certdbname, openflags, 0600, DB_HASH, 0 ); + handle->permCertDB = dbsopen( certdbname, openflags, 0600, DB_HASH, 0 ); /* check for correct version number */ if ( handle->permCertDB ) { @@ -4277,14 +4427,34 @@ SEC_OpenPermCertDB(CERTCertDBHandle *handle, PRBool readOnly, /* if first open fails, try to create a new DB */ if ( handle->permCertDB == NULL ) { - /* don't create if readonly */ if ( readOnly ) { - goto loser; + /* if opening read-only and cert8.db does not exist, + * use cert7.db + */ + tmpname = (* namecb)(cbarg, 7); /* get v7 db name */ + if (!tmpname) { + goto loser; + } + handle->permCertDB = dbopen(tmpname, O_RDONLY, 0600, DB_HASH, 0); + PORT_Free(tmpname); + if (!handle->permCertDB) { + goto loser; + } + versionEntry = ReadDBVersionEntry(handle); + if ( versionEntry == NULL ) { + /* no version number */ + goto loser; + } else if ( versionEntry->common.version != 7 ) { + DestroyDBEntry((certDBEntry *)versionEntry); + goto loser; + } + PORT_Free(certdbname); + return SECSuccess; } - - handle->permCertDB = dbopen(certdbname, - O_RDWR | O_CREAT | O_TRUNC, - 0600, DB_HASH, 0); + /* create a new database */ + handle->permCertDB = dbsopen(certdbname, + O_RDWR | O_CREAT | O_TRUNC, + 0600, DB_HASH, 0); /* if create fails then we lose */ if ( handle->permCertDB == 0 ) { @@ -4303,7 +4473,22 @@ SEC_OpenPermCertDB(CERTCertDBHandle *handle, PRBool readOnly, if ( rv != SECSuccess ) { goto loser; } - +#if 0 /* in this 3.3.4.x version, we want to avoid upgrading 7 to 8 */ + /* try to upgrade old db here */ + tmpname = (* namecb)(cbarg, 7); /* get v7 db name */ + if ( tmpname ) { + updatedb = dbopen( tmpname, O_RDONLY, 0600, DB_HASH, 0 ); + PORT_Free(tmpname); + if ( updatedb ) { + rv = UpdateV7DB(handle, updatedb); + if ( rv != SECSuccess ) { + goto loser; + } + updated = PR_TRUE; + goto update_finished; + } + } +#endif /* try to upgrade old db here */ tmpname = (* namecb)(cbarg, 6); /* get v6 db name */ if ( tmpname ) { @@ -4351,6 +4536,7 @@ SEC_OpenPermCertDB(CERTCertDBHandle *handle, PRBool readOnly, } } } +update_finished: /* initialize the database with our well known certificates * or in the case of update, just fall down to CERT_AddNewCerts() @@ -4401,14 +4587,7 @@ DeletePermCert(CERTCertificate *cert) if ( rv != SECSuccess ) { ret = SECFailure; } - - if ( cert->nickname ) { - rv = DeleteDBNicknameEntry(cert->dbhandle, cert->nickname); - if ( rv != SECSuccess ) { - ret = SECFailure; - } - } - + rv = RemovePermSubjectNode(cert); return(ret); @@ -4686,6 +4865,10 @@ __CERT_ClosePermCertDB(CERTCertDBHandle *handle) certdb_Close( handle->permCertDB ); handle->permCertDB = 0; } + if (handle->dbMon) { + PZ_DestroyMonitor(handle->dbMon); + handle->dbMon = NULL; + } } return; } diff --git a/security/nss/lib/certdb/secname.c b/security/nss/lib/certdb/secname.c index 4df4cd204..597f9ae32 100644 --- a/security/nss/lib/certdb/secname.c +++ b/security/nss/lib/certdb/secname.c @@ -67,8 +67,8 @@ CountArray(void **array) return count; } -static void -**AddToArray(PRArenaPool *arena, void **array, void *element) +static void ** +AddToArray(PRArenaPool *arena, void **array, void *element) { unsigned count; void **ap; @@ -96,35 +96,6 @@ static void return array; } -#if 0 -static void -**RemoveFromArray(void **array, void *element) -{ - unsigned count; - void **ap; - int slot; - - /* Look for element */ - ap = array; - if (ap) { - count = 1; /* count the null at the end */ - slot = -1; - for (; *ap; ap++, count++) { - if (*ap == element) { - /* Found it */ - slot = ap - array; - } - } - if (slot >= 0) { - /* Found it. Squish array down */ - PORT_Memmove((void*) (array + slot), (void*) (array + slot + 1), - (count - slot - 1) * sizeof(void*)); - /* Don't bother reallocing the memory */ - } - } - return array; -} -#endif /* 0 */ SECOidTag CERT_GetAVATag(CERTAVA *ava) @@ -217,6 +188,7 @@ SetupAVAValue(PRArenaPool *arena, int valueType, char *value, SECItem *it, case SEC_ASN1_PRINTABLE_STRING: case SEC_ASN1_IA5_STRING: case SEC_ASN1_T61_STRING: + case SEC_ASN1_UTF8_STRING: /* no conversion required */ valueLen = PORT_Strlen(value); break; case SEC_ASN1_UNIVERSAL_STRING: @@ -352,17 +324,27 @@ SECStatus CERT_CopyRDN(PRArenaPool *arena, CERTRDN *to, CERTRDN *from) { CERTAVA **avas, *fava, *tava; - SECStatus rv; + SECStatus rv = SECSuccess; /* Copy each ava from from */ avas = from->avas; - while ((fava = *avas++) != 0) { - tava = CERT_CopyAVA(arena, fava); - if (!tava) return SECFailure; - rv = CERT_AddAVA(arena, to, tava); - if (rv) return rv; + if (avas) { + if (avas[0] == NULL) { + rv = CERT_AddAVA(arena, to, NULL); + return rv; + } + while ((fava = *avas++) != 0) { + tava = CERT_CopyAVA(arena, fava); + if (!tava) { + rv = SECFailure; + break; + } + rv = CERT_AddAVA(arena, to, tava); + if (rv != SECSuccess) + break; + } } - return SECSuccess; + return rv; } /************************************************************************/ @@ -453,24 +435,38 @@ SECStatus CERT_CopyName(PRArenaPool *arena, CERTName *to, CERTName *from) { CERTRDN **rdns, *frdn, *trdn; - SECStatus rv; + SECStatus rv = SECSuccess; + + if (!to || !from) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } CERT_DestroyName(to); to->arena = arena; /* Copy each rdn from from */ rdns = from->rdns; - while ((frdn = *rdns++) != 0) { - trdn = CERT_CreateRDN(arena, 0); - if ( trdn == NULL ) { - return(SECFailure); + if (rdns) { + if (rdns[0] == NULL) { + rv = CERT_AddRDN(to, NULL); + return rv; + } + while ((frdn = *rdns++) != NULL) { + trdn = CERT_CreateRDN(arena, 0); + if (!trdn) { + rv = SECFailure; + break; + } + rv = CERT_CopyRDN(arena, trdn, frdn); + if (rv != SECSuccess) + break; + rv = CERT_AddRDN(to, trdn); + if (rv != SECSuccess) + break; } - rv = CERT_CopyRDN(arena, trdn, frdn); - if (rv) return rv; - rv = CERT_AddRDN(to, trdn); - if (rv) return rv; } - return SECSuccess; + return rv; } /************************************************************************/ diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c index 38473cf71..5a9955f7a 100644 --- a/security/nss/lib/cryptohi/seckey.c +++ b/security/nss/lib/cryptohi/seckey.c @@ -377,7 +377,8 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count) (tag != SEC_OID_MISSI_DSS) && (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) && (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) && - (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) ) { + (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) && + (tag != SEC_OID_SDN702_DSA_SIGNATURE) ) { return SECSuccess; } @@ -423,7 +424,8 @@ seckey_UpdateCertPQGChain(CERTCertificate * subjectCert, int count) (tag != SEC_OID_MISSI_DSS) && (tag != SEC_OID_ANSIX9_DSA_SIGNATURE) && (tag != SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) && - (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) ) { + (tag != SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) && + (tag != SEC_OID_SDN702_DSA_SIGNATURE) ) { return SECFailure; } @@ -865,6 +867,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) return pubk; break; case SEC_OID_ANSIX9_DSA_SIGNATURE: + case SEC_OID_SDN702_DSA_SIGNATURE: pubk->keyType = dsaKey; rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &os); if (rv != SECSuccess) break; @@ -909,7 +912,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) if (rv == SECSuccess) return pubk; - break; + break; case SEC_OID_MISSI_ALT_KEA: pubk->keyType = keaKey; @@ -923,7 +926,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki) if (rv == SECSuccess) return pubk; - break; + break; default: diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index 17b87bb70..c5b5a1299 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -187,6 +187,7 @@ endif endif else # Solaris x86 + DEFINES += -D_X86_ DEFINES += -DMP_USE_UINT_DIGIT DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D ASFILES = mpi_i86pc.s diff --git a/security/nss/lib/freebl/md5.c b/security/nss/lib/freebl/md5.c index b0c0ed6a0..55653f18f 100644 --- a/security/nss/lib/freebl/md5.c +++ b/security/nss/lib/freebl/md5.c @@ -241,7 +241,8 @@ MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length) MD5Context * MD5_NewContext(void) { - MD5Context *cx = (MD5Context *)PORT_ZAlloc(sizeof(MD5Context)); + /* no need to ZAlloc, _Begin will init the context */ + MD5Context *cx = (MD5Context *)PORT_Alloc(sizeof(MD5Context)); if (cx == NULL) { PORT_SetError(PR_OUT_OF_MEMORY_ERROR); return NULL; @@ -271,6 +272,14 @@ MD5_Begin(MD5Context *cx) #define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s)) +#if defined(SOLARIS) || defined(HPUX) +#define addto64(sumhigh, sumlow, addend) \ + sumlow += addend; sumhigh += (sumlow < addend); +#else +#define addto64(sumhigh, sumlow, addend) \ + sumlow += addend; if (sumlow < addend) ++sumhigh; +#endif + #define MASK 0x00ff00ff #ifdef IS_LITTLE_ENDIAN #define lendian(i32) \ @@ -280,14 +289,56 @@ MD5_Begin(MD5Context *cx) (tmp = i32 >> 16 | i32 << 16, (tmp & MASK) << 8 | tmp >> 8 & MASK) #endif -#if defined(SOLARIS) || defined(HPUX) -#define addto64(sumhigh, sumlow, addend) \ - sumlow += addend; sumhigh += (sumlow < addend); -#else -#define addto64(sumhigh, sumlow, addend) \ - sumlow += addend; if (sumlow < addend) ++sumhigh; +#ifndef IS_LITTLE_ENDIAN + +#define lebytes(b4) \ + ((b4)[3] << 24 | (b4)[2] << 16 | (b4)[1] << 8 | (b4)[0]) + +static void +md5_prep_state_le(MD5Context *cx) +{ + PRUint32 tmp; + cx->u.w[0] = lendian(cx->u.w[0]); + cx->u.w[1] = lendian(cx->u.w[1]); + cx->u.w[2] = lendian(cx->u.w[2]); + cx->u.w[3] = lendian(cx->u.w[3]); + cx->u.w[4] = lendian(cx->u.w[4]); + cx->u.w[5] = lendian(cx->u.w[5]); + cx->u.w[6] = lendian(cx->u.w[6]); + cx->u.w[7] = lendian(cx->u.w[7]); + cx->u.w[8] = lendian(cx->u.w[8]); + cx->u.w[9] = lendian(cx->u.w[9]); + cx->u.w[10] = lendian(cx->u.w[10]); + cx->u.w[11] = lendian(cx->u.w[11]); + cx->u.w[12] = lendian(cx->u.w[12]); + cx->u.w[13] = lendian(cx->u.w[13]); + cx->u.w[14] = lendian(cx->u.w[14]); + cx->u.w[15] = lendian(cx->u.w[15]); +} + +static void +md5_prep_buffer_le(MD5Context *cx, const PRUint8 *beBuf) +{ + cx->u.w[0] = lebytes(&beBuf[0]); + cx->u.w[1] = lebytes(&beBuf[4]); + cx->u.w[2] = lebytes(&beBuf[8]); + cx->u.w[3] = lebytes(&beBuf[12]); + cx->u.w[4] = lebytes(&beBuf[16]); + cx->u.w[5] = lebytes(&beBuf[20]); + cx->u.w[6] = lebytes(&beBuf[24]); + cx->u.w[7] = lebytes(&beBuf[28]); + cx->u.w[8] = lebytes(&beBuf[32]); + cx->u.w[9] = lebytes(&beBuf[36]); + cx->u.w[10] = lebytes(&beBuf[40]); + cx->u.w[11] = lebytes(&beBuf[44]); + cx->u.w[12] = lebytes(&beBuf[48]); + cx->u.w[13] = lebytes(&beBuf[52]); + cx->u.w[14] = lebytes(&beBuf[56]); + cx->u.w[15] = lebytes(&beBuf[60]); +} #endif + #define F(X, Y, Z) \ ((X & Y) | ((~X) & Z)) @@ -313,7 +364,7 @@ MD5_Begin(MD5Context *cx) a = b + cls(a + I(b, c, d) + bufint + ti, s) static void -md5_compress(MD5Context *cx) +md5_compress(MD5Context *cx, const PRUint32 *wBuf) { PRUint32 a, b, c, d; PRUint32 tmp; @@ -321,88 +372,70 @@ md5_compress(MD5Context *cx) b = cx->cv[1]; c = cx->cv[2]; d = cx->cv[3]; -#ifndef IS_LITTLE_ENDIAN - cx->u.w[0] = lendian(cx->u.w[0]); - cx->u.w[1] = lendian(cx->u.w[1]); - cx->u.w[2] = lendian(cx->u.w[2]); - cx->u.w[3] = lendian(cx->u.w[3]); - cx->u.w[4] = lendian(cx->u.w[4]); - cx->u.w[5] = lendian(cx->u.w[5]); - cx->u.w[6] = lendian(cx->u.w[6]); - cx->u.w[7] = lendian(cx->u.w[7]); - cx->u.w[8] = lendian(cx->u.w[8]); - cx->u.w[9] = lendian(cx->u.w[9]); - cx->u.w[10] = lendian(cx->u.w[10]); - cx->u.w[11] = lendian(cx->u.w[11]); - cx->u.w[12] = lendian(cx->u.w[12]); - cx->u.w[13] = lendian(cx->u.w[13]); - cx->u.w[14] = lendian(cx->u.w[14]); - cx->u.w[15] = lendian(cx->u.w[15]); -#endif - FF(a, b, c, d, cx->u.w[R1B0 ], S1_0, T1_0); - FF(d, a, b, c, cx->u.w[R1B1 ], S1_1, T1_1); - FF(c, d, a, b, cx->u.w[R1B2 ], S1_2, T1_2); - FF(b, c, d, a, cx->u.w[R1B3 ], S1_3, T1_3); - FF(a, b, c, d, cx->u.w[R1B4 ], S1_0, T1_4); - FF(d, a, b, c, cx->u.w[R1B5 ], S1_1, T1_5); - FF(c, d, a, b, cx->u.w[R1B6 ], S1_2, T1_6); - FF(b, c, d, a, cx->u.w[R1B7 ], S1_3, T1_7); - FF(a, b, c, d, cx->u.w[R1B8 ], S1_0, T1_8); - FF(d, a, b, c, cx->u.w[R1B9 ], S1_1, T1_9); - FF(c, d, a, b, cx->u.w[R1B10], S1_2, T1_10); - FF(b, c, d, a, cx->u.w[R1B11], S1_3, T1_11); - FF(a, b, c, d, cx->u.w[R1B12], S1_0, T1_12); - FF(d, a, b, c, cx->u.w[R1B13], S1_1, T1_13); - FF(c, d, a, b, cx->u.w[R1B14], S1_2, T1_14); - FF(b, c, d, a, cx->u.w[R1B15], S1_3, T1_15); - GG(a, b, c, d, cx->u.w[R2B0 ], S2_0, T2_0); - GG(d, a, b, c, cx->u.w[R2B1 ], S2_1, T2_1); - GG(c, d, a, b, cx->u.w[R2B2 ], S2_2, T2_2); - GG(b, c, d, a, cx->u.w[R2B3 ], S2_3, T2_3); - GG(a, b, c, d, cx->u.w[R2B4 ], S2_0, T2_4); - GG(d, a, b, c, cx->u.w[R2B5 ], S2_1, T2_5); - GG(c, d, a, b, cx->u.w[R2B6 ], S2_2, T2_6); - GG(b, c, d, a, cx->u.w[R2B7 ], S2_3, T2_7); - GG(a, b, c, d, cx->u.w[R2B8 ], S2_0, T2_8); - GG(d, a, b, c, cx->u.w[R2B9 ], S2_1, T2_9); - GG(c, d, a, b, cx->u.w[R2B10], S2_2, T2_10); - GG(b, c, d, a, cx->u.w[R2B11], S2_3, T2_11); - GG(a, b, c, d, cx->u.w[R2B12], S2_0, T2_12); - GG(d, a, b, c, cx->u.w[R2B13], S2_1, T2_13); - GG(c, d, a, b, cx->u.w[R2B14], S2_2, T2_14); - GG(b, c, d, a, cx->u.w[R2B15], S2_3, T2_15); - HH(a, b, c, d, cx->u.w[R3B0 ], S3_0, T3_0); - HH(d, a, b, c, cx->u.w[R3B1 ], S3_1, T3_1); - HH(c, d, a, b, cx->u.w[R3B2 ], S3_2, T3_2); - HH(b, c, d, a, cx->u.w[R3B3 ], S3_3, T3_3); - HH(a, b, c, d, cx->u.w[R3B4 ], S3_0, T3_4); - HH(d, a, b, c, cx->u.w[R3B5 ], S3_1, T3_5); - HH(c, d, a, b, cx->u.w[R3B6 ], S3_2, T3_6); - HH(b, c, d, a, cx->u.w[R3B7 ], S3_3, T3_7); - HH(a, b, c, d, cx->u.w[R3B8 ], S3_0, T3_8); - HH(d, a, b, c, cx->u.w[R3B9 ], S3_1, T3_9); - HH(c, d, a, b, cx->u.w[R3B10], S3_2, T3_10); - HH(b, c, d, a, cx->u.w[R3B11], S3_3, T3_11); - HH(a, b, c, d, cx->u.w[R3B12], S3_0, T3_12); - HH(d, a, b, c, cx->u.w[R3B13], S3_1, T3_13); - HH(c, d, a, b, cx->u.w[R3B14], S3_2, T3_14); - HH(b, c, d, a, cx->u.w[R3B15], S3_3, T3_15); - II(a, b, c, d, cx->u.w[R4B0 ], S4_0, T4_0); - II(d, a, b, c, cx->u.w[R4B1 ], S4_1, T4_1); - II(c, d, a, b, cx->u.w[R4B2 ], S4_2, T4_2); - II(b, c, d, a, cx->u.w[R4B3 ], S4_3, T4_3); - II(a, b, c, d, cx->u.w[R4B4 ], S4_0, T4_4); - II(d, a, b, c, cx->u.w[R4B5 ], S4_1, T4_5); - II(c, d, a, b, cx->u.w[R4B6 ], S4_2, T4_6); - II(b, c, d, a, cx->u.w[R4B7 ], S4_3, T4_7); - II(a, b, c, d, cx->u.w[R4B8 ], S4_0, T4_8); - II(d, a, b, c, cx->u.w[R4B9 ], S4_1, T4_9); - II(c, d, a, b, cx->u.w[R4B10], S4_2, T4_10); - II(b, c, d, a, cx->u.w[R4B11], S4_3, T4_11); - II(a, b, c, d, cx->u.w[R4B12], S4_0, T4_12); - II(d, a, b, c, cx->u.w[R4B13], S4_1, T4_13); - II(c, d, a, b, cx->u.w[R4B14], S4_2, T4_14); - II(b, c, d, a, cx->u.w[R4B15], S4_3, T4_15); + FF(a, b, c, d, wBuf[R1B0 ], S1_0, T1_0); + FF(d, a, b, c, wBuf[R1B1 ], S1_1, T1_1); + FF(c, d, a, b, wBuf[R1B2 ], S1_2, T1_2); + FF(b, c, d, a, wBuf[R1B3 ], S1_3, T1_3); + FF(a, b, c, d, wBuf[R1B4 ], S1_0, T1_4); + FF(d, a, b, c, wBuf[R1B5 ], S1_1, T1_5); + FF(c, d, a, b, wBuf[R1B6 ], S1_2, T1_6); + FF(b, c, d, a, wBuf[R1B7 ], S1_3, T1_7); + FF(a, b, c, d, wBuf[R1B8 ], S1_0, T1_8); + FF(d, a, b, c, wBuf[R1B9 ], S1_1, T1_9); + FF(c, d, a, b, wBuf[R1B10], S1_2, T1_10); + FF(b, c, d, a, wBuf[R1B11], S1_3, T1_11); + FF(a, b, c, d, wBuf[R1B12], S1_0, T1_12); + FF(d, a, b, c, wBuf[R1B13], S1_1, T1_13); + FF(c, d, a, b, wBuf[R1B14], S1_2, T1_14); + FF(b, c, d, a, wBuf[R1B15], S1_3, T1_15); + GG(a, b, c, d, wBuf[R2B0 ], S2_0, T2_0); + GG(d, a, b, c, wBuf[R2B1 ], S2_1, T2_1); + GG(c, d, a, b, wBuf[R2B2 ], S2_2, T2_2); + GG(b, c, d, a, wBuf[R2B3 ], S2_3, T2_3); + GG(a, b, c, d, wBuf[R2B4 ], S2_0, T2_4); + GG(d, a, b, c, wBuf[R2B5 ], S2_1, T2_5); + GG(c, d, a, b, wBuf[R2B6 ], S2_2, T2_6); + GG(b, c, d, a, wBuf[R2B7 ], S2_3, T2_7); + GG(a, b, c, d, wBuf[R2B8 ], S2_0, T2_8); + GG(d, a, b, c, wBuf[R2B9 ], S2_1, T2_9); + GG(c, d, a, b, wBuf[R2B10], S2_2, T2_10); + GG(b, c, d, a, wBuf[R2B11], S2_3, T2_11); + GG(a, b, c, d, wBuf[R2B12], S2_0, T2_12); + GG(d, a, b, c, wBuf[R2B13], S2_1, T2_13); + GG(c, d, a, b, wBuf[R2B14], S2_2, T2_14); + GG(b, c, d, a, wBuf[R2B15], S2_3, T2_15); + HH(a, b, c, d, wBuf[R3B0 ], S3_0, T3_0); + HH(d, a, b, c, wBuf[R3B1 ], S3_1, T3_1); + HH(c, d, a, b, wBuf[R3B2 ], S3_2, T3_2); + HH(b, c, d, a, wBuf[R3B3 ], S3_3, T3_3); + HH(a, b, c, d, wBuf[R3B4 ], S3_0, T3_4); + HH(d, a, b, c, wBuf[R3B5 ], S3_1, T3_5); + HH(c, d, a, b, wBuf[R3B6 ], S3_2, T3_6); + HH(b, c, d, a, wBuf[R3B7 ], S3_3, T3_7); + HH(a, b, c, d, wBuf[R3B8 ], S3_0, T3_8); + HH(d, a, b, c, wBuf[R3B9 ], S3_1, T3_9); + HH(c, d, a, b, wBuf[R3B10], S3_2, T3_10); + HH(b, c, d, a, wBuf[R3B11], S3_3, T3_11); + HH(a, b, c, d, wBuf[R3B12], S3_0, T3_12); + HH(d, a, b, c, wBuf[R3B13], S3_1, T3_13); + HH(c, d, a, b, wBuf[R3B14], S3_2, T3_14); + HH(b, c, d, a, wBuf[R3B15], S3_3, T3_15); + II(a, b, c, d, wBuf[R4B0 ], S4_0, T4_0); + II(d, a, b, c, wBuf[R4B1 ], S4_1, T4_1); + II(c, d, a, b, wBuf[R4B2 ], S4_2, T4_2); + II(b, c, d, a, wBuf[R4B3 ], S4_3, T4_3); + II(a, b, c, d, wBuf[R4B4 ], S4_0, T4_4); + II(d, a, b, c, wBuf[R4B5 ], S4_1, T4_5); + II(c, d, a, b, wBuf[R4B6 ], S4_2, T4_6); + II(b, c, d, a, wBuf[R4B7 ], S4_3, T4_7); + II(a, b, c, d, wBuf[R4B8 ], S4_0, T4_8); + II(d, a, b, c, wBuf[R4B9 ], S4_1, T4_9); + II(c, d, a, b, wBuf[R4B10], S4_2, T4_10); + II(b, c, d, a, wBuf[R4B11], S4_3, T4_11); + II(a, b, c, d, wBuf[R4B12], S4_0, T4_12); + II(d, a, b, c, wBuf[R4B13], S4_1, T4_13); + II(c, d, a, b, wBuf[R4B14], S4_2, T4_14); + II(b, c, d, a, wBuf[R4B15], S4_3, T4_15); cx->cv[0] += a; cx->cv[1] += b; cx->cv[2] += c; @@ -414,6 +447,7 @@ MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen) { PRUint32 bytesToConsume; PRUint32 inBufIndex = cx->lsbInput & 63; + const PRUint32 *wBuf; /* Add the number of input bytes to the 64-bit input counter. */ addto64(cx->msbInput, cx->lsbInput, inputLen); @@ -421,9 +455,13 @@ MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen) /* There is already data in the buffer. Fill with input. */ bytesToConsume = PR_MIN(inputLen, MD5_BUFFER_SIZE - inBufIndex); memcpy(&cx->inBuf[inBufIndex], input, bytesToConsume); - if (inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE) + if (inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE) { /* The buffer is filled. Run the compression function. */ - md5_compress(cx); +#ifndef IS_LITTLE_ENDIAN + md5_prep_state_le(cx); +#endif + md5_compress(cx, cx->u.w); + } /* Remaining input. */ inputLen -= bytesToConsume; input += bytesToConsume; @@ -431,8 +469,25 @@ MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen) /* Iterate over 64-byte chunks of the message. */ while (inputLen >= MD5_BUFFER_SIZE) { - memcpy(cx->inBuf, input, MD5_BUFFER_SIZE); - md5_compress(cx); +#ifdef IS_LITTLE_ENDIAN +#ifdef _X86_ + /* x86 can handle arithmetic on non-word-aligned buffers */ + wBuf = (PRUint32 *)input; +#else + if ((ptrdiff_t)input & 0x3) { + /* buffer not aligned, copy it to force alignment */ + memcpy(cx->inBuf, input, MD5_BUFFER_SIZE); + wBuf = cx->u.w; + } else { + /* buffer is aligned */ + wBuf = (PRUint32 *)input; + } +#endif +#else + md5_prep_buffer_le(cx, input); + wBuf = cx->u.w; +#endif + md5_compress(cx, wBuf); inputLen -= MD5_BUFFER_SIZE; input += MD5_BUFFER_SIZE; } @@ -487,7 +542,10 @@ MD5_End(MD5Context *cx, unsigned char *digest, cx->u.w[15] = lendian(highInput); /* Final call to compress. */ - md5_compress(cx); +#ifndef IS_LITTLE_ENDIAN + md5_prep_state_le(cx); +#endif + md5_compress(cx, cx->u.w); /* Copy the resulting values out of the chain variables into return buf. */ *digestLen = MD5_HASH_LEN; diff --git a/security/nss/lib/freebl/prng_fips1861.c b/security/nss/lib/freebl/prng_fips1861.c index 2359913fd..0f7d90a78 100644 --- a/security/nss/lib/freebl/prng_fips1861.c +++ b/security/nss/lib/freebl/prng_fips1861.c @@ -166,8 +166,6 @@ alg_fips186_1_x3_1(RNGContext *rng, PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } - /* initialize the SHA1 context */ - memset(&sha1cx, 0, sizeof(sha1cx)); /* * <Step 2> Initialize t, taken care of in SHA-1 (same initial values) */ diff --git a/security/nss/lib/freebl/rijndael.c b/security/nss/lib/freebl/rijndael.c index f59cd6c99..1a5857c48 100644 --- a/security/nss/lib/freebl/rijndael.c +++ b/security/nss/lib/freebl/rijndael.c @@ -282,16 +282,17 @@ rijndael_invkey_expansion(AESContext *cx, unsigned char *key, unsigned int Nk) #define BYTE3WORD(w) ((w) & 0x000000ff) #endif -#define COLUMN_0(array) *((PRUint32 *)(array )) -#define COLUMN_1(array) *((PRUint32 *)(array + 4)) -#define COLUMN_2(array) *((PRUint32 *)(array + 8)) -#define COLUMN_3(array) *((PRUint32 *)(array + 12)) -#define COLUMN_4(array) *((PRUint32 *)(array + 16)) -#define COLUMN_5(array) *((PRUint32 *)(array + 20)) -#define COLUMN_6(array) *((PRUint32 *)(array + 24)) -#define COLUMN_7(array) *((PRUint32 *)(array + 28)) +typedef union { + PRUint32 w[4]; + PRUint8 b[16]; +} rijndael_state; -#define STATE_BYTE(i) clone[i] +#define COLUMN_0(state) state.w[0] +#define COLUMN_1(state) state.w[1] +#define COLUMN_2(state) state.w[2] +#define COLUMN_3(state) state.w[3] + +#define STATE_BYTE(i) state.b[i] static SECStatus rijndael_encryptBlock128(AESContext *cx, @@ -300,61 +301,92 @@ rijndael_encryptBlock128(AESContext *cx, { unsigned int r; PRUint32 *roundkeyw; - PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE]; + rijndael_state state; + PRUint32 C0, C1, C2, C3; +#if defined(_X86_) +#define pIn input +#define pOut output +#else + unsigned char *pIn, *pOut; + PRUint32 inBuf[4], outBuf[4]; + if ((ptrdiff_t)input & 0x3) { + memcpy(inBuf, input, sizeof inBuf); + pIn = (unsigned char *)inBuf; + } else { + pIn = (unsigned char *)input; + } + if ((ptrdiff_t)output & 0x3) { + pOut = (unsigned char *)outBuf; + } else { + pOut = (unsigned char *)output; + } +#endif roundkeyw = cx->expandedKey; /* Step 1: Add Round Key 0 to initial state */ - COLUMN_0(clone) = COLUMN_0(input) ^ *roundkeyw++; - COLUMN_1(clone) = COLUMN_1(input) ^ *roundkeyw++; - COLUMN_2(clone) = COLUMN_2(input) ^ *roundkeyw++; - COLUMN_3(clone) = COLUMN_3(input) ^ *roundkeyw++; + COLUMN_0(state) = *((PRUint32 *)(pIn )) ^ *roundkeyw++; + COLUMN_1(state) = *((PRUint32 *)(pIn + 4 )) ^ *roundkeyw++; + COLUMN_2(state) = *((PRUint32 *)(pIn + 8 )) ^ *roundkeyw++; + COLUMN_3(state) = *((PRUint32 *)(pIn + 12)) ^ *roundkeyw++; /* Step 2: Loop over rounds [1..NR-1] */ for (r=1; r<cx->Nr; ++r) { /* Do ShiftRow, ByteSub, and MixColumn all at once */ - COLUMN_0(output) = T0(STATE_BYTE(0)) ^ - T1(STATE_BYTE(5)) ^ - T2(STATE_BYTE(10)) ^ - T3(STATE_BYTE(15)); - COLUMN_1(output) = T0(STATE_BYTE(4)) ^ - T1(STATE_BYTE(9)) ^ - T2(STATE_BYTE(14)) ^ - T3(STATE_BYTE(3)); - COLUMN_2(output) = T0(STATE_BYTE(8)) ^ - T1(STATE_BYTE(13)) ^ - T2(STATE_BYTE(2)) ^ - T3(STATE_BYTE(7)); - COLUMN_3(output) = T0(STATE_BYTE(12)) ^ - T1(STATE_BYTE(1)) ^ - T2(STATE_BYTE(6)) ^ - T3(STATE_BYTE(11)); + C0 = T0(STATE_BYTE(0)) ^ + T1(STATE_BYTE(5)) ^ + T2(STATE_BYTE(10)) ^ + T3(STATE_BYTE(15)); + C1 = T0(STATE_BYTE(4)) ^ + T1(STATE_BYTE(9)) ^ + T2(STATE_BYTE(14)) ^ + T3(STATE_BYTE(3)); + C2 = T0(STATE_BYTE(8)) ^ + T1(STATE_BYTE(13)) ^ + T2(STATE_BYTE(2)) ^ + T3(STATE_BYTE(7)); + C3 = T0(STATE_BYTE(12)) ^ + T1(STATE_BYTE(1)) ^ + T2(STATE_BYTE(6)) ^ + T3(STATE_BYTE(11)); /* Round key addition */ - COLUMN_0(clone) = COLUMN_0(output) ^ *roundkeyw++; - COLUMN_1(clone) = COLUMN_1(output) ^ *roundkeyw++; - COLUMN_2(clone) = COLUMN_2(output) ^ *roundkeyw++; - COLUMN_3(clone) = COLUMN_3(output) ^ *roundkeyw++; + COLUMN_0(state) = C0 ^ *roundkeyw++; + COLUMN_1(state) = C1 ^ *roundkeyw++; + COLUMN_2(state) = C2 ^ *roundkeyw++; + COLUMN_3(state) = C3 ^ *roundkeyw++; } /* Step 3: Do the last round */ /* Final round does not employ MixColumn */ - COLUMN_0(output) = ((BYTE0WORD(T2(STATE_BYTE(0)))) | - (BYTE1WORD(T3(STATE_BYTE(5)))) | - (BYTE2WORD(T0(STATE_BYTE(10)))) | - (BYTE3WORD(T1(STATE_BYTE(15))))) ^ - *roundkeyw++; - COLUMN_1(output) = ((BYTE0WORD(T2(STATE_BYTE(4)))) | - (BYTE1WORD(T3(STATE_BYTE(9)))) | - (BYTE2WORD(T0(STATE_BYTE(14)))) | - (BYTE3WORD(T1(STATE_BYTE(3))))) ^ - *roundkeyw++; - COLUMN_2(output) = ((BYTE0WORD(T2(STATE_BYTE(8)))) | - (BYTE1WORD(T3(STATE_BYTE(13)))) | - (BYTE2WORD(T0(STATE_BYTE(2)))) | - (BYTE3WORD(T1(STATE_BYTE(7))))) ^ - *roundkeyw++; - COLUMN_3(output) = ((BYTE0WORD(T2(STATE_BYTE(12)))) | - (BYTE1WORD(T3(STATE_BYTE(1)))) | - (BYTE2WORD(T0(STATE_BYTE(6)))) | - (BYTE3WORD(T1(STATE_BYTE(11))))) ^ - *roundkeyw++; + C0 = ((BYTE0WORD(T2(STATE_BYTE(0)))) | + (BYTE1WORD(T3(STATE_BYTE(5)))) | + (BYTE2WORD(T0(STATE_BYTE(10)))) | + (BYTE3WORD(T1(STATE_BYTE(15))))) ^ + *roundkeyw++; + C1 = ((BYTE0WORD(T2(STATE_BYTE(4)))) | + (BYTE1WORD(T3(STATE_BYTE(9)))) | + (BYTE2WORD(T0(STATE_BYTE(14)))) | + (BYTE3WORD(T1(STATE_BYTE(3))))) ^ + *roundkeyw++; + C2 = ((BYTE0WORD(T2(STATE_BYTE(8)))) | + (BYTE1WORD(T3(STATE_BYTE(13)))) | + (BYTE2WORD(T0(STATE_BYTE(2)))) | + (BYTE3WORD(T1(STATE_BYTE(7))))) ^ + *roundkeyw++; + C3 = ((BYTE0WORD(T2(STATE_BYTE(12)))) | + (BYTE1WORD(T3(STATE_BYTE(1)))) | + (BYTE2WORD(T0(STATE_BYTE(6)))) | + (BYTE3WORD(T1(STATE_BYTE(11))))) ^ + *roundkeyw++; + *((PRUint32 *) pOut ) = C0; + *((PRUint32 *)(pOut + 4)) = C1; + *((PRUint32 *)(pOut + 8)) = C2; + *((PRUint32 *)(pOut + 12)) = C3; +#if defined(_X86_) +#undef pIn +#undef pOut +#else + if ((ptrdiff_t)output & 0x3) { + memcpy(output, outBuf, sizeof outBuf); + } +#endif return SECSuccess; } @@ -365,61 +397,88 @@ rijndael_decryptBlock128(AESContext *cx, { int r; PRUint32 *roundkeyw; - PRUint8 clone[RIJNDAEL_MAX_STATE_SIZE]; + rijndael_state state; + PRUint32 C0, C1, C2, C3; +#if defined(_X86_) +#define pIn input +#define pOut output +#else + unsigned char *pIn, *pOut; + PRUint32 inBuf[4], outBuf[4]; + if ((ptrdiff_t)input & 0x3) { + memcpy(inBuf, input, sizeof inBuf); + pIn = (unsigned char *)inBuf; + } else { + pIn = (unsigned char *)input; + } + if ((ptrdiff_t)output & 0x3) { + pOut = (unsigned char *)outBuf; + } else { + pOut = (unsigned char *)output; + } +#endif roundkeyw = cx->expandedKey + cx->Nb * cx->Nr + 3; /* reverse the final key addition */ - COLUMN_3(clone) = COLUMN_3(input) ^ *roundkeyw--; - COLUMN_2(clone) = COLUMN_2(input) ^ *roundkeyw--; - COLUMN_1(clone) = COLUMN_1(input) ^ *roundkeyw--; - COLUMN_0(clone) = COLUMN_0(input) ^ *roundkeyw--; + COLUMN_3(state) = *((PRUint32 *)(pIn + 12)) ^ *roundkeyw--; + COLUMN_2(state) = *((PRUint32 *)(pIn + 8)) ^ *roundkeyw--; + COLUMN_1(state) = *((PRUint32 *)(pIn + 4)) ^ *roundkeyw--; + COLUMN_0(state) = *((PRUint32 *)(pIn )) ^ *roundkeyw--; /* Loop over rounds in reverse [NR..1] */ for (r=cx->Nr; r>1; --r) { /* Invert the (InvByteSub*InvMixColumn)(InvShiftRow(state)) */ - COLUMN_0(output) = TInv0(STATE_BYTE(0)) ^ - TInv1(STATE_BYTE(13)) ^ - TInv2(STATE_BYTE(10)) ^ - TInv3(STATE_BYTE(7)); - COLUMN_1(output) = TInv0(STATE_BYTE(4)) ^ - TInv1(STATE_BYTE(1)) ^ - TInv2(STATE_BYTE(14)) ^ - TInv3(STATE_BYTE(11)); - COLUMN_2(output) = TInv0(STATE_BYTE(8)) ^ - TInv1(STATE_BYTE(5)) ^ - TInv2(STATE_BYTE(2)) ^ - TInv3(STATE_BYTE(15)); - COLUMN_3(output) = TInv0(STATE_BYTE(12)) ^ - TInv1(STATE_BYTE(9)) ^ - TInv2(STATE_BYTE(6)) ^ - TInv3(STATE_BYTE(3)); + C0 = TInv0(STATE_BYTE(0)) ^ + TInv1(STATE_BYTE(13)) ^ + TInv2(STATE_BYTE(10)) ^ + TInv3(STATE_BYTE(7)); + C1 = TInv0(STATE_BYTE(4)) ^ + TInv1(STATE_BYTE(1)) ^ + TInv2(STATE_BYTE(14)) ^ + TInv3(STATE_BYTE(11)); + C2 = TInv0(STATE_BYTE(8)) ^ + TInv1(STATE_BYTE(5)) ^ + TInv2(STATE_BYTE(2)) ^ + TInv3(STATE_BYTE(15)); + C3 = TInv0(STATE_BYTE(12)) ^ + TInv1(STATE_BYTE(9)) ^ + TInv2(STATE_BYTE(6)) ^ + TInv3(STATE_BYTE(3)); /* Invert the key addition step */ - COLUMN_3(clone) = COLUMN_3(output) ^ *roundkeyw--; - COLUMN_2(clone) = COLUMN_2(output) ^ *roundkeyw--; - COLUMN_1(clone) = COLUMN_1(output) ^ *roundkeyw--; - COLUMN_0(clone) = COLUMN_0(output) ^ *roundkeyw--; + COLUMN_3(state) = C3 ^ *roundkeyw--; + COLUMN_2(state) = C2 ^ *roundkeyw--; + COLUMN_1(state) = C1 ^ *roundkeyw--; + COLUMN_0(state) = C0 ^ *roundkeyw--; } /* inverse sub */ - output[ 0] = SBOXINV(clone[ 0]); - output[ 1] = SBOXINV(clone[13]); - output[ 2] = SBOXINV(clone[10]); - output[ 3] = SBOXINV(clone[ 7]); - output[ 4] = SBOXINV(clone[ 4]); - output[ 5] = SBOXINV(clone[ 1]); - output[ 6] = SBOXINV(clone[14]); - output[ 7] = SBOXINV(clone[11]); - output[ 8] = SBOXINV(clone[ 8]); - output[ 9] = SBOXINV(clone[ 5]); - output[10] = SBOXINV(clone[ 2]); - output[11] = SBOXINV(clone[15]); - output[12] = SBOXINV(clone[12]); - output[13] = SBOXINV(clone[ 9]); - output[14] = SBOXINV(clone[ 6]); - output[15] = SBOXINV(clone[ 3]); + pOut[ 0] = SBOXINV(STATE_BYTE( 0)); + pOut[ 1] = SBOXINV(STATE_BYTE(13)); + pOut[ 2] = SBOXINV(STATE_BYTE(10)); + pOut[ 3] = SBOXINV(STATE_BYTE( 7)); + pOut[ 4] = SBOXINV(STATE_BYTE( 4)); + pOut[ 5] = SBOXINV(STATE_BYTE( 1)); + pOut[ 6] = SBOXINV(STATE_BYTE(14)); + pOut[ 7] = SBOXINV(STATE_BYTE(11)); + pOut[ 8] = SBOXINV(STATE_BYTE( 8)); + pOut[ 9] = SBOXINV(STATE_BYTE( 5)); + pOut[10] = SBOXINV(STATE_BYTE( 2)); + pOut[11] = SBOXINV(STATE_BYTE(15)); + pOut[12] = SBOXINV(STATE_BYTE(12)); + pOut[13] = SBOXINV(STATE_BYTE( 9)); + pOut[14] = SBOXINV(STATE_BYTE( 6)); + pOut[15] = SBOXINV(STATE_BYTE( 3)); /* final key addition */ - COLUMN_3(output) ^= *roundkeyw--; - COLUMN_2(output) ^= *roundkeyw--; - COLUMN_1(output) ^= *roundkeyw--; - COLUMN_0(output) ^= *roundkeyw--; + *((PRUint32 *)(pOut + 12)) ^= *roundkeyw--; + *((PRUint32 *)(pOut + 8)) ^= *roundkeyw--; + *((PRUint32 *)(pOut + 4)) ^= *roundkeyw--; + *((PRUint32 *) pOut ) ^= *roundkeyw--; +#if defined(_X86_) +#undef pIn +#undef pOut +#else + if ((ptrdiff_t)output & 0x3) { + memcpy(output, outBuf, sizeof outBuf); + } +#endif return SECSuccess; } @@ -441,6 +500,8 @@ rijndael_encryptBlock(AESContext *cx, unsigned char *output, const unsigned char *input) { + return SECFailure; +#ifdef rijndael_large_blocks_fixed unsigned int j, r, Nb; unsigned int c2, c3; PRUint32 *roundkeyw; @@ -473,6 +534,7 @@ rijndael_encryptBlock(AESContext *cx, *roundkeyw++; } return SECSuccess; +#endif } SECStatus @@ -480,6 +542,8 @@ rijndael_decryptBlock(AESContext *cx, unsigned char *output, const unsigned char *input) { + return SECFailure; +#ifdef rijndael_large_blocks_fixed int j, r, Nb; int c2, c3; PRUint32 *roundkeyw; @@ -513,6 +577,7 @@ rijndael_decryptBlock(AESContext *cx, COLUMN(output, j) ^= *roundkeyw--; } return SECSuccess; +#endif } /************************************************************************** diff --git a/security/nss/lib/freebl/rsa.c b/security/nss/lib/freebl/rsa.c index cbbee0b36..588cfa6ec 100644 --- a/security/nss/lib/freebl/rsa.c +++ b/security/nss/lib/freebl/rsa.c @@ -761,11 +761,13 @@ swap_in_key_value(PRArenaPool *arena, mp_int *mpval, SECItem *buffer) if ((unsigned int)len <= buffer->len) { /* The new value is no longer than the old buffer, so use it */ err = mp_to_unsigned_octets(mpval, buffer->data, len); + if (err >= 0) err = MP_OKAY; buffer->len = len; } else if (arena) { /* The new value is longer, but working within an arena */ (void)SECITEM_AllocItem(arena, buffer, len); err = mp_to_unsigned_octets(mpval, buffer->data, len); + if (err >= 0) err = MP_OKAY; } else { /* The new value is longer, no arena, can't handle this key */ return SECFailure; @@ -812,6 +814,7 @@ RSA_PrivateKeyCheck(RSAPrivateKey *key) /* mind the p's and q's (and d_p's and d_q's) */ SECItem tmp; mp_exch(&p, &q); + mp_exch(&d_p,&d_q); tmp = key->prime1; key->prime1 = key->prime2; key->prime2 = tmp; diff --git a/security/nss/lib/freebl/sha_fast.c b/security/nss/lib/freebl/sha_fast.c index 655f5c3e6..612e3d1ab 100644 --- a/security/nss/lib/freebl/sha_fast.c +++ b/security/nss/lib/freebl/sha_fast.c @@ -325,7 +325,8 @@ SHA1_NewContext(void) { SHA1Context *cx; - cx = PORT_ZNew(SHA1Context); + /* no need to ZNew, _Begin will init the context */ + cx = PORT_New(SHA1Context); return cx; } diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c index e8c9ab925..849e33bb0 100644 --- a/security/nss/lib/nss/nssinit.c +++ b/security/nss/lib/nss/nssinit.c @@ -72,6 +72,9 @@ nss_certdb_name_cb(void *arg, int dbVersion) const char *dbver; switch (dbVersion) { + case 8: + dbver = "8"; + break; case 7: dbver = "7"; break; @@ -155,8 +158,10 @@ nss_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly) if (name == NULL) return SECFailure; keydb = SECKEY_OpenKeyDB(readOnly, nss_keydb_name_cb, (void *)name); - if (keydb == NULL) + if (keydb == NULL) { + PORT_Free(name); return SECFailure; + } SECKEY_SetDefaultKeyDB(keydb); PORT_Free(name); return SECSuccess; @@ -215,6 +220,8 @@ nss_OpenVolatileSecModDB() { return rv; } +extern SECStatus secoid_Init(void); + /* * OK there are now lots of options here, lets go through them all: * @@ -248,6 +255,10 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, if (status != SECSuccess) goto loser; RNG_SystemInfoForRNG(); + + if (secoid_Init() != SECSuccess) { + goto loser; + } if (noCertDB) { status = nss_OpenVolatileCertDB(); @@ -355,6 +366,10 @@ NSS_NoDB_Init(const char * configdir) return rv; } RNG_SystemInfoForRNG(); + + if (secoid_Init() != SECSuccess) { + return rv; + } rv = nss_OpenVolatileCertDB(); if (rv != SECSuccess) { diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c index d52df806d..47f6ca5b5 100644 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ b/security/nss/lib/pk11wrap/pk11skey.c @@ -54,6 +54,8 @@ #define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */ #define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */ +static const SECItem pk11_null_params = { 0 }; + /* forward static declarations. */ static PK11SymKey *pk11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive, SECItem *param, CK_MECHANISM_TYPE target, @@ -180,11 +182,6 @@ pk11_getKeyFromList(PK11SlotInfo *slot) { if (symKey == NULL) { return NULL; } - symKey->refLock = PZ_NewLock(nssILockRefLock); - if (symKey->refLock == NULL) { - PORT_Free(symKey); - return NULL; - } symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner); symKey->next = NULL; return symKey; @@ -199,7 +196,6 @@ PK11_CleanKeyList(PK11SlotInfo *slot) symKey = slot->freeSymKeysHead; slot->freeSymKeysHead = symKey->next; pk11_CloseSession(slot, symKey->session,symKey->sessionOwner); - PK11_USE_THREADS(PZ_DestroyLock(symKey->refLock);) PORT_Free(symKey); }; return; @@ -243,17 +239,15 @@ PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx) void PK11_FreeSymKey(PK11SymKey *symKey) { - PRBool destroy = PR_FALSE; PK11SlotInfo *slot; PRBool freeit = PR_TRUE; - PK11_USE_THREADS(PZ_Lock(symKey->refLock);) - if (symKey->refCount-- == 1) { - destroy= PR_TRUE; - } - PK11_USE_THREADS(PZ_Unlock(symKey->refLock);) - if (destroy) { + if (PR_AtomicDecrement(&symKey->refCount) == 0) { +#if 0 if ((symKey->owner) && symKey->objectID != CK_INVALID_KEY) { +#else + if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) { +#endif pk11_EnterKeyMonitor(symKey); (void) PK11_GETTAB(symKey->slot)-> C_DestroyObject(symKey->session, symKey->objectID); @@ -276,7 +270,6 @@ PK11_FreeSymKey(PK11SymKey *symKey) if (freeit) { pk11_CloseSession(symKey->slot, symKey->session, symKey->sessionOwner); - PK11_USE_THREADS(PZ_DestroyLock(symKey->refLock);) PORT_Free(symKey); } PK11_FreeSlot(slot); @@ -286,9 +279,7 @@ PK11_FreeSymKey(PK11SymKey *symKey) PK11SymKey * PK11_ReferenceSymKey(PK11SymKey *symKey) { - PK11_USE_THREADS(PZ_Lock(symKey->refLock);) - symKey->refCount++; - PK11_USE_THREADS(PZ_Unlock(symKey->refLock);) + PR_AtomicIncrement(&symKey->refCount); return symKey; } @@ -3171,7 +3162,8 @@ PK11_DestroyContext(PK11Context *context, PRBool freeit) /* initialize the critical fields of the context */ if (context->savedData != NULL ) PORT_Free(context->savedData); if (context->key) PK11_FreeSymKey(context->key); - if (context->param) SECITEM_FreeItem(context->param, PR_TRUE); + if (context->param && context->param != &pk11_null_params) + SECITEM_FreeItem(context->param, PR_TRUE); if (context->sessionLock) PZ_DestroyLock(context->sessionLock); PK11_FreeSlot(context->slot); if (freeit) PORT_Free(context); @@ -3180,46 +3172,46 @@ PK11_DestroyContext(PK11Context *context, PRBool freeit) /* * save the current context. Allocate Space if necessary. */ -static void * -pk11_saveContextHelper(PK11Context *context, void *space, - unsigned long *savedLength, PRBool staticBuffer, PRBool recurse) +static unsigned char * +pk11_saveContextHelper(PK11Context *context, unsigned char *buffer, + unsigned long *savedLength) { - CK_ULONG length; CK_RV crv; - if (staticBuffer) PORT_Assert(space != NULL); - - if (space == NULL) { - crv =PK11_GETTAB(context->slot)->C_GetOperationState(context->session, - NULL,&length); + /* If buffer is NULL, this will get the length */ + crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session, + (CK_BYTE_PTR)buffer, + savedLength); + if (!buffer || (crv == CKR_BUFFER_TOO_SMALL)) { + /* the given buffer wasn't big enough (or was NULL), but we + * have the length, so try again with a new buffer and the + * correct length + */ + unsigned long bufLen = *savedLength; + buffer = PORT_Alloc(bufLen); + if (buffer == NULL) { + return (unsigned char *)NULL; + } + crv = PK11_GETTAB(context->slot)->C_GetOperationState( + context->session, + (CK_BYTE_PTR)buffer, + savedLength); if (crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return NULL; + PORT_ZFree(buffer, bufLen); } - space = PORT_Alloc(length); - if (space == NULL) return NULL; - *savedLength = length; - } - crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session, - (CK_BYTE_PTR)space,savedLength); - if (!staticBuffer && !recurse && (crv == CKR_BUFFER_TOO_SMALL)) { - if (!staticBuffer) PORT_Free(space); - return pk11_saveContextHelper(context, NULL, - savedLength, PR_FALSE, PR_TRUE); } if (crv != CKR_OK) { - if (!staticBuffer) PORT_Free(space); PORT_SetError( PK11_MapError(crv) ); - return NULL; + return (unsigned char *)NULL; } - return space; + return buffer; } void * pk11_saveContext(PK11Context *context, void *space, unsigned long *savedLength) { - return pk11_saveContextHelper(context, space, - savedLength, PR_FALSE, PR_FALSE); + return pk11_saveContextHelper(context, + (unsigned char *)space, savedLength); } /* @@ -3359,7 +3351,15 @@ static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type, /* save the parameters so that some digesting stuff can do multiple * begins on a single context */ context->type = type; - context->param = SECITEM_DupItem(param); + if (param) { + if (param->len > 0) { + context->param = SECITEM_DupItem(param); + } else { + context->param = (SECItem *)&pk11_null_params; + } + } else { + context->param = NULL; + } context->init = PR_FALSE; context->sessionLock = PZ_NewLock(nssILockPK11cxt); if ((context->param == NULL) || (context->sessionLock == NULL)) { @@ -3557,8 +3557,7 @@ PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength) if (cx->ownSession) { PK11_EnterContextMonitor(cx); - data = (unsigned char*)pk11_saveContextHelper(cx,save,&length, - PR_FALSE,PR_FALSE); + data = pk11_saveContextHelper(cx, save, &length); PK11_ExitContextMonitor(cx); if (data) *len = length; } else if (saveLength >= cx->savedLength) { @@ -3568,7 +3567,14 @@ PK11_SaveContext(PK11Context *cx,unsigned char *save,int *len, int saveLength) } *len = cx->savedLength; } - return (data != NULL) ? SECSuccess : SECFailure; + if (data != NULL) { + if (cx->ownSession) { + PORT_ZFree(data, length); + } + return SECSuccess; + } else { + return SECFailure; + } } /* @@ -3945,31 +3951,34 @@ pk11_Finalize(PK11Context *context) { CK_ULONG count = 0; CK_RV crv; + unsigned char stackBuf[256]; + unsigned char *buffer = NULL; if (!context->ownSession) { return SECSuccess; } +finalize: switch (context->operation) { case CKA_ENCRYPT: crv=PK11_GETTAB(context->slot)->C_EncryptFinal(context->session, - NULL,&count); + buffer, &count); break; case CKA_DECRYPT: crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session, - NULL,&count); + buffer, &count); break; case CKA_SIGN: crv=PK11_GETTAB(context->slot)->C_SignFinal(context->session, - NULL,&count); + buffer, &count); break; case CKA_VERIFY: crv=PK11_GETTAB(context->slot)->C_VerifyFinal(context->session, - NULL,count); + buffer, count); break; case CKA_DIGEST: crv=PK11_GETTAB(context->slot)->C_DigestFinal(context->session, - NULL,&count); + buffer, &count); break; default: crv = CKR_OPERATION_NOT_INITIALIZED; @@ -3977,9 +3986,23 @@ pk11_Finalize(PK11Context *context) } if (crv != CKR_OK) { + if (crv == CKR_OPERATION_NOT_INITIALIZED) { + /* if there's no operation, it is finalized */ + return SECSuccess; + } PORT_SetError( PK11_MapError(crv) ); return SECFailure; } + + /* try to finalize the session with a buffer */ + if (buffer == NULL && count > 0) { + if (count < sizeof stackBuf) { + buffer = stackBuf; + goto finalize; + } else { + return SECFailure; + } + } return SECSuccess; } diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index 5abb593c9..c613c01cb 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -51,6 +51,7 @@ #include "secerr.h" #define NSSCKT_H /* we included pkcs11t.h, so block ckt.h from including nssckt.h */ #include "ckt.h" +#include "pratom.h" /************************************************************* @@ -382,27 +383,19 @@ PK11_NewSlotInfo(void) if (slot == NULL) return slot; #ifdef PKCS11_USE_THREADS - slot->refLock = PZ_NewLock(nssILockSlot); - if (slot->refLock == NULL) { - PORT_Free(slot); - return slot; - } slot->sessionLock = PZ_NewLock(nssILockSession); if (slot->sessionLock == NULL) { - PZ_DestroyLock(slot->refLock); PORT_Free(slot); return slot; } slot->freeListLock = PZ_NewLock(nssILockFreelist); if (slot->freeListLock == NULL) { PZ_DestroyLock(slot->sessionLock); - PZ_DestroyLock(slot->refLock); PORT_Free(slot); return slot; } #else slot->sessionLock = NULL; - slot->refLock = NULL; slot->freeListLock = NULL; #endif slot->freeSymKeysHead = NULL; @@ -451,9 +444,7 @@ PK11_NewSlotInfo(void) PK11SlotInfo * PK11_ReferenceSlot(PK11SlotInfo *slot) { - PK11_USE_THREADS(PZ_Lock(slot->refLock);) - slot->refCount++; - PK11_USE_THREADS(PZ_Unlock(slot->refLock);) + PR_AtomicIncrement(&slot->refCount); return slot; } @@ -472,15 +463,15 @@ PK11_DestroySlot(PK11SlotInfo *slot) /* free up the cached keys and sessions */ PK11_CleanKeyList(slot); + if (slot->mechanismList) { + PORT_Free(slot->mechanismList); + } + /* finally Tell our parent module that we've gone away so it can unload */ if (slot->module) { SECMOD_SlotDestroyModule(slot->module,PR_TRUE); } #ifdef PKCS11_USE_THREADS - if (slot->refLock) { - PZ_DestroyLock(slot->refLock); - slot->refLock = NULL; - } if (slot->sessionLock) { PZ_DestroyLock(slot->sessionLock); slot->sessionLock = NULL; @@ -500,13 +491,9 @@ PK11_DestroySlot(PK11SlotInfo *slot) void PK11_FreeSlot(PK11SlotInfo *slot) { - PRBool freeit = PR_FALSE; - - PK11_USE_THREADS(PZ_Lock(slot->refLock);) - if (slot->refCount-- == 1) freeit = PR_TRUE; - PK11_USE_THREADS(PZ_Unlock(slot->refLock);) - - if (freeit) PK11_DestroySlot(slot); + if (PR_AtomicDecrement(&slot->refCount) == 0) { + PK11_DestroySlot(slot); + } } void @@ -3650,10 +3637,10 @@ PK11_GenerateRandom(unsigned char *data,int len) { slot = PK11_GetBestSlot(CKM_FAKE_RANDOM,NULL); if (slot == NULL) return SECFailure; - PK11_EnterSlotMonitor(slot); + if (!slot->isInternal) PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_GenerateRandom(slot->session,data, (CK_ULONG)len); - PK11_ExitSlotMonitor(slot); + if (!slot->isInternal) PK11_ExitSlotMonitor(slot); PK11_FreeSlot(slot); return (crv != CKR_OK) ? SECFailure : SECSuccess; } diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h index 43d95c750..ea13cd82f 100644 --- a/security/nss/lib/pk11wrap/secmodti.h +++ b/security/nss/lib/pk11wrap/secmodti.h @@ -81,8 +81,7 @@ struct PK11SlotInfoStr { unsigned long defaultFlags; /* keep track of who is using us so we don't accidently get freed while * still in use */ - int refCount; - PZLock *refLock; + PRInt32 refCount; /* to be in/decremented by atomic calls ONLY! */ PZLock *freeListLock; PK11SymKey *freeSymKeysHead; int keyCount; @@ -144,8 +143,7 @@ struct PK11SymKeyStr { SECItem data; /* raw key data if available */ CK_SESSION_HANDLE session; PRBool sessionOwner; - int refCount; /* number of references to this key */ - PZLock *refLock; + PRInt32 refCount; /* number of references to this key */ int size; /* key size in bytes */ PK11Origin origin; /* where this key came from (see def in secmodt.h) */ diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c index ced36fb2d..a6d10b85a 100644 --- a/security/nss/lib/pkcs7/p7decode.c +++ b/security/nss/lib/pkcs7/p7decode.c @@ -280,11 +280,8 @@ sec_pkcs7_decoder_start_digests (SEC_PKCS7DecoderContext *p7dcx, int depth, /* * No algorithms means no work to do. - * This is not expected, so cause an assert. - * But if it does happen, just act as if there were - * no algorithms specified. + * Just act as if there were no algorithms specified. */ - PORT_Assert (digcnt != 0); if (digcnt == 0) return SECSuccess; diff --git a/security/nss/lib/softoken/alghmac.c b/security/nss/lib/softoken/alghmac.c index aef81a76b..1d877644b 100644 --- a/security/nss/lib/softoken/alghmac.c +++ b/security/nss/lib/softoken/alghmac.c @@ -56,6 +56,12 @@ HMAC_Destroy(HMACContext *cx) PORT_ZFree(cx, sizeof(HMACContext)); } +int +HMAC_GetLength(HMACContext *cx) +{ + return cx->hashobj->length; +} + HMACContext * HMAC_Create(SECOidTag hash_alg, const unsigned char *secret, diff --git a/security/nss/lib/softoken/alghmac.h b/security/nss/lib/softoken/alghmac.h index 10d598267..3edd7df8f 100644 --- a/security/nss/lib/softoken/alghmac.h +++ b/security/nss/lib/softoken/alghmac.h @@ -85,6 +85,9 @@ HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len, extern HMACContext * HMAC_Clone(HMACContext *cx); +extern int +HMAC_GetLength(HMACContext *cx); + SEC_END_PROTOS #endif diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 0c88cca85..9c123bd0b 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -1956,9 +1956,7 @@ SECKEYLowPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type) pubKey->keyType = rsaKey; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.rsa.modulus, object,CKA_MODULUS); - /* This requirement taken from rsa.c */ - if (pubKey->u.rsa.modulus.len == 0 || - SECKEY_LowPublicModulusLen(pubKey) % 16 != 0) + if (pubKey->u.rsa.modulus.len == 0) crv = CKR_ARGUMENTS_BAD; if (crv != CKR_OK) break; crv = pk11_Attribute2SSecItem(arena,&pubKey->u.rsa.publicExponent, @@ -2396,12 +2394,19 @@ PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin) int i; PK11Slot *slot = pk11_SlotFromID(slotID); #ifdef PKCS11_USE_THREADS - slot->sessionLock = PZ_NewLock(nssILockSession); - if (slot->sessionLock == NULL) return CKR_HOST_MEMORY; + slot->slotLock = PZ_NewLock(nssILockSession); + if (slot->slotLock == NULL) return CKR_HOST_MEMORY; + for (i=0; i < NUMBER_OF_SESSION_LOCKS; i++) { + slot->sessionLock[i] = PZ_NewLock(nssILockSession); + if (slot->sessionLock[i] == NULL) return CKR_HOST_MEMORY; + } slot->objectLock = PZ_NewLock(nssILockObject); if (slot->objectLock == NULL) return CKR_HOST_MEMORY; #else - slot->sessionLock = NULL; + slot->slotLock = NULL; + for (i=0; i < NUMBER_OF_SESSION_LOCKS; i++) { + slot->sessionLock[i] = NULL; + } slot->objectLock = NULL; #endif for(i=0; i < SESSION_HASH_SIZE; i++) { @@ -2915,11 +2920,17 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, flags | CKF_SERIAL_SESSION); if (session == NULL) return CKR_HOST_MEMORY; - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) if (slotID == NETSCAPE_SLOT_ID && (flags & CKF_RW_SESSION)) { /* NETSCAPE_SLOT_ID is Read ONLY */ session->info.flags &= ~CKF_RW_SESSION; } + PK11_USE_THREADS(PZ_Lock(slot->slotLock);) + ++slot->sessionCount; + PK11_USE_THREADS(PZ_Unlock(slot->slotLock);) + if (session->info.flags & CKF_RW_SESSION) { + PR_AtomicIncrement(&slot->rwSessionCount); + } + do { do { sessionID = (slot->sessionIDCount++ & MAX_SESSION_ID); @@ -2929,6 +2940,7 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, } else if (slotID == FIPS_SLOT_ID) { sessionID |= PK11_FIPS_FLAG; } + PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,sessionID));) pk11queue_find(sameID, sessionID, slot->head, SESSION_HASH_SIZE); if (sameID == NULL) { session->handle = sessionID; @@ -2937,46 +2949,48 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, } else { slot->sessionIDConflict++; /* for debugging */ } + PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,sessionID));) } while (sameID != NULL); - slot->sessionCount++; - if (session->info.flags & CKF_RW_SESSION) { - slot->rwSessionCount++; - } - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) - *phSession = sessionID; return CKR_OK; } - /* NSC_CloseSession closes a session between an application and a token. */ CK_RV NSC_CloseSession(CK_SESSION_HANDLE hSession) { PK11Slot *slot; PK11Session *session; SECItem *pw = NULL; + PRBool sessionFound; session = pk11_SessionFromHandle(hSession); if (session == NULL) return CKR_SESSION_HANDLE_INVALID; slot = pk11_SlotFromSession(session); + sessionFound = PR_FALSE; /* lock */ - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,hSession));) if (pk11queue_is_queued(session,hSession,slot->head,SESSION_HASH_SIZE)) { + sessionFound = PR_TRUE; pk11queue_delete(session,hSession,slot->head,SESSION_HASH_SIZE); session->refCount--; /* can't go to zero while we hold the reference */ - slot->sessionCount--; + PORT_Assert(session->refCount > 0); + } + PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,hSession));) + + if (sessionFound) { + PK11_USE_THREADS(PZ_Lock(slot->slotLock);) + if (--slot->sessionCount == 0) { + pw = slot->password; + slot->isLoggedIn = PR_FALSE; + slot->password = NULL; + } + PK11_USE_THREADS(PZ_Unlock(slot->slotLock);) if (session->info.flags & CKF_RW_SESSION) { - slot->rwSessionCount--; + PR_AtomicDecrement(&slot->rwSessionCount); } } - if (slot->sessionCount == 0) { - pw = slot->password; - slot->isLoggedIn = PR_FALSE; - slot->password = NULL; - } - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) pk11_FreeSession(session); if (pw) SECITEM_ZfreeItem(pw, PR_TRUE); @@ -2996,11 +3010,11 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID) if (slot == NULL) return CKR_SLOT_ID_INVALID; /* first log out the card */ - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(slot->slotLock);) pw = slot->password; slot->isLoggedIn = PR_FALSE; slot->password = NULL; - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Unlock(slot->slotLock);) if (pw) SECITEM_ZfreeItem(pw, PR_TRUE); /* now close all the current sessions */ @@ -3010,7 +3024,7 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID) * will guarrenteed be close, and no session will be partially closed */ for (i=0; i < SESSION_HASH_SIZE; i++) { do { - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,i));) session = slot->head[i]; /* hand deque */ /* this duplicates function of NSC_close session functions, but @@ -3020,12 +3034,16 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID) slot->head[i] = session->next; if (session->next) session->next->prev = NULL; session->next = session->prev = NULL; - slot->sessionCount--; + PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,i));) + PK11_USE_THREADS(PZ_Lock(slot->slotLock);) + --slot->sessionCount; + PK11_USE_THREADS(PZ_Unlock(slot->slotLock);) if (session->info.flags & CKF_RW_SESSION) { - slot->rwSessionCount--; + PR_AtomicDecrement(&slot->rwSessionCount); } + } else { + PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,i));) } - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) if (session) pk11_FreeSession(session); } while (session != NULL); } @@ -3097,12 +3115,12 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, /* should this be a fixed password? */ if (ulPinLen == 0) { SECItem *pw; - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(slot->slotLock);) pw = slot->password; slot->password = NULL; slot->isLoggedIn = PR_TRUE; slot->ssoLoggedIn = (PRBool)(userType == CKU_SO); - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Unlock(slot->slotLock);) pk11_update_all_states(slot); SECITEM_ZfreeItem(pw,PR_TRUE); return CKR_OK; @@ -3122,11 +3140,11 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, if (SECKEY_CheckKeyDBPassword(handle,pin) == SECSuccess) { SECItem *tmp; - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(slot->slotLock);) tmp = slot->password; slot->isLoggedIn = PR_TRUE; slot->password = pin; - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Unlock(slot->slotLock);) if (tmp) SECITEM_ZfreeItem(tmp, PR_TRUE); /* update all sessions */ @@ -3152,12 +3170,12 @@ CK_RV NSC_Logout(CK_SESSION_HANDLE hSession) if (!slot->isLoggedIn) return CKR_USER_NOT_LOGGED_IN; - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(slot->slotLock);) pw = slot->password; slot->isLoggedIn = PR_FALSE; slot->ssoLoggedIn = PR_FALSE; slot->password = NULL; - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Unlock(slot->slotLock);) if (pw) SECITEM_ZfreeItem(pw, PR_TRUE); pk11_update_all_states(slot); diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 31e59f070..b8cb1cfa3 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -499,6 +499,7 @@ pk11_InitGeneric(PK11Session *session,PK11SessionContext **contextPtr, context->hashInfo = NULL; context->doPad = PR_FALSE; context->padDataLength = 0; + context->blockSize = 0; *contextPtr = context; return CKR_OK; @@ -845,12 +846,21 @@ CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession, unsigned int maxout = *pulLastEncryptedPartLen; CK_RV crv; SECStatus rv = SECSuccess; + PRBool contextFinished = PR_TRUE; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_TRUE,&session); if (crv != CKR_OK) return crv; *pulLastEncryptedPartLen = 0; + if (!pLastEncryptedPart) { + /* caller is checking the amount of remaining data */ + if (context->blockSize > 0) { + *pulLastEncryptedPartLen = context->blockSize; + contextFinished = PR_FALSE; /* still have padding to go */ + } + goto finish; + } /* do padding */ if (context->doPad) { @@ -865,9 +875,11 @@ CK_RV NSC_EncryptFinal(CK_SESSION_HANDLE hSession, if (rv == SECSuccess) *pulLastEncryptedPartLen = (CK_ULONG) outlen; } - /* do it */ +finish: + if (contextFinished) { pk11_SetContextByType(session, PK11_ENCRYPT, NULL); pk11_FreeContext(context); + } pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; } @@ -889,6 +901,11 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, crv = pk11_GetContext(hSession,&context,PK11_ENCRYPT,PR_FALSE,&session); if (crv != CKR_OK) return crv; + if (!pEncryptedData) { + *pulEncryptedDataLen = ulDataLen + 2 * context->blockSize; + goto finish; + } + if (context->doPad) { CK_ULONG finalLen; /* padding is fairly complicated, have the update and final @@ -910,8 +927,9 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, rv = (*context->update)(context->cipherInfo, pEncryptedData, &outlen, maxoutlen, pData, ulDataLen); *pulEncryptedDataLen = (CK_ULONG) outlen; - pk11_FreeContext(context); pk11_SetContextByType(session, PK11_ENCRYPT, NULL); + pk11_FreeContext(context); +finish: pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; @@ -1144,7 +1162,7 @@ finish_des: (unsigned char*)att->attrib.pValue, (unsigned char*)pMechanism->pParameter, pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC, - PR_TRUE, att->attrib.ulValueLen,16); + PR_FALSE, att->attrib.ulValueLen,16); pk11_FreeAttribute(att); if (context->cipherInfo == NULL) { crv = CKR_HOST_MEMORY; @@ -1227,12 +1245,22 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, unsigned int maxout = *pulLastPartLen; CK_RV crv; SECStatus rv = SECSuccess; + PRBool contextFinished = PR_TRUE; /* make sure we're legal */ crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_TRUE,&session); if (crv != CKR_OK) return crv; *pulLastPartLen = 0; + if (!pLastPart) { + /* caller is checking the amount of remaining data */ + if (context->padDataLength > 0) { + *pulLastPartLen = 2 * context->blockSize; + contextFinished = PR_FALSE; /* still have padding to go */ + } + goto finish; + } + if (context->doPad) { /* decrypt our saved buffer */ if (context->padDataLength != 0) { @@ -1249,9 +1277,11 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, } } - /* do it */ +finish: + if (contextFinished) { pk11_SetContextByType(session, PK11_DECRYPT, NULL); pk11_FreeContext(context); + } pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; } @@ -1273,6 +1303,11 @@ CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession, crv = pk11_GetContext(hSession,&context,PK11_DECRYPT,PR_FALSE,&session); if (crv != CKR_OK) return crv; + if (!pData) { + *pulDataLen = ulEncryptedDataLen + context->blockSize; + goto finish; + } + if (context->doPad) { CK_ULONG finalLen; /* padding is fairly complicated, have the update and final @@ -1292,8 +1327,9 @@ CK_RV NSC_Decrypt(CK_SESSION_HANDLE hSession, rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, pEncryptedData, ulEncryptedDataLen); *pulDataLen = (CK_ULONG) outlen; - pk11_FreeContext(context); pk11_SetContextByType(session, PK11_DECRYPT, NULL); + pk11_FreeContext(context); +finish: pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; } @@ -1336,6 +1372,7 @@ CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession, context->hashUpdate = (PK11Hash) MD2_Update; context->end = (PK11End) MD2_End; context->destroy = (PK11Destroy) MD2_DestroyContext; + context->maxLen = MD2_LENGTH; MD2_Begin(md2_context); break; case CKM_MD5: @@ -1350,6 +1387,7 @@ CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession, context->hashUpdate = (PK11Hash) MD5_Update; context->end = (PK11End) MD5_End; context->destroy = (PK11Destroy) MD5_DestroyContext; + context->maxLen = MD5_LENGTH; MD5_Begin(md5_context); break; case CKM_SHA_1: @@ -1365,6 +1403,7 @@ CK_RV NSC_DigestInit(CK_SESSION_HANDLE hSession, context->end = (PK11End) SHA1_End; context->destroy = (PK11Destroy) SHA1_DestroyContext; SHA1_Begin(sha1_context); + context->maxLen = SHA1_LENGTH; break; default: crv = CKR_MECHANISM_INVALID; @@ -1397,6 +1436,11 @@ CK_RV NSC_Digest(CK_SESSION_HANDLE hSession, crv = pk11_GetContext(hSession,&context,PK11_HASH,PR_FALSE,&session); if (crv != CKR_OK) return crv; + if (pDigest == NULL) { + *pulDigestLen = context->maxLen; + goto finish; + } + /* do it: */ (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen); /* NOTE: this assumes buf size is bigenough for the algorithm */ @@ -1405,6 +1449,7 @@ CK_RV NSC_Digest(CK_SESSION_HANDLE hSession, pk11_SetContextByType(session, PK11_HASH, NULL); pk11_FreeContext(context); +finish: pk11_FreeSession(session); return CKR_OK; } @@ -1443,12 +1488,12 @@ CK_RV NSC_DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest, if (pDigest != NULL) { (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout); *pulDigestLen = digestLen; + pk11_SetContextByType(session, PK11_HASH, NULL); + pk11_FreeContext(context); } else { - *pulDigestLen = 0; + *pulDigestLen = context->maxLen; } - pk11_SetContextByType(session, PK11_HASH, NULL); - pk11_FreeContext(context); pk11_FreeSession(session); return CKR_OK; } @@ -1556,6 +1601,7 @@ pk11_doHMACInit(PK11SessionContext *context,SECOidTag oid, context->destroy = (PK11Destroy) pk11_Space; context->update = (PK11Cipher) pk11_HMACCopy; context->verify = (PK11Verify) pk11_HMACCmp; + context->maxLen = HMAC_GetLength(HMACcontext); HMAC_Begin(HMACcontext); return CKR_OK; } @@ -1676,6 +1722,7 @@ pk11_doSSLMACInit(PK11SessionContext *context,SECOidTag oid, context->destroy = (PK11Destroy) pk11_Space; context->update = (PK11Cipher) pk11_SSLMACSign; context->verify = (PK11Verify) pk11_SSLMACVerify; + context->maxLen = mac_size; return CKR_OK; } @@ -2156,6 +2203,7 @@ finish_rsa: context->destroy = (privKey == key->objectInfo) ? (PK11Destroy)pk11_Null:(PK11Destroy)pk11_FreePrivKey; } + context->maxLen = SECKEY_LowPrivateModulusLen(privKey); break; case CKM_DSA_SHA1: @@ -2177,6 +2225,7 @@ finish_rsa: context->update = (PK11Cipher) nsc_DSA_Sign_Stub; context->destroy = (privKey == key->objectInfo) ? (PK11Destroy) pk11_Null:(PK11Destroy)pk11_FreePrivKey; + context->maxLen = DSA_SIGNATURE_LEN; break; case CKM_MD2_HMAC_GENERAL: @@ -2325,7 +2374,10 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature, crv = pk11_GetContext(hSession,&context,PK11_SIGN,PR_TRUE,&session); if (crv != CKR_OK) return crv; - if (context->hashInfo) { + if (!pSignature) { + *pulSignatureLen = context->maxLen; + goto finish; + } else if (context->hashInfo) { (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf)); rv = (*context->update)(context->cipherInfo, pSignature, &outlen, maxoutlen, tmpbuf, digestLen); @@ -2349,6 +2401,8 @@ CK_RV NSC_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature, pk11_FreeContext(context); pk11_SetContextByType(session, PK11_SIGN, NULL); + +finish: pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; @@ -2372,6 +2426,11 @@ CK_RV NSC_Sign(CK_SESSION_HANDLE hSession, crv = pk11_GetContext(hSession,&context,PK11_SIGN,PR_FALSE,&session); if (crv != CKR_OK) return crv; + if (!pSignature) { + *pulSignatureLen = context->maxLen; + goto finish; + } + /* multi part Signing are completely implemented by SignUpdate and * sign Final */ if (context->multi) { @@ -2387,6 +2446,8 @@ CK_RV NSC_Sign(CK_SESSION_HANDLE hSession, *pulSignatureLen = (CK_ULONG) outlen; pk11_FreeContext(context); pk11_SetContextByType(session, PK11_SIGN, NULL); + +finish: pk11_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; @@ -4425,8 +4486,17 @@ loser: /* * SSL Key generation given pre master secret */ -static char *mixers[] = { "A", "BB", "CCC", "DDDD", "EEEEE", "FFFFFF", "GGGGGGG"}; -#define NUM_MIXERS 7 +#define NUM_MIXERS 9 +static const char * const mixers[NUM_MIXERS] = { + "A", + "BB", + "CCC", + "DDDD", + "EEEEE", + "FFFFFF", + "GGGGGGG", + "HHHHHHHH", + "IIIIIIIII" }; #define SSL3_PMS_LENGTH 48 #define SSL3_MASTER_SECRET_LENGTH 48 @@ -4838,14 +4908,21 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, /* ** client_write_IV[CipherSpec.IV_size] */ - PORT_Memcpy(ssl3_keys_out->pIVClient, &key_block[i], IVSize); - i += IVSize; + if (IVSize > 0) { + PORT_Memcpy(ssl3_keys_out->pIVClient, + &key_block[i], IVSize); + i += IVSize; + } /* ** server_write_IV[CipherSpec.IV_size] */ - PORT_Memcpy(ssl3_keys_out->pIVServer, &key_block[i], IVSize); - i += IVSize; + if (IVSize > 0) { + PORT_Memcpy(ssl3_keys_out->pIVServer, + &key_block[i], IVSize); + i += IVSize; + } + PORT_Assert(i <= sizeof key_block); } else if (!isTLS) { @@ -5329,6 +5406,7 @@ CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession, PK11SessionContext *context; PK11Session *session; CK_RV crv; + CK_ULONG pOSLen = *pulOperationStateLen; /* make sure we're legal */ crv = pk11_GetContext(hSession, &context, PK11_HASH, PR_TRUE, &session); @@ -5339,6 +5417,10 @@ CK_RV NSC_GetOperationState(CK_SESSION_HANDLE hSession, if (pOperationState == NULL) { pk11_FreeSession(session); return CKR_OK; + } else { + if (pOSLen < *pulOperationStateLen) { + return CKR_BUFFER_TOO_SMALL; + } } PORT_Memcpy(pOperationState,&context->type,sizeof(PK11ContextType)); pOperationState += sizeof(PK11ContextType); diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index acce33c29..7709eb1ff 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -85,9 +85,33 @@ typedef void (*PK11Free)(void *); #define ATTRIBUTE_HASH_SIZE 32 #define SESSION_OBJECT_HASH_SIZE 32 #define TOKEN_OBJECT_HASH_SIZE 1024 -#define SESSION_HASH_SIZE 512 #define MAX_KEY_LEN 256 #define MAX_OBJECT_LIST_SIZE 800 +#define SESSION_HASH_SIZE 1024 + +/* + * LOG2_BUCKETS_PER_SESSION_LOCK must be a prime number. + * With SESSION_HASH_SIZE=1024, LOG2 can be 9, 5, 1, or 0. + * With SESSION_HASH_SIZE=4096, LOG2 can be 11, 9, 5, 1, or 0. + * + * HASH_SIZE LOG2_BUCKETS_PER BUCKETS_PER_LOCK NUMBER_OF_BUCKETS + * 1024 9 512 2 + * 1024 5 32 32 + * 1024 1 2 512 + * 1024 0 1 1024 + * 4096 11 2048 2 + * 4096 9 512 8 + * 4096 5 32 128 + * 4096 1 2 2048 + * 4096 0 1 4096 + */ +#define LOG2_BUCKETS_PER_SESSION_LOCK 1 +#define BUCKETS_PER_SESSION_LOCK (1 << (LOG2_BUCKETS_PER_SESSION_LOCK)) +#define NUMBER_OF_SESSION_LOCKS (SESSION_HASH_SIZE/BUCKETS_PER_SESSION_LOCK) +/* NOSPREAD sessionID to hash table index macro has been slower. */ +#if 0 +#define NOSPREAD +#endif /* Value to tell if an attribute is modifiable or not. * NEVER: attribute is only set on creation. @@ -237,7 +261,6 @@ struct PK11SessionStr { PK11Session *prev; CK_SESSION_HANDLE handle; int refCount; - PZLock *refLock; PZLock *objectLock; int objectIDCount; CK_SESSION_INFO info; @@ -256,7 +279,8 @@ struct PK11SessionStr { */ struct PK11SlotStr { CK_SLOT_ID slotID; - PZLock *sessionLock; + PZLock *slotLock; + PZLock *sessionLock[NUMBER_OF_SESSION_LOCKS]; PZLock *objectLock; SECItem *password; PRBool hasTokens; @@ -267,7 +291,7 @@ struct PK11SlotStr { int sessionIDCount; int sessionIDConflict; int sessionCount; - int rwSessionCount; + PRInt32 rwSessionCount; int tokenIDCount; PK11Object *tokObjects[TOKEN_OBJECT_HASH_SIZE]; PK11Session *head[SESSION_HASH_SIZE]; @@ -329,8 +353,12 @@ struct PK11SSLMACInfoStr { #define pk11_SlotFromSession(sp) ((sp)->slot) #define pk11_isToken(id) (((id) & PK11_TOKEN_MASK) == PK11_TOKEN_MAGIC) +/* the session hash multiplier */ +#define SHMULTIPLIER 1791398085 + /* queueing helper macros */ -#define pk11_hash(value,size) ((value) & (size-1))/*size must be a power of 2*/ +#define pk11_hash(value,size) \ + ((PRUint32)((value) * SHMULTIPLIER) & (size-1)) #define pk11queue_add(element,id,head,hash_size) \ { int tmp = pk11_hash(id,hash_size); \ (element)->next = (head)[tmp]; \ @@ -351,6 +379,45 @@ struct PK11SSLMACInfoStr { (element)->next = NULL; \ (element)->prev = NULL; \ +#define pk11queue_init_element(element) \ + (element)->prev = NULL; + +#define pk11queue_add2(element, id, index, head) \ + { \ + (element)->next = (head)[index]; \ + if ((head)[index]) \ + (head)[index]->prev = (element); \ + (head)[index] = (element); \ + } + +#define pk11queue_find2(element, id, index, head) \ + for ( (element) = (head)[index]; \ + (element) != NULL; \ + (element) = (element)->next) { \ + if ((element)->handle == (id)) { break; } \ + } + +#define pk11queue_delete2(element, id, index, head) \ + if ((element)->next) (element)->next->prev = (element)->prev; \ + if ((element)->prev) (element)->prev->next = (element)->next; \ + else (head)[index] = ((element)->next); + +#define pk11queue_clear_deleted_element(element) \ + (element)->next = NULL; \ + (element)->prev = NULL; \ + +/* sessionID (handle) is used to determine session lock bucket */ +#ifdef NOSPREAD +/* NOSPREAD: (ID>>L2LPB) & (perbucket-1) */ +#define PK11_SESSION_LOCK(slot,handle) \ + ((slot)->sessionLock[((handle) >> LOG2_BUCKETS_PER_SESSION_LOCK) \ + & (NUMBER_OF_SESSION_LOCKS-1)]) +#else +/* SPREAD: ID & (perbucket-1) */ +#define PK11_SESSION_LOCK(slot,handle) \ + ((slot)->sessionLock[(handle) & (NUMBER_OF_SESSION_LOCKS-1)]) +#endif + /* expand an attribute & secitem structures out */ #define pk11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen #define pk11_item_expand(ip) (ip)->data,(ip)->len diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index e9dd6f7b3..f0c8e495f 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -827,19 +827,16 @@ pk11_ReferenceObject(PK11Object *object) static PK11Object * pk11_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, PK11Slot *slot) { - PK11Object **head; PZLock *lock; PK11Object *object; + PRUint32 index = pk11_hash(handle, TOKEN_OBJECT_HASH_SIZE); - head = slot->tokObjects; - lock = slot->objectLock; - - PK11_USE_THREADS(PZ_Lock(lock);) - pk11queue_find(object,handle,head,TOKEN_OBJECT_HASH_SIZE); + PK11_USE_THREADS(PZ_Lock(slot->objectLock);) + pk11queue_find2(object, handle, index, slot->tokObjects); if (object) { pk11_ReferenceObject(object); } - PK11_USE_THREADS(PZ_Unlock(lock);) + PK11_USE_THREADS(PZ_Unlock(slot->objectLock);) return(object); } @@ -888,8 +885,10 @@ pk11_FreeObject(PK11Object *object) void pk11_AddSlotObject(PK11Slot *slot, PK11Object *object) { + PRUint32 index = pk11_hash(object->handle, TOKEN_OBJECT_HASH_SIZE); + pk11queue_init_element(object); PK11_USE_THREADS(PZ_Lock(slot->objectLock);) - pk11queue_add(object,object->handle,slot->tokObjects,TOKEN_OBJECT_HASH_SIZE); + pk11queue_add2(object, object->handle, index, slot->tokObjects); PK11_USE_THREADS(PZ_Unlock(slot->objectLock);) } @@ -914,6 +913,7 @@ void pk11_DeleteObject(PK11Session *session, PK11Object *object) { PK11Slot *slot = pk11_SlotFromSession(session); + PRUint32 index = pk11_hash(object->handle, TOKEN_OBJECT_HASH_SIZE); if (object->session) { PK11Session *session = object->session; @@ -922,9 +922,9 @@ pk11_DeleteObject(PK11Session *session, PK11Object *object) PK11_USE_THREADS(PZ_Unlock(session->objectLock);) } PK11_USE_THREADS(PZ_Lock(slot->objectLock);) - pk11queue_delete(object,object->handle,slot->tokObjects, - TOKEN_OBJECT_HASH_SIZE); + pk11queue_delete2(object, object->handle, index, slot->tokObjects); PK11_USE_THREADS(PZ_Unlock(slot->objectLock);) + pk11queue_clear_deleted_element(object); pk11_FreeObject(object); } @@ -1107,11 +1107,11 @@ pk11_update_all_states(PK11Slot *slot) PK11Session *session; for (i=0; i < SESSION_HASH_SIZE; i++) { - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,i));) for (session = slot->head[i]; session; session = session->next) { pk11_update_state(slot,session); } - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,i));) } } @@ -1184,19 +1184,12 @@ pk11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, session->search = NULL; session->objectIDCount = 1; #ifdef PKCS11_USE_THREADS - session->refLock = PZ_NewLock(nssILockRefLock); - if (session->refLock == NULL) { - PORT_Free(session); - return NULL; - } session->objectLock = PZ_NewLock(nssILockObject); if (session->objectLock == NULL) { - PK11_USE_THREADS(PZ_DestroyLock(session->refLock);) PORT_Free(session); return NULL; } #else - session->refLock = NULL; session->objectLock = NULL; #endif session->objects[0] = NULL; @@ -1228,7 +1221,6 @@ pk11_DestroySession(PK11Session *session) pk11_DeleteObject(session,op->parent); } PK11_USE_THREADS(PZ_DestroyLock(session->objectLock);) - PK11_USE_THREADS(PZ_DestroyLock(session->refLock);) if (session->enc_context) { pk11_FreeContext(session->enc_context); } @@ -1255,10 +1247,10 @@ pk11_SessionFromHandle(CK_SESSION_HANDLE handle) PK11Slot *slot = pk11_SlotFromSessionHandle(handle); PK11Session *session; - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,handle));) pk11queue_find(session,handle,slot->head,SESSION_HASH_SIZE); if (session) session->refCount++; - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,handle));) return (session); } @@ -1272,10 +1264,10 @@ pk11_FreeSession(PK11Session *session) PRBool destroy = PR_FALSE; PK11_USE_THREADS(PK11Slot *slot = pk11_SlotFromSession(session);) - PK11_USE_THREADS(PZ_Lock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Lock(PK11_SESSION_LOCK(slot,session->handle));) if (session->refCount == 1) destroy = PR_TRUE; session->refCount--; - PK11_USE_THREADS(PZ_Unlock(slot->sessionLock);) + PK11_USE_THREADS(PZ_Unlock(PK11_SESSION_LOCK(slot,session->handle));) if (destroy) pk11_DestroySession(session); } diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 8c84edeed..614269292 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -93,11 +93,17 @@ static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, */ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { /* cipher_suite policy enabled is_present*/ - { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, - { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, - { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, + { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, + { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { SSL_RSA_WITH_RC4_128_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, @@ -168,6 +174,8 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = { {cipher_des40, calg_des, 8, 5, type_block, 8, 8, kg_export}, {cipher_idea, calg_idea, 16, 16, type_block, 8, 8, kg_strong}, {cipher_fortezza, calg_fortezza, 10, 10, type_block, 24, 8, kg_null}, + {cipher_aes_128, calg_aes, 16, 16, type_block, 16,16, kg_strong}, + {cipher_aes_256, calg_aes, 32, 32, type_block, 16,16, kg_strong}, {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, kg_null}, }; @@ -262,6 +270,22 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = { cipher_fortezza, mac_sha, kea_fortezza}, {SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_fortezza}, +/* New TLS cipher suites */ + {TLS_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_rsa}, + {TLS_DHE_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_dss}, + {TLS_DHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dhe_rsa}, + {TLS_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_rsa}, + {TLS_DHE_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_dss}, + {TLS_DHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dhe_rsa}, +#if 0 + {TLS_DH_DSS_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_dss}, + {TLS_DH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_rsa}, + {TLS_DH_ANON_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_dh_anon}, + {TLS_DH_DSS_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_dss}, + {TLS_DH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_rsa}, + {TLS_DH_ANON_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_dh_anon}, +#endif + {TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, cipher_des, mac_sha,kea_rsa_export_1024}, {TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, @@ -285,6 +309,8 @@ const char * const ssl3_cipherName[] = { "DES-CBC-40", "IDEA-CBC", "FORTEZZA", + "AES-128", + "AES-256", "missing" }; @@ -7080,7 +7106,7 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) *buf = *origBuf; } while (buf->len > 0) { - while (ssl3->hs.header_bytes < 4) { + if (ssl3->hs.header_bytes < 4) { uint8 t; t = *(buf->buf++); buf->len--; @@ -7088,21 +7114,22 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) ssl3->hs.msg_type = (SSL3HandshakeType)t; else ssl3->hs.msg_len = (ssl3->hs.msg_len << 8) + t; + if (ssl3->hs.header_bytes < 4) + continue; #define MAX_HANDSHAKE_MSG_LEN 0x1ffff /* 128k - 1 */ - - if (ssl3->hs.header_bytes == 4) { - if (ssl3->hs.msg_len > MAX_HANDSHAKE_MSG_LEN) { - (void)ssl3_DecodeError(ss); - PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); - return SECFailure; - } + if (ssl3->hs.msg_len > MAX_HANDSHAKE_MSG_LEN) { + (void)ssl3_DecodeError(ss); + PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); + return SECFailure; } #undef MAX_HANDSHAKE_MSG_LEN - if (buf->len == 0 && ssl3->hs.msg_len > 0) { - buf->buf = NULL; - return SECSuccess; - } + + /* If msg_len is zero, be sure we fall through, + ** even if bug->len is zero. + */ + if (ssl3->hs.msg_len > 0) + continue; } /* diff --git a/security/nss/lib/ssl/sslenum.c b/security/nss/lib/ssl/sslenum.c index fe32b8f14..c83038203 100644 --- a/security/nss/lib/ssl/sslenum.c +++ b/security/nss/lib/ssl/sslenum.c @@ -76,6 +76,14 @@ const PRUint16 SSL_ImplementedCiphers[] = { SSL_DHE_DSS_WITH_DES_CBC_SHA, TLS_DHE_DSS_WITH_RC4_128_SHA, + /* AES ciphersuites */ + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_RSA_WITH_AES_128_CBC_SHA, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_256_CBC_SHA, + 0 }; diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index 98beb5097..0b043dddd 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -221,7 +221,7 @@ typedef struct { #endif } ssl3CipherSuiteCfg; -#define ssl_V3_SUITES_IMPLEMENTED 19 +#define ssl_V3_SUITES_IMPLEMENTED 25 typedef struct sslOptionsStr { unsigned int useSecurity : 1; /* 1 */ @@ -599,6 +599,8 @@ typedef enum { cipher_des40, cipher_idea, cipher_fortezza, + cipher_aes_128, + cipher_aes_256, cipher_missing /* reserved for no such supported cipher */ } SSL3BulkCipher; @@ -612,6 +614,7 @@ typedef enum { calg_3des = CKM_DES3_CBC, calg_idea = CKM_IDEA_CBC, calg_fortezza = CKM_SKIPJACK_CBC64, + calg_aes = CKM_AES_CBC, calg_init = (int) 0x7fffffffL } CipherAlgorithm; diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h index 51b780ca2..13850020c 100644 --- a/security/nss/lib/ssl/sslproto.h +++ b/security/nss/lib/ssl/sslproto.h @@ -139,7 +139,21 @@ #define SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA 0x001d #define SSL_FORTEZZA_DMS_WITH_RC4_128_SHA 0x001e -/* New TLS cipher suites backported to SSL3. */ +/* New TLS cipher suites */ +#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F +#define TLS_DH_DSS_WITH_AES_128_CBC_SHA 0x0030 +#define TLS_DH_RSA_WITH_AES_128_CBC_SHA 0x0031 +#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA 0x0032 +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 +#define TLS_DH_ANON_WITH_AES_128_CBC_SHA 0x0034 + +#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 +#define TLS_DH_DSS_WITH_AES_256_CBC_SHA 0x0036 +#define TLS_DH_RSA_WITH_AES_256_CBC_SHA 0x0037 +#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA 0x0038 +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 +#define TLS_DH_ANON_WITH_AES_256_CBC_SHA 0x003A + #define TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x0062 #define TLS_RSA_EXPORT1024_WITH_RC4_56_SHA 0x0064 diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 25ee5667b..d294a1421 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -80,6 +80,12 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */ { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { SSL_RSA_WITH_NULL_MD5, SSL_ALLOWED, SSL_ALLOWED }, + { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED }, { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_ALLOWED, SSL_NOT_ALLOWED }, { 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED } diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c index 21f31482e..483925df4 100644 --- a/security/nss/lib/util/secasn1d.c +++ b/security/nss/lib/util/secasn1d.c @@ -38,6 +38,13 @@ * $Id$ */ +/* #define DEBUG_ASN1D_STATES 1 */ + +#ifdef DEBUG_ASN1D_STATES +#include <stdio.h> +#define PR_Assert sec_asn1d_Assert +#endif + #include "secasn1.h" #include "secerr.h" @@ -72,7 +79,7 @@ typedef enum { } sec_asn1d_parse_place; #ifdef DEBUG_ASN1D_STATES -static const char *place_names[] = { +static const char * const place_names[] = { "beforeIdentifier", "duringIdentifier", "afterIdentifier", @@ -101,6 +108,114 @@ static const char *place_names[] = { "afterChoice", "notInUse" }; + +static const char * const class_names[] = { + "UNIVERSAL", + "APPLICATION", + "CONTEXT_SPECIFIC", + "PRIVATE" +}; + +static const char * const method_names[] = { "PRIMITIVE", "CONSTRUCTED" }; + +static const char * const type_names[] = { + "END_OF_CONTENTS", + "BOOLEAN", + "INTEGER", + "BIT_STRING", + "OCTET_STRING", + "NULL", + "OBJECT_ID", + "OBJECT_DESCRIPTOR", + "(type 08)", + "REAL", + "ENUMERATED", + "EMBEDDED", + "UTF8_STRING", + "(type 0d)", + "(type 0e)", + "(type 0f)", + "SEQUENCE", + "SET", + "NUMERIC_STRING", + "PRINTABLE_STRING", + "T61_STRING", + "VIDEOTEXT_STRING", + "IA5_STRING", + "UTC_TIME", + "GENERALIZED_TIME", + "GRAPHIC_STRING", + "VISIBLE_STRING", + "GENERAL_STRING", + "UNIVERSAL_STRING", + "(type 1d)", + "BMP_STRING", + "HIGH_TAG_VALUE" +}; + +static const char * const flag_names[] = { /* flags, right to left */ + "OPTIONAL", + "EXPLICIT", + "ANY", + "INLINE", + "POINTER", + "GROUP", + "DYNAMIC", + "SKIP", + "INNER", + "SAVE", + "", /* decoder ignores "MAY_STREAM", */ + "SKIP_REST", + "CHOICE", + "NO_STREAM", + "DEBUG_BREAK", + "unknown 08", + "unknown 10", + "unknown 20", + "unknown 40", + "unknown 80" +}; + +static int /* bool */ +formatKind(unsigned long kind, char * buf) +{ + int i; + unsigned long k = kind & SEC_ASN1_TAGNUM_MASK; + unsigned long notag = kind & (SEC_ASN1_CHOICE | SEC_ASN1_POINTER | + SEC_ASN1_INLINE | SEC_ASN1_ANY | SEC_ASN1_SAVE); + + buf[0] = 0; + if ((kind & SEC_ASN1_CLASS_MASK) != SEC_ASN1_UNIVERSAL) { + sprintf(buf, " %s", class_names[(kind & SEC_ASN1_CLASS_MASK) >> 6] ); + buf += strlen(buf); + } + if (kind & SEC_ASN1_METHOD_MASK) { + sprintf(buf, " %s", method_names[1]); + buf += strlen(buf); + } + if ((kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) { + if (k || !notag) { + sprintf(buf, " %s", type_names[k] ); + if ((k == SEC_ASN1_SET || k == SEC_ASN1_SEQUENCE) && + (kind & SEC_ASN1_GROUP)) { + buf += strlen(buf); + sprintf(buf, "_OF"); + } + } + } else { + sprintf(buf, " [%d]", k); + } + buf += strlen(buf); + + for (k = kind >> 8, i = 0; k; k >>= 1, ++i) { + if (k & 1) { + sprintf(buf, " %s", flag_names[i]); + buf += strlen(buf); + } + } + return notag != 0; +} + #endif /* DEBUG_ASN1D_STATES */ typedef enum { @@ -274,12 +389,7 @@ sec_asn1d_push_state (SEC_ASN1DecoderContext *cx, new_state = (sec_asn1d_state*)sec_asn1d_zalloc (cx->our_pool, sizeof(*new_state)); if (new_state == NULL) { - cx->status = decodeError; - if (state != NULL) { - PORT_ArenaRelease(cx->our_pool, state->our_mark); - state->our_mark = NULL; - } - return NULL; + goto loser; } new_state->top = cx; @@ -291,13 +401,24 @@ sec_asn1d_push_state (SEC_ASN1DecoderContext *cx, if (state != NULL) { new_state->depth = state->depth; - if (new_depth) - new_state->depth++; + if (new_depth) { + if (++new_state->depth > SEC_ASN1D_MAX_DEPTH) { + goto loser; + } + } state->child = new_state; } cx->current = new_state; return new_state; + +loser: + cx->status = decodeError; + if (state != NULL) { + PORT_ArenaRelease(cx->our_pool, state->our_mark); + state->our_mark = NULL; + } + return NULL; } @@ -412,10 +533,10 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state) encode_kind &= ~SEC_ASN1_DYNAMIC; encode_kind &= ~SEC_ASN1_MAY_STREAM; - if( encode_kind & SEC_ASN1_CHOICE ) { + if (encode_kind & SEC_ASN1_CHOICE) { #if 0 /* XXX remove? */ sec_asn1d_state *child = sec_asn1d_push_state(state->top, state->theTemplate, state->dest, PR_FALSE); - if( (sec_asn1d_state *)NULL == child ) { + if ((sec_asn1d_state *)NULL == child) { return (sec_asn1d_state *)NULL; } @@ -536,7 +657,7 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state) /* XXX is this the right set of bits to test here? */ PORT_Assert ((under_kind & (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL - | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM + | SEC_ASN1_MAY_STREAM | SEC_ASN1_INLINE | SEC_ASN1_POINTER)) == 0); if (encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) { @@ -551,7 +672,7 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state) expect_tag_number = 0; } else { check_tag_mask = SEC_ASN1_TAG_MASK; - expect_tag_modifiers = encode_kind & SEC_ASN1_TAG_MASK + expect_tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK & ~SEC_ASN1_TAGNUM_MASK; /* * XXX This assumes only single-octet identifiers. To handle @@ -600,6 +721,43 @@ sec_asn1d_init_state_based_on_template (sec_asn1d_state *state) return state; } +static sec_asn1d_state * +sec_asn1d_get_enclosing_construct(sec_asn1d_state *state) +{ + for (state = state->parent; state; state = state->parent) { + sec_asn1d_parse_place place = state->place; + if (place != afterImplicit && + place != afterPointer && + place != afterInline && + place != afterSaveEncoding && + place != duringSaveEncoding && + place != duringChoice) { + + /* we've walked up the stack to a state that represents + ** the enclosing construct. + */ + break; + } + } + return state; +} + +static PRBool +sec_asn1d_parent_allows_EOC(sec_asn1d_state *state) +{ + /* get state of enclosing construct. */ + state = sec_asn1d_get_enclosing_construct(state); + if (state) { + sec_asn1d_parse_place place = state->place; + /* Is it one of the types that permits an unexpected EOC? */ + int eoc_permitted = + (place == duringGroup || + place == duringConstructedString || + state->child->optional); + return (state->indefinite && eoc_permitted) ? PR_TRUE : PR_FALSE; + } + return PR_FALSE; +} static unsigned long sec_asn1d_parse_identifier (sec_asn1d_state *state, @@ -616,6 +774,13 @@ sec_asn1d_parse_identifier (sec_asn1d_state *state, } byte = (unsigned char) *buf; +#ifdef DEBUG_ASN1D_STATES + { + char kindBuf[256]; + formatKind(byte, kindBuf); + printf("Found tag %02x %s\n", byte, kindBuf); + } +#endif tag_number = byte & SEC_ASN1_TAGNUM_MASK; if (IS_HIGH_TAG_NUMBER (tag_number)) { @@ -628,15 +793,7 @@ sec_asn1d_parse_identifier (sec_asn1d_state *state, */ state->pending = 1; } else { - if (byte == 0 && state->parent != NULL && - (state->parent->indefinite || - ( - (state->parent->place == afterImplicit || - state->parent->place == afterPointer) - && state->parent->parent != NULL && state->parent->parent->indefinite - ) - ) - ) { + if (byte == 0 && sec_asn1d_parent_allows_EOC(state)) { /* * Our parent has indefinite-length encoding, and the * entire tag found is 0, so it seems that we have hit the @@ -768,14 +925,16 @@ sec_asn1d_parse_length (sec_asn1d_state *state, state->place = duringLength; } } - if (!state->indefinite) { - if (state->underlying_kind & SEC_ASN1_ANY || - state->underlying_kind & SEC_ASN1_SKIP) { - if (state->found_tag_modifiers & SEC_ASN1_CONSTRUCTED) { - state->found_tag_modifiers &= ~SEC_ASN1_CONSTRUCTED; - return 1; - } - } + + /* If we're parsing an ANY, SKIP, or SAVE template, and + ** the object being saved is definite length encoded and constructed, + ** there's no point in decoding that construct's members. + ** So, just forget it's constructed and treat it as primitive. + ** (SAVE appears as an ANY at this point) + */ + if (!state->indefinite && + (state->underlying_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP))) { + state->found_tag_modifiers &= ~SEC_ASN1_CONSTRUCTED; } return 1; @@ -830,6 +989,12 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state) PRArenaPool *poolp; unsigned long alloc_len; +#ifdef DEBUG_ASN1D_STATES + { + printf("Found Length %d %s\n", state->contents_length, + state->indefinite ? "indefinite" : ""); + } +#endif /* * XXX I cannot decide if this allocation should exclude the case @@ -872,11 +1037,15 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state) */ state->pending = state->contents_length; + /* If this item has definite length encoding, and + ** is enclosed by a definite length constructed type, + ** make sure it isn't longer than the remaining space in that + ** constructed type. + */ if (state->contents_length > 0) { - sec_asn1d_state *tmp = state->parent; - while (tmp && tmp->depth == state->depth) tmp = tmp->parent; - if (tmp && !tmp->indefinite && state->contents_length > tmp->pending) - { + sec_asn1d_state *parent = sec_asn1d_get_enclosing_construct(state); + if (parent && !parent->indefinite && + state->consumed + state->contents_length > parent->pending) { state->top->status = decodeError; return; } @@ -912,7 +1081,10 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state) * below under cases SET_OF and SEQUENCE_OF; it will be cleaner. */ PORT_Assert (state->underlying_kind == SEC_ASN1_SET_OF - || state->underlying_kind == SEC_ASN1_SEQUENCE_OF); + || state->underlying_kind == SEC_ASN1_SEQUENCE_OF + || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC) + || state->underlying_kind == (SEC_ASN1_SEQUENCE_OF|SEC_ASN1_DYNAMIC) + ); if (state->contents_length != 0 || state->indefinite) { const SEC_ASN1Template *subt; @@ -932,10 +1104,9 @@ sec_asn1d_prepare_for_contents (sec_asn1d_state *state) } else { /* * A group of zero; we are done. - * XXX Should we store a NULL here? Or set state to - * afterGroup and let that code do it? + * Set state to afterGroup and let that code plant the NULL. */ - state->place = afterEndOfContents; + state->place = afterGroup; } return; } @@ -1232,8 +1403,12 @@ sec_asn1d_free_child (sec_asn1d_state *state, PRBool error) if (error && state->top->their_pool == NULL) { /* * XXX We need to free anything allocated. + * At this point, we failed in the middle of decoding. But we + * can't free the data we previously allocated with PR_Malloc + * unless we keep track of every pointer. So instead we have a + * memory leak when decoding fails half-way, unless an arena is + * used. See bug 95311 . */ - PORT_Assert (0); } state->child = NULL; state->our_mark = NULL; @@ -1250,7 +1425,17 @@ sec_asn1d_free_child (sec_asn1d_state *state, PRBool error) state->place = beforeEndOfContents; } - +/* We have just saved an entire encoded ASN.1 object (type) for a SAVE +** template, and now in the next template, we are going to decode that +** saved data by calling SEC_ASN1DecoderUpdate recursively. +** If that recursive call fails with needBytes, it is a fatal error, +** because the encoded object should have been complete. +** If that recursive call fails with decodeError, it will have already +** cleaned up the state stack, so we must bail out quickly. +** +** These checks of the status returned by the recursive call are now +** done in the caller of this function, immediately after it returns. +*/ static void sec_asn1d_reuse_encoding (sec_asn1d_state *state) { @@ -1317,7 +1502,6 @@ sec_asn1d_reuse_encoding (sec_asn1d_state *state) (char *) item->data, item->len) != SECSuccess) return; if (state->top->status == needBytes) { - state->top->status = decodeError; return; } @@ -1372,9 +1556,19 @@ sec_asn1d_parse_bit_string (sec_asn1d_state *state, { unsigned char byte; - PORT_Assert (state->pending > 0); + /*PORT_Assert (state->pending > 0); */ PORT_Assert (state->place == beforeBitString); + if (state->pending == 0) { + if (state->dest != NULL) { + SECItem *item = (SECItem *)(state->dest); + item->data = NULL; + item->len = 0; + state->place = beforeEndOfContents; + return 0; + } + } + if (len == 0) { state->top->status = needBytes; return 0; @@ -1399,12 +1593,16 @@ static unsigned long sec_asn1d_parse_more_bit_string (sec_asn1d_state *state, const char *buf, unsigned long len) { -/* PORT_Assert (state->pending > 0); PORT_Assert (state->place == duringBitString); -*/ - if (state->pending == 0 || state->place != duringBitString) { - PORT_SetError (SEC_ERROR_BAD_DER); - state->top->status = decodeError; + if (state->pending == 0) { + /* An empty bit string with some unused bits is invalid. */ + if (state->bit_string_unused_bits) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + } else { + /* An empty bit string with no unused bits is OK. */ + state->place = beforeEndOfContents; + } return 0; } @@ -1516,7 +1714,7 @@ sec_asn1d_next_substring (sec_asn1d_state *state) if (state->pending) { PORT_Assert (!state->indefinite); - if( child_consumed > state->pending ) { + if (child_consumed > state->pending) { PORT_SetError (SEC_ERROR_BAD_DER); state->top->status = decodeError; return; @@ -1635,7 +1833,7 @@ sec_asn1d_next_in_group (sec_asn1d_state *state) */ if (state->pending) { PORT_Assert (!state->indefinite); - if( child_consumed > state->pending ) { + if (child_consumed > state->pending) { PORT_SetError (SEC_ERROR_BAD_DER); state->top->status = decodeError; return; @@ -1705,7 +1903,7 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state) sec_asn1d_free_child (child, PR_FALSE); if (state->pending) { PORT_Assert (!state->indefinite); - if( child_consumed > state->pending ) { + if (child_consumed > state->pending) { PORT_SetError (SEC_ERROR_BAD_DER); state->top->status = decodeError; return; @@ -1754,7 +1952,7 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state) */ if (state->indefinite && child->endofcontents) { PORT_Assert (child_consumed == 2); - if( child_consumed != 2 ) { + if (child_consumed != 2) { PORT_SetError (SEC_ERROR_BAD_DER); state->top->status = decodeError; } else { @@ -1817,7 +2015,7 @@ sec_asn1d_next_in_sequence (sec_asn1d_state *state) * sake it should probably be made to work at some point. */ PORT_Assert (child_found_tag_number < SEC_ASN1_HIGH_TAG_NUMBER); - identifier = child_found_tag_modifiers | child_found_tag_number; + identifier = (unsigned char)(child_found_tag_modifiers | child_found_tag_number); sec_asn1d_record_any_header (child, (char *) &identifier, 1); } } @@ -1917,7 +2115,8 @@ sec_asn1d_concat_group (sec_asn1d_state *state) PORT_Assert (state->place == afterGroup); placep = (const void***)state->dest; - if (state->subitems_head != NULL) { + PORT_Assert(state->subitems_head == NULL || placep != NULL); + if (placep != NULL) { struct subitem *item; const void **group; int count; @@ -1937,7 +2136,6 @@ sec_asn1d_concat_group (sec_asn1d_state *state) return; } - PORT_Assert (placep != NULL); *placep = group; item = state->subitems_head; @@ -1953,8 +2151,6 @@ sec_asn1d_concat_group (sec_asn1d_state *state) * a memory leak (it is just temporarily left dangling). */ state->subitems_head = state->subitems_tail = NULL; - } else if (placep != NULL) { - *placep = NULL; } state->place = afterEndOfContents; @@ -2064,7 +2260,7 @@ static unsigned long sec_asn1d_parse_end_of_contents (sec_asn1d_state *state, const char *buf, unsigned long len) { - int i; + unsigned int i; PORT_Assert (state->pending <= 2); PORT_Assert (state->place == duringEndOfContents); @@ -2110,7 +2306,7 @@ sec_asn1d_pop_state (sec_asn1d_state *state) state->consumed += state->child->consumed; if (state->pending) { PORT_Assert (!state->indefinite); - if( state->child->consumed > state->pending ) { + if (state->child->consumed > state->pending) { PORT_SetError (SEC_ERROR_BAD_DER); state->top->status = decodeError; } else { @@ -2134,134 +2330,146 @@ sec_asn1d_pop_state (sec_asn1d_state *state) } static sec_asn1d_state * -sec_asn1d_before_choice -( - sec_asn1d_state *state -) +sec_asn1d_before_choice (sec_asn1d_state *state) { - sec_asn1d_state *child; + sec_asn1d_state *child; - if( state->allocate ) { - void *dest; + if (state->allocate) { + void *dest; - dest = sec_asn1d_zalloc(state->top->their_pool, state->theTemplate->size); - if( (void *)NULL == dest ) { - state->top->status = decodeError; - return (sec_asn1d_state *)NULL; - } + dest = sec_asn1d_zalloc(state->top->their_pool, state->theTemplate->size); + if ((void *)NULL == dest) { + state->top->status = decodeError; + return (sec_asn1d_state *)NULL; + } - state->dest = (char *)dest + state->theTemplate->offset; - } + state->dest = (char *)dest + state->theTemplate->offset; + } - child = sec_asn1d_push_state(state->top, state->theTemplate + 1, - state->dest, PR_FALSE); - if( (sec_asn1d_state *)NULL == child ) { - return (sec_asn1d_state *)NULL; - } + child = sec_asn1d_push_state(state->top, state->theTemplate + 1, + (char *)state->dest - state->theTemplate->offset, + PR_FALSE); + if ((sec_asn1d_state *)NULL == child) { + return (sec_asn1d_state *)NULL; + } - sec_asn1d_scrub_state(child); - child = sec_asn1d_init_state_based_on_template(child); - if( (sec_asn1d_state *)NULL == child ) { - return (sec_asn1d_state *)NULL; - } + sec_asn1d_scrub_state(child); + child = sec_asn1d_init_state_based_on_template(child); + if ((sec_asn1d_state *)NULL == child) { + return (sec_asn1d_state *)NULL; + } - child->optional = PR_TRUE; + child->optional = PR_TRUE; - state->place = duringChoice; + state->place = duringChoice; - return child; + return child; } static sec_asn1d_state * -sec_asn1d_during_choice -( - sec_asn1d_state *state -) +sec_asn1d_during_choice (sec_asn1d_state *state) { - sec_asn1d_state *child = state->child; - - PORT_Assert((sec_asn1d_state *)NULL != child); - - if( child->missing ) { - unsigned char child_found_tag_modifiers = 0; - unsigned long child_found_tag_number = 0; + sec_asn1d_state *child = state->child; + + PORT_Assert((sec_asn1d_state *)NULL != child); - child->theTemplate++; + if (child->missing) { + unsigned char child_found_tag_modifiers = 0; + unsigned long child_found_tag_number = 0; + void * dest; + + state->consumed += child->consumed; + + if (child->endofcontents) { + /* This choice is probably the first item in a GROUP + ** (e.g. SET_OF) that was indefinite-length encoded. + ** We're actually at the end of that GROUP. + ** We look up the stack to be sure that we find + ** a state with indefinite length encoding before we + ** find a state (like a SEQUENCE) that is definite. + */ + child->place = notInUse; + state->place = afterChoice; + state->endofcontents = PR_TRUE; /* propagate this up */ + if (sec_asn1d_parent_allows_EOC(state)) + return state; + PORT_SetError(SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return NULL; + } - if( 0 == child->theTemplate->kind ) { - /* Ran out of choices */ - PORT_SetError(SEC_ERROR_BAD_DER); - state->top->status = decodeError; - return (sec_asn1d_state *)NULL; - } + dest = (char *)child->dest - child->theTemplate->offset; + child->theTemplate++; - state->consumed += child->consumed; + if (0 == child->theTemplate->kind) { + /* Ran out of choices */ + PORT_SetError(SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return (sec_asn1d_state *)NULL; + } + child->dest = (char *)dest + child->theTemplate->offset; - /* cargo'd from next_in_sequence innards */ - if( state->pending ) { - PORT_Assert(!state->indefinite); - if( child->consumed > state->pending ) { - PORT_SetError (SEC_ERROR_BAD_DER); - state->top->status = decodeError; - return NULL; - } - state->pending -= child->consumed; - if( 0 == state->pending ) { - /* XXX uh.. not sure if I should have stopped this - * from happening before. */ - PORT_Assert(0); - PORT_SetError(SEC_ERROR_BAD_DER); - state->top->status = decodeError; - return (sec_asn1d_state *)NULL; - } - } + /* cargo'd from next_in_sequence innards */ + if (state->pending) { + PORT_Assert(!state->indefinite); + if (child->consumed > state->pending) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return NULL; + } + state->pending -= child->consumed; + if (0 == state->pending) { + /* XXX uh.. not sure if I should have stopped this + * from happening before. */ + PORT_Assert(0); + PORT_SetError(SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return (sec_asn1d_state *)NULL; + } + } - child->consumed = 0; - sec_asn1d_scrub_state(child); + child->consumed = 0; + sec_asn1d_scrub_state(child); - /* move it on top again */ - state->top->current = child; + /* move it on top again */ + state->top->current = child; - child_found_tag_modifiers = child->found_tag_modifiers; - child_found_tag_number = child->found_tag_number; + child_found_tag_modifiers = child->found_tag_modifiers; + child_found_tag_number = child->found_tag_number; - child = sec_asn1d_init_state_based_on_template(child); - if( (sec_asn1d_state *)NULL == child ) { - return (sec_asn1d_state *)NULL; - } + child = sec_asn1d_init_state_based_on_template(child); + if ((sec_asn1d_state *)NULL == child) { + return (sec_asn1d_state *)NULL; + } - /* copy our findings to the new top */ - child->found_tag_modifiers = child_found_tag_modifiers; - child->found_tag_number = child_found_tag_number; + /* copy our findings to the new top */ + child->found_tag_modifiers = child_found_tag_modifiers; + child->found_tag_number = child_found_tag_number; - child->optional = PR_TRUE; - child->place = afterIdentifier; + child->optional = PR_TRUE; + child->place = afterIdentifier; - return child; - } else { - if( (void *)NULL != state->dest ) { - /* Store the enum */ - int *which = (int *)((char *)state->dest + state->theTemplate->offset); - *which = (int)child->theTemplate->size; + return child; + } + if ((void *)NULL != state->dest) { + /* Store the enum */ + int *which = (int *)state->dest; + *which = (int)child->theTemplate->size; } child->place = notInUse; state->place = afterChoice; return state; - } } static void -sec_asn1d_after_choice -( - sec_asn1d_state *state -) +sec_asn1d_after_choice (sec_asn1d_state *state) { - state->consumed += state->child->consumed; - state->child->consumed = 0; - state->place = afterEndOfContents; - sec_asn1d_pop_state(state); + state->consumed += state->child->consumed; + state->child->consumed = 0; + state->place = afterEndOfContents; + sec_asn1d_pop_state(state); } unsigned long @@ -2286,7 +2494,7 @@ SECStatus SEC_ASN1DecodeInteger(SECItem *src, unsigned long *value) { unsigned long v; - int i; + unsigned int i; if (src == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -2319,29 +2527,42 @@ SEC_ASN1DecodeInteger(SECItem *src, unsigned long *value) #ifdef DEBUG_ASN1D_STATES static void -dump_states -( - SEC_ASN1DecoderContext *cx -) +dump_states(SEC_ASN1DecoderContext *cx) { - sec_asn1d_state *state; - - for( state = cx->current; state->parent; state = state->parent ) { - ; - } - - for( ; state; state = state->child ) { - int i; - for( i = 0; i < state->depth; i++ ) { - printf(" "); - } - - printf("%s: template[0]->kind = 0x%02x, expect tag number = 0x%02x\n", - (state == cx->current) ? "STATE" : "State", - state->theTemplate->kind, state->expect_tag_number); - } - - return; + sec_asn1d_state *state; + char kindBuf[256]; + + for (state = cx->current; state->parent; state = state->parent) { + ; + } + + for (; state; state = state->child) { + int i; + for (i = 0; i < state->depth; i++) { + printf(" "); + } + + i = formatKind(state->theTemplate->kind, kindBuf); + printf("%s: tmpl %08x, kind%s", + (state == cx->current) ? "STATE" : "State", + state->theTemplate, + kindBuf); + printf(" %s", (state->place >= 0 && state->place <= notInUse) + ? place_names[ state->place ] + : "(undefined)"); + if (!i) + printf(", expect 0x%02x", + state->expect_tag_number | state->expect_tag_modifiers); + + printf("%s%s%s %d\n", + state->indefinite ? ", indef" : "", + state->missing ? ", miss" : "", + state->endofcontents ? ", EOC" : "", + state->pending + ); + } + + return; } #endif /* DEBUG_ASN1D_STATES */ @@ -2352,7 +2573,7 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, sec_asn1d_state *state = NULL; unsigned long consumed; SEC_ASN1EncodingPart what; - + sec_asn1d_state *stateEnd = cx->current; if (cx->status == needBytes) cx->status = keepGoing; @@ -2362,10 +2583,11 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, what = SEC_ASN1_Contents; consumed = 0; #ifdef DEBUG_ASN1D_STATES - printf("\nPLACE = %s, next byte = 0x%02x\n", + printf("\nPLACE = %s, next byte = 0x%02x, %08x[%d]\n", (state->place >= 0 && state->place <= notInUse) ? place_names[ state->place ] : "(undefined)", - (unsigned int)((unsigned char *)buf)[ consumed ]); + (unsigned int)((unsigned char *)buf)[ consumed ], + buf, consumed); dump_states(cx); #endif /* DEBUG_ASN1D_STATES */ switch (state->place) { @@ -2408,8 +2630,16 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, break; case duringSaveEncoding: sec_asn1d_reuse_encoding (state); - if (cx->status == decodeError) - return SECFailure; + if (cx->status == decodeError) { + /* recursive call has already popped all states from stack. + ** Bail out quickly. + */ + return SECFailure; + } + if (cx->status == needBytes) { + /* recursive call wanted more data. Fatal. Clean up below. */ + cx->status = decodeError; + } break; case duringSequence: sec_asn1d_next_in_sequence (state); @@ -2427,7 +2657,10 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, sec_asn1d_concat_group (state); break; case afterSaveEncoding: - /* XXX comment! */ + /* SEC_ASN1DecoderUpdate has called itself recursively to + ** decode SAVEd encoded data, and now is done decoding that. + ** Return to the calling copy of SEC_ASN1DecoderUpdate. + */ return SECSuccess; case beforeEndOfContents: sec_asn1d_prepare_for_end_of_contents (state); @@ -2462,7 +2695,7 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, /* We should not consume more than we have. */ PORT_Assert (consumed <= len); - if( consumed > len ) { + if (consumed > len) { PORT_SetError (SEC_ERROR_BAD_DER); cx->status = decodeError; break; @@ -2532,7 +2765,7 @@ SEC_ASN1DecoderUpdate (SEC_ASN1DecoderContext *cx, } if (cx->status == decodeError) { - while (state != NULL) { + while (state != NULL && stateEnd->parent!=state) { sec_asn1d_free_child (state, PR_TRUE); state = state->parent; } @@ -2709,6 +2942,13 @@ SEC_ASN1DecodeItem (PRArenaPool *poolp, void *dest, (char *) item->data, item->len); } +#ifdef DEBUG_ASN1D_STATES +void sec_asn1d_Assert(const char *s, const char *file, PRIntn ln) +{ + printf("Assertion failed, \"%s\", file %s, line %d\n", s, file, ln); + fflush(stdout); +} +#endif /* * Generic templates for individual/simple items and pointers to diff --git a/security/nss/lib/util/secasn1t.h b/security/nss/lib/util/secasn1t.h index cb56a0bd7..d74820a8e 100644 --- a/security/nss/lib/util/secasn1t.h +++ b/security/nss/lib/util/secasn1t.h @@ -191,6 +191,8 @@ typedef struct sec_ASN1Template_struct { #define SEC_ASN1_SET_OF (SEC_ASN1_GROUP | SEC_ASN1_SET) #define SEC_ASN1_ANY_CONTENTS (SEC_ASN1_ANY | SEC_ASN1_INNER) +/* Maximum depth of nested SEQUENCEs and SETs */ +#define SEC_ASN1D_MAX_DEPTH 32 /* ** Function used for SEC_ASN1_DYNAMIC. diff --git a/security/nss/lib/util/secitem.c b/security/nss/lib/util/secitem.c index f185d60b9..a60755881 100644 --- a/security/nss/lib/util/secitem.c +++ b/security/nss/lib/util/secitem.c @@ -141,6 +141,11 @@ SECITEM_CompareItem(const SECItem *a, const SECItem *b) unsigned m; SECComparison rv; + if (!a || !a->len || !a->data) + return (!b || !b->len || !b->data) ? SECEqual : SECLessThan; + if (!b || !b->len || !b->data) + return SECGreaterThan; + m = ( ( a->len < b->len ) ? a->len : b->len ); rv = (SECComparison) PORT_Memcmp(a->data, b->data, m); @@ -159,10 +164,15 @@ SECITEM_CompareItem(const SECItem *a, const SECItem *b) PRBool SECITEM_ItemsAreEqual(const SECItem *a, const SECItem *b) { - if (SECITEM_CompareItem(a, b) == SECEqual) - return PR_TRUE; - - return PR_FALSE; + if (a->len != b->len) + return PR_FALSE; + if (!a->len) + return PR_TRUE; + if (!a->data || !b->data) { + /* avoid null pointer crash. */ + return (PRBool)(a->data == b->data); + } + return (PRBool)!PORT_Memcmp(a->data, b->data, a->len); } SECItem * diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c index 567508619..cef09291a 100644 --- a/security/nss/lib/util/secoid.c +++ b/security/nss/lib/util/secoid.c @@ -39,7 +39,8 @@ #include "secerr.h" /* MISSI Mosaic Object ID space */ -#define MISSI 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01 +#define USGOV 0x60, 0x86, 0x48, 0x01, 0x65 +#define MISSI USGOV, 0x02, 0x01, 0x01 #define MISSI_OLD_KEA_DSS MISSI, 0x0c #define MISSI_OLD_DSS MISSI, 0x02 #define MISSI_KEA_DSS MISSI, 0x14 @@ -47,6 +48,9 @@ #define MISSI_KEA MISSI, 0x0a #define MISSI_ALT_KEA MISSI, 0x16 +#define NISTALGS USGOV, 3, 4 +#define AES NISTALGS, 1 + /** ** The Netscape OID space is allocated by Terry Hayes. If you need ** a piece of the space, contact him at thayes@netscape.com. @@ -307,8 +311,8 @@ static unsigned char pkcs12RSASignatureWithSHA1Digest[] = static unsigned char ansix9DSASignature[] = { ANSI_X9_ALGORITHM, 0x01 }; static unsigned char ansix9DSASignaturewithSHA1Digest[] = { ANSI_X9_ALGORITHM, 0x03 }; -static unsigned char bogusDSASignaturewithSHA1Digest[] = - { ALGORITHM, 0x1b }; +static unsigned char bogusDSASignaturewithSHA1Digest[] = { ALGORITHM, 0x1b }; +static unsigned char sdn702DSASignature[] = { ALGORITHM, 0x0c }; /* verisign OIDs */ static unsigned char verisignUserNotices[] = { VERISIGN, 1, 7, 1, 1 }; @@ -395,6 +399,21 @@ static unsigned char cmsRC2wrap[] = { PKCS9_SMIME_ALGS, 7 }; /* RFC2633 SMIME message attributes */ static unsigned char smimeEncryptionKeyPreference[] = { PKCS9_SMIME_ATTRS, 11 }; +static unsigned char aes128_ECB[] = { AES, 1 }; +static unsigned char aes128_CBC[] = { AES, 2 }; +static unsigned char aes128_OFB[] = { AES, 3 }; +static unsigned char aes128_CFB[] = { AES, 4 }; + +static unsigned char aes192_ECB[] = { AES, 21 }; +static unsigned char aes192_CBC[] = { AES, 22 }; +static unsigned char aes192_OFB[] = { AES, 23 }; +static unsigned char aes192_CFB[] = { AES, 24 }; + +static unsigned char aes256_ECB[] = { AES, 41 }; +static unsigned char aes256_CBC[] = { AES, 42 }; +static unsigned char aes256_OFB[] = { AES, 43 }; +static unsigned char aes256_CFB[] = { AES, 44 }; + /* * NOTE: the order of these entries must mach the SECOidTag enum in secoidt.h! */ @@ -1215,6 +1234,30 @@ static SECOidData oids[] = { "S/MIME Encryption Key Preference", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION }, + /* AES algorithm OIDs */ + { { siDEROID, aes128_ECB, sizeof(aes128_ECB) }, + SEC_OID_AES_128_ECB, + "AES-128-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION }, + { { siDEROID, aes128_CBC, sizeof(aes128_CBC) }, + SEC_OID_AES_128_CBC, + "AES-128-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION }, + { { siDEROID, aes192_ECB, sizeof(aes192_ECB) }, + SEC_OID_AES_192_ECB, + "AES-192-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION }, + { { siDEROID, aes192_CBC, sizeof(aes192_CBC) }, + SEC_OID_AES_192_CBC, + "AES-192-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION }, + { { siDEROID, aes256_ECB, sizeof(aes256_ECB) }, + SEC_OID_AES_256_ECB, + "AES-256-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION }, + { { siDEROID, aes256_CBC, sizeof(aes256_CBC) }, + SEC_OID_AES_256_CBC, + "AES-256-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION }, + + /* More bogus DSA OIDs */ + { { siDEROID, sdn702DSASignature, sizeof(sdn702DSASignature) }, + SEC_OID_SDN702_DSA_SIGNATURE, + "SDN.702 DSA Signature", CKM_DSA_SHA1, INVALID_CERT_EXTENSION }, }; /* @@ -1367,8 +1410,8 @@ SECOID_AddEntry(SECItem *oid, char *description, unsigned long mech) { static DB *oidhash = NULL; static DB *oidmechhash = NULL; -static SECStatus -InitOIDHash(void) +SECStatus +secoid_Init(void) { DBT key; DBT data; @@ -1376,6 +1419,10 @@ InitOIDHash(void) SECOidData *oid; int i; + if (oidhash) { + return PR_SUCCESS; + } + oidhash = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 ); oidmechhash = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 ); @@ -1432,14 +1479,9 @@ SECOID_FindOIDByMechanism(unsigned long mechanism) DBT data; SECOidData *ret; int rv; + + PR_ASSERT(oidhash != NULL); - if ( !oidhash ) { - rv = InitOIDHash(); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return NULL; - } - } key.data = &mechanism; key.size = sizeof(mechanism); @@ -1461,13 +1503,7 @@ SECOID_FindOID(SECItem *oid) SECOidData *ret; int rv; - if ( !oidhash ) { - rv = InitOIDHash(); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return NULL; - } - } + PR_ASSERT(oidhash != NULL); key.data = oid->data; key.size = oid->len; diff --git a/security/nss/lib/util/secoidt.h b/security/nss/lib/util/secoidt.h index 0594610ec..f854bad3d 100644 --- a/security/nss/lib/util/secoidt.h +++ b/security/nss/lib/util/secoidt.h @@ -284,6 +284,16 @@ typedef enum { /* SMIME attributes */ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE = 182, + /* AES OIDs */ + SEC_OID_AES_128_ECB = 183, + SEC_OID_AES_128_CBC = 184, + SEC_OID_AES_192_ECB = 185, + SEC_OID_AES_192_CBC = 186, + SEC_OID_AES_256_ECB = 187, + SEC_OID_AES_256_CBC = 188, + + SEC_OID_SDN702_DSA_SIGNATURE = 189, + SEC_OID_TOTAL } SECOidTag; @@ -301,9 +311,10 @@ struct SECOidDataStr { SECOidTag offset; char *desc; unsigned long mechanism; - SECSupportExtenTag supportedExtension; /* only used for x.509 v3 extensions, so - that we can print the names of those - extensions that we don't even support */ + SECSupportExtenTag supportedExtension; + /* only used for x.509 v3 extensions, so + that we can print the names of those + extensions that we don't even support */ }; #endif /* _SECOIDT_H_ */ diff --git a/security/nss/pkg/linux/Makefile b/security/nss/pkg/linux/Makefile index f25d09f71..842444ae1 100644 --- a/security/nss/pkg/linux/Makefile +++ b/security/nss/pkg/linux/Makefile @@ -9,25 +9,28 @@ CORE_DEPTH = ../../.. NAME = sun-nss RELEASE = 1 -TOPDIR = /usr/src/redhat -VERSION = `grep NSS_VERSION $(CORE_DEPTH)/../dist/public/nss/nss.h \ - | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'` +VERSION = `grep NSS_VERSION $(CORE_DEPTH)/../dist/public/security/nss.h \ + | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'` +PWD = `pwd` +BUILDROOT = $(PWD)\/$(NAME)-root include $(CORE_DEPTH)/coreconf/config.mk publish: $(MAKE) clean + mkdir -p SOURCES SRPMS RPMS BUILD mkdir -p usr/lib/mps find $(CORE_DEPTH)/../dist/$(OBJDIR)/lib -type l \ \( -name "*.so" -o -name "*.chk" \) \ - -exec cp -L {} usr/lib/mps \; - mkdir -p usr/include/mps - cp -Lr $(CORE_DEPTH)/../dist/public/* usr/include/mps + -exec cp {} usr/lib/mps \; + (cd $(CORE_DEPTH)/../dist/public && tar cphf - .) \ + | (mkdir -p usr/include/mps && cd usr/include/mps && tar xvfBp -) tar czvf $(NAME)-$(VERSION).tar.gz usr + echo "%define _topdir `pwd`" >temp.spec sed -e "s/NAME_REPLACE/$(NAME)/" \ -e "s/VERSION_REPLACE/$(VERSION)/" \ -e "s/RELEASE_REPLACE/$(RELEASE)/" \ - <$(NAME).spec >temp.spec + <$(NAME).spec >>temp.spec echo "" >>temp.spec echo "%files" >>temp.spec echo "%defattr(-,root,root)" >>temp.spec @@ -42,17 +45,12 @@ publish: find usr -type d | sed -e "s-^-%dir /-" >>temp.spec find usr -type f ! \( -name "*.so" -o -name "*.chk" \) \ | sed -e "s-^-/-" >>temp.spec - cp $(NAME)-$(VERSION).tar.gz $(TOPDIR)/SOURCES + cp $(NAME)-$(VERSION).tar.gz SOURCES rpm -ba temp.spec - if [ ! -d RPMS ] ; then mkdir -p RPMS ; fi - if [ ! -d SRPMS ] ; then mkdir -p SRPMS ; fi - cp -v $(TOPDIR)/RPMS/i386/$(NAME)-$(VERSION)-* RPMS - cp -v $(TOPDIR)/RPMS/i386/$(NAME)-devel-$(VERSION)-* RPMS - cp -v $(TOPDIR)/SRPMS/$(NAME)-$(VERSION)-* SRPMS clean:: - rm -rf $(TOPDIR)/BUILD/$(NAME) - rm -rf RPMS SRPMS usr + rm -rf SOURCES SRPMS RPMS BUILD + rm -rf usr rm -f temp.spec rm -f $(NAME)-$(VERSION).tar.gz diff --git a/security/nss/pkg/linux/sun-nss.spec b/security/nss/pkg/linux/sun-nss.spec index 1c3563332..94457b87a 100644 --- a/security/nss/pkg/linux/sun-nss.spec +++ b/security/nss/pkg/linux/sun-nss.spec @@ -7,8 +7,9 @@ Copyright: MPL/GPL Group: System Environment/Base Source: %{name}-%{version}.tar.gz ExclusiveOS: Linux -BuildRoot: /var/tmp/%{name}-root -Requires: sun-nspr >= 4.3 +BuildRoot: %_topdir/%{name}-root + +Requires: sun-nspr >= 4.1.2 %description Network Security Services (NSS) is a set of libraries designed diff --git a/security/nss/pkg/solaris/Makefile b/security/nss/pkg/solaris/Makefile index 2d2ff6ff4..2ba36e4fb 100644 --- a/security/nss/pkg/solaris/Makefile +++ b/security/nss/pkg/solaris/Makefile @@ -12,23 +12,35 @@ CORE_DEPTH = ../../.. cp $< $@ chmod +x $@ +HEADER_DIR_BEFORE_3_6 = public/security +HEADER_DIR_SINCE_3_6 = public/nss ifeq ($(USE_64), 1) DIRS = \ - SUNWtlsx + SUNWtlsx \ + SUNWtlsux \ + SUNWtlsdx else DIRS = \ - SUNWtls + SUNWtls \ + SUNWtlsu \ + SUNWtlsd endif PROTO = \ $(ROOT) \ $(ROOT)/usr \ $(ROOT)/usr/lib \ - $(ROOT)/usr/lib/mps + $(ROOT)/usr/lib/mps \ + $(ROOT)/usr/include \ + $(ROOT)/usr/include/mps \ + $(ROOT)/usr/sfw \ + $(ROOT)/usr/sfw/bin ifdef USE_64 -PROTO += $(ROOT)/usr/lib/mps/sparcv9 +PROTO += $(ROOT)/usr/lib/mps/sparcv9 \ + $(ROOT)/usr/include/mps/sparcv9 \ + $(ROOT)/usr/sfw/bin/sparcv9 endif include Makefile.com @@ -36,7 +48,7 @@ include Makefile.com awk_pkginfo: bld_awk_pkginfo ./bld_awk_pkginfo -m $(MACH) -p "$(PRODUCT_VERSION)" -o $@ -v $(PRODUCT_VERSION) -all:: awk_pkginfo $(PROTO) +all:: awk_pkginfo $(PROTO) # $(HEADER_DIR) publish: awk_pkginfo $(PROTO) +$(LOOP_OVER_DIRS) @@ -48,9 +60,25 @@ $(ROOT) $(ROOT)/%: mkdir -p $@ ifdef USE_64 -$(ROOT)/usr/lib/mps/sparcv9: $(ROOT)/usr/lib +$(ROOT)/usr/lib/mps/sparcv9: $(ROOT)/usr/lib/mps $(LN) -sf ../../../../$(DIST)/lib $@ +$(ROOT)/usr/sfw/bin/sparcv9: $(ROOT)/usr/sfw/bin + $(LN) -sf ../../../../$(DIST)/bin $@ +$(ROOT)/usr/include/mps/sparcv9: $(ROOT)/usr/include + @if [ -d ../../../$(SOURCE_PREFIX)/$(HEADER_DIR_SINCE_3_6) ] ; then \ + $(LN) -sf ../../../../$(SOURCE_PREFIX)/$(HEADER_DIR_SINCE_3_6) $@ ; \ + else \ + $(LN) -sf ../../../../$(SOURCE_PREFIX)/$(HEADER_DIR_BEFORE_3_6) $@ ; \ + fi else $(ROOT)/usr/lib/mps: $(ROOT)/usr/lib $(LN) -sf ../../../$(DIST)/lib $@ +$(ROOT)/usr/sfw/bin: $(ROOT)/usr/sfw + $(LN) -sf ../../../$(DIST)/bin $@ +$(ROOT)/usr/include/mps: $(ROOT)/usr/include + @if [ -d ../../../$(SOURCE_PREFIX)/$(HEADER_DIR_SINCE_3_6) ] ; then \ + $(LN) -sf ../../../$(SOURCE_PREFIX)/$(HEADER_DIR_SINCE_3_6) $@ ; \ + else \ + $(LN) -sf ../../../$(SOURCE_PREFIX)/$(HEADER_DIR_BEFORE_3_6) $@ ; \ + fi endif diff --git a/security/nss/pkg/solaris/Makefile-devl.com b/security/nss/pkg/solaris/Makefile-devl.com new file mode 100755 index 000000000..8e1c52ad4 --- /dev/null +++ b/security/nss/pkg/solaris/Makefile-devl.com @@ -0,0 +1,33 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +MACH = $(shell mach) + +PUBLISH_ROOT = $(DIST) +ifeq ($(CORE_DEPTH),../../..) +ROOT = ROOT +else +ROOT = $(subst ../../../,,$(CORE_DEPTH))/ROOT +endif + +PKGARCHIVE = $(PUBLISH_ROOT)/pkgarchive +DATAFILES = copyright +FILES = $(DATAFILES) pkginfo + + +PACKAGE = $(shell basename `pwd`) + +PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/nss/lib/nss/nss.h | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') + +LN = /usr/bin/ln + +CLOBBERFILES = $(FILES) + +include $(CORE_DEPTH)/coreconf/config.mk +include $(CORE_DEPTH)/coreconf/rules.mk + +# vim: ft=make diff --git a/security/nss/pkg/solaris/Makefile-devl.targ b/security/nss/pkg/solaris/Makefile-devl.targ new file mode 100755 index 000000000..bbf9411bb --- /dev/null +++ b/security/nss/pkg/solaris/Makefile-devl.targ @@ -0,0 +1,26 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +pkginfo: pkginfo.tmpl ../awk_pkginfo + $(RM) $@; nawk -f ../awk_pkginfo $@.tmpl > $@ + +pkg: $(PKGARCHIVE) prototype + pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE) + +$(PKGARCHIVE): + [ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE) + +$(DATAFILES):: %: ../common_files/% + $(RM) $@; cp ../common_files/$@ $@ + +$(MACHDATAFILES): %: ../common_files/%_$(MACH) + $(RM) $@; cp ../common_files/$@_$(MACH) $@ + +clobber clean:: + -$(RM) $(CLOBBERFILES) $(CLEANFILES) + +.PHONY: pkg diff --git a/security/nss/pkg/solaris/Makefile-tlsu.com b/security/nss/pkg/solaris/Makefile-tlsu.com new file mode 100755 index 000000000..8e1c52ad4 --- /dev/null +++ b/security/nss/pkg/solaris/Makefile-tlsu.com @@ -0,0 +1,33 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +MACH = $(shell mach) + +PUBLISH_ROOT = $(DIST) +ifeq ($(CORE_DEPTH),../../..) +ROOT = ROOT +else +ROOT = $(subst ../../../,,$(CORE_DEPTH))/ROOT +endif + +PKGARCHIVE = $(PUBLISH_ROOT)/pkgarchive +DATAFILES = copyright +FILES = $(DATAFILES) pkginfo + + +PACKAGE = $(shell basename `pwd`) + +PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/nss/lib/nss/nss.h | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') + +LN = /usr/bin/ln + +CLOBBERFILES = $(FILES) + +include $(CORE_DEPTH)/coreconf/config.mk +include $(CORE_DEPTH)/coreconf/rules.mk + +# vim: ft=make diff --git a/security/nss/pkg/solaris/Makefile-tlsu.targ b/security/nss/pkg/solaris/Makefile-tlsu.targ new file mode 100755 index 000000000..bbf9411bb --- /dev/null +++ b/security/nss/pkg/solaris/Makefile-tlsu.targ @@ -0,0 +1,26 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +pkginfo: pkginfo.tmpl ../awk_pkginfo + $(RM) $@; nawk -f ../awk_pkginfo $@.tmpl > $@ + +pkg: $(PKGARCHIVE) prototype + pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE) + +$(PKGARCHIVE): + [ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE) + +$(DATAFILES):: %: ../common_files/% + $(RM) $@; cp ../common_files/$@ $@ + +$(MACHDATAFILES): %: ../common_files/%_$(MACH) + $(RM) $@; cp ../common_files/$@_$(MACH) $@ + +clobber clean:: + -$(RM) $(CLOBBERFILES) $(CLEANFILES) + +.PHONY: pkg diff --git a/security/nss/pkg/solaris/Makefile.com b/security/nss/pkg/solaris/Makefile.com index ac4790230..d3580a3a5 100644 --- a/security/nss/pkg/solaris/Makefile.com +++ b/security/nss/pkg/solaris/Makefile.com @@ -21,8 +21,7 @@ FILES = $(DATAFILES) pkginfo prototype PACKAGE = $(shell basename `pwd`) -PRODUCT_VERSION = "3.3.4" -PRODUCT_NAME = NSS_3_3_4_RTM +PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/nss/lib/nss/nss.h | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') LN = /usr/bin/ln diff --git a/security/nss/pkg/solaris/SUNWtlsd/Makefile b/security/nss/pkg/solaris/SUNWtlsd/Makefile new file mode 100755 index 000000000..3a1bd83b3 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsd/Makefile @@ -0,0 +1,16 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +CORE_DEPTH = ../../../.. +include ../Makefile-devl.com + +DATAFILES += + +all:: $(FILES) +publish:: all pkg + +include ../Makefile-devl.targ diff --git a/security/nss/pkg/solaris/SUNWtlsd/pkgdepend b/security/nss/pkg/solaris/SUNWtlsd/pkgdepend new file mode 100755 index 000000000..fe0695db7 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsd/pkgdepend @@ -0,0 +1,23 @@ +# Copyright 2002 Microsystems, Inc. All Rights Reserved. +# Use is subject to license terms. +# +# $Id$ +# +# This package information file defines software dependencies associated +# with the pkg. You can define three types of pkg dependencies with this file: +# P indicates a prerequisite for installation +# I indicates an incompatible package +# R indicates a reverse dependency +# <pkg.abbr> see pkginfo(4), PKG parameter +# <name> see pkginfo(4), NAME parameter +# <version> see pkginfo(4), VERSION parameter +# <arch> see pkginfo(4), ARCH parameter +# <type> <pkg.abbr> <name> +# (<arch>)<version> +# (<arch>)<version> +# ... +# <type> <pkg.abbr> <name> +# ... + +P SUNWprd Netscape Portable Runtime Development +P SUNWtls Netscape Security Services diff --git a/security/nss/pkg/solaris/SUNWtlsd/pkginfo.tmpl b/security/nss/pkg/solaris/SUNWtlsd/pkginfo.tmpl new file mode 100755 index 000000000..c47b89069 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsd/pkginfo.tmpl @@ -0,0 +1,34 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWtlsd" +NAME="Network Security Services Development" +ARCH="ISA" +VERSION="NSSVERS,REV=0.0.0" +SUNW_PRODNAME="Network Security Services Development" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Network Security Services Files for Development" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/security/nss/pkg/solaris/SUNWtlsd/prototype b/security/nss/pkg/solaris/SUNWtlsd/prototype new file mode 100755 index 000000000..52b1e8911 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsd/prototype @@ -0,0 +1,121 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i copyright +i pkginfo +i depend=pkgdepend +# +# source locations relative to the prototype file +# +# SUNWtlsd +# +d none usr 0755 root sys +d none usr/include 0755 root bin +d none usr/include/mps 0755 root bin +f none usr/include/mps/base64.h 0644 root bin +f none usr/include/mps/blapi.h 0644 root bin +f none usr/include/mps/blapit.h 0644 root bin +f none usr/include/mps/cert.h 0644 root bin +f none usr/include/mps/certdb.h 0644 root bin +f none usr/include/mps/certt.h 0644 root bin +f none usr/include/mps/ciferfam.h 0644 root bin +f none usr/include/mps/cmmf.h 0644 root bin +f none usr/include/mps/cmmft.h 0644 root bin +f none usr/include/mps/cms.h 0644 root bin +f none usr/include/mps/cmsreclist.h 0644 root bin +f none usr/include/mps/cmst.h 0644 root bin +f none usr/include/mps/crmf.h 0644 root bin +f none usr/include/mps/crmft.h 0644 root bin +f none usr/include/mps/cryptohi.h 0644 root bin +f none usr/include/mps/cryptoht.h 0644 root bin +f none usr/include/mps/hasht.h 0644 root bin +f none usr/include/mps/jar-ds.h 0644 root bin +f none usr/include/mps/jar.h 0644 root bin +f none usr/include/mps/jarfile.h 0644 root bin +f none usr/include/mps/key.h 0644 root bin +f none usr/include/mps/keydbt.h 0644 root bin +f none usr/include/mps/keyhi.h 0644 root bin +f none usr/include/mps/keylow.h 0644 root bin +f none usr/include/mps/keyt.h 0644 root bin +f none usr/include/mps/keytboth.h 0644 root bin +f none usr/include/mps/keythi.h 0644 root bin +f none usr/include/mps/keytlow.h 0644 root bin +f none usr/include/mps/nss.h 0644 root bin +f none usr/include/mps/nssb64.h 0644 root bin +f none usr/include/mps/nssb64t.h 0644 root bin +f none usr/include/mps/nssbase.h 0644 root bin +f none usr/include/mps/nssbaset.h 0644 root bin +f none usr/include/mps/nssckepv.h 0644 root bin +f none usr/include/mps/nssckft.h 0644 root bin +f none usr/include/mps/nssckfw.h 0644 root bin +f none usr/include/mps/nssckfwc.h 0644 root bin +f none usr/include/mps/nssckfwt.h 0644 root bin +f none usr/include/mps/nssckg.h 0644 root bin +f none usr/include/mps/nssckmdt.h 0644 root bin +f none usr/include/mps/nssckp.h 0644 root bin +f none usr/include/mps/nssckt.h 0644 root bin +f none usr/include/mps/nsscku.h 0644 root bin +f none usr/include/mps/nssilock.h 0644 root bin +f none usr/include/mps/nsslocks.h 0644 root bin +f none usr/include/mps/nssrwlk.h 0644 root bin +f none usr/include/mps/nssrwlkt.h 0644 root bin +f none usr/include/mps/ocsp.h 0644 root bin +f none usr/include/mps/ocspt.h 0644 root bin +f none usr/include/mps/p12.h 0644 root bin +f none usr/include/mps/p12plcy.h 0644 root bin +f none usr/include/mps/p12t.h 0644 root bin +f none usr/include/mps/pk11func.h 0644 root bin +f none usr/include/mps/pk11pqg.h 0644 root bin +f none usr/include/mps/pk11sdr.h 0644 root bin +f none usr/include/mps/pkcs11.h 0644 root bin +f none usr/include/mps/pkcs11f.h 0644 root bin +f none usr/include/mps/pkcs11p.h 0644 root bin +f none usr/include/mps/pkcs11t.h 0644 root bin +f none usr/include/mps/pkcs11u.h 0644 root bin +f none usr/include/mps/pkcs12.h 0644 root bin +f none usr/include/mps/pkcs12t.h 0644 root bin +f none usr/include/mps/pkcs7t.h 0644 root bin +f none usr/include/mps/portreg.h 0644 root bin +f none usr/include/mps/pqgutil.h 0644 root bin +f none usr/include/mps/preenc.h 0644 root bin +f none usr/include/mps/secasn1.h 0644 root bin +f none usr/include/mps/secasn1t.h 0644 root bin +f none usr/include/mps/seccomon.h 0644 root bin +f none usr/include/mps/secder.h 0644 root bin +f none usr/include/mps/secdert.h 0644 root bin +f none usr/include/mps/secdig.h 0644 root bin +f none usr/include/mps/secdigt.h 0644 root bin +f none usr/include/mps/secerr.h 0644 root bin +f none usr/include/mps/sechash.h 0644 root bin +f none usr/include/mps/secitem.h 0644 root bin +f none usr/include/mps/secmime.h 0644 root bin +f none usr/include/mps/secmod.h 0644 root bin +f none usr/include/mps/secmodt.h 0644 root bin +f none usr/include/mps/secoid.h 0644 root bin +f none usr/include/mps/secoidt.h 0644 root bin +f none usr/include/mps/secpkcs5.h 0644 root bin +f none usr/include/mps/secpkcs7.h 0644 root bin +f none usr/include/mps/secport.h 0644 root bin +f none usr/include/mps/secrng.h 0644 root bin +f none usr/include/mps/secrngt.h 0644 root bin +f none usr/include/mps/smime.h 0644 root bin +f none usr/include/mps/ssl.h 0644 root bin +f none usr/include/mps/sslerr.h 0644 root bin +f none usr/include/mps/sslproto.h 0644 root bin +f none usr/include/mps/swfort.h 0644 root bin +f none usr/include/mps/swfortt.h 0644 root bin +f none usr/include/mps/watcomfx.h 0644 root bin diff --git a/security/nss/pkg/solaris/SUNWtlsdx/Makefile b/security/nss/pkg/solaris/SUNWtlsdx/Makefile new file mode 100755 index 000000000..3a1bd83b3 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsdx/Makefile @@ -0,0 +1,16 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +CORE_DEPTH = ../../../.. +include ../Makefile-devl.com + +DATAFILES += + +all:: $(FILES) +publish:: all pkg + +include ../Makefile-devl.targ diff --git a/security/nss/pkg/solaris/SUNWtlsdx/pkgdepend b/security/nss/pkg/solaris/SUNWtlsdx/pkgdepend new file mode 100755 index 000000000..831c2b37c --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsdx/pkgdepend @@ -0,0 +1,23 @@ +# Copyright 2002 Microsystems, Inc. All Rights Reserved. +# Use is subject to license terms. +# +# $Id$ +# +# This package information file defines software dependencies associated +# with the pkg. You can define three types of pkg dependencies with this file: +# P indicates a prerequisite for installation +# I indicates an incompatible package +# R indicates a reverse dependency +# <pkg.abbr> see pkginfo(4), PKG parameter +# <name> see pkginfo(4), NAME parameter +# <version> see pkginfo(4), VERSION parameter +# <arch> see pkginfo(4), ARCH parameter +# <type> <pkg.abbr> <name> +# (<arch>)<version> +# (<arch>)<version> +# ... +# <type> <pkg.abbr> <name> +# ... + +P SUNWprdx Netscape Portable Runtime Development (64-bit) +P SUNWtlsx Netscape Security Services (64-bit) diff --git a/security/nss/pkg/solaris/SUNWtlsdx/pkginfo.tmpl b/security/nss/pkg/solaris/SUNWtlsdx/pkginfo.tmpl new file mode 100755 index 000000000..cadd53c8c --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsdx/pkginfo.tmpl @@ -0,0 +1,35 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWtlsdx" +NAME="Network Security Services Development (64-bit)" +ARCH="ISA" +SUNW_ISA="sparcv9" +VERSION="NSSVERS,REV=0.0.0" +SUNW_PRODNAME="Network Security Services Development (64-bit)" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Network Security Services Files for Development (64-bit)" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/security/nss/pkg/solaris/SUNWtlsdx/prototype b/security/nss/pkg/solaris/SUNWtlsdx/prototype new file mode 100755 index 000000000..fe52f14db --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsdx/prototype @@ -0,0 +1,122 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i copyright +i pkginfo +i depend=pkgdepend +# +# source locations relative to the prototype file +# +# SUNWtlsdx +# +d none usr 0755 root sys +d none usr/include 0755 root bin +s none usr/include/mps/64=sparcv9 +d none usr/include/mps/sparcv9 0755 root bin +f none usr/include/mps/sparcv9/base64.h 0644 root bin +f none usr/include/mps/sparcv9/blapi.h 0644 root bin +f none usr/include/mps/sparcv9/blapit.h 0644 root bin +f none usr/include/mps/sparcv9/cert.h 0644 root bin +f none usr/include/mps/sparcv9/certdb.h 0644 root bin +f none usr/include/mps/sparcv9/certt.h 0644 root bin +f none usr/include/mps/sparcv9/ciferfam.h 0644 root bin +f none usr/include/mps/sparcv9/cmmf.h 0644 root bin +f none usr/include/mps/sparcv9/cmmft.h 0644 root bin +f none usr/include/mps/sparcv9/cms.h 0644 root bin +f none usr/include/mps/sparcv9/cmsreclist.h 0644 root bin +f none usr/include/mps/sparcv9/cmst.h 0644 root bin +f none usr/include/mps/sparcv9/crmf.h 0644 root bin +f none usr/include/mps/sparcv9/crmft.h 0644 root bin +f none usr/include/mps/sparcv9/cryptohi.h 0644 root bin +f none usr/include/mps/sparcv9/cryptoht.h 0644 root bin +f none usr/include/mps/sparcv9/hasht.h 0644 root bin +f none usr/include/mps/sparcv9/jar-ds.h 0644 root bin +f none usr/include/mps/sparcv9/jar.h 0644 root bin +f none usr/include/mps/sparcv9/jarfile.h 0644 root bin +f none usr/include/mps/sparcv9/key.h 0644 root bin +f none usr/include/mps/sparcv9/keydbt.h 0644 root bin +f none usr/include/mps/sparcv9/keyhi.h 0644 root bin +f none usr/include/mps/sparcv9/keylow.h 0644 root bin +f none usr/include/mps/sparcv9/keyt.h 0644 root bin +f none usr/include/mps/sparcv9/keytboth.h 0644 root bin +f none usr/include/mps/sparcv9/keythi.h 0644 root bin +f none usr/include/mps/sparcv9/keytlow.h 0644 root bin +f none usr/include/mps/sparcv9/nss.h 0644 root bin +f none usr/include/mps/sparcv9/nssb64.h 0644 root bin +f none usr/include/mps/sparcv9/nssb64t.h 0644 root bin +f none usr/include/mps/sparcv9/nssbase.h 0644 root bin +f none usr/include/mps/sparcv9/nssbaset.h 0644 root bin +f none usr/include/mps/sparcv9/nssckepv.h 0644 root bin +f none usr/include/mps/sparcv9/nssckft.h 0644 root bin +f none usr/include/mps/sparcv9/nssckfw.h 0644 root bin +f none usr/include/mps/sparcv9/nssckfwc.h 0644 root bin +f none usr/include/mps/sparcv9/nssckfwt.h 0644 root bin +f none usr/include/mps/sparcv9/nssckg.h 0644 root bin +f none usr/include/mps/sparcv9/nssckmdt.h 0644 root bin +f none usr/include/mps/sparcv9/nssckp.h 0644 root bin +f none usr/include/mps/sparcv9/nssckt.h 0644 root bin +f none usr/include/mps/sparcv9/nsscku.h 0644 root bin +f none usr/include/mps/sparcv9/nssilock.h 0644 root bin +f none usr/include/mps/sparcv9/nsslocks.h 0644 root bin +f none usr/include/mps/sparcv9/nssrwlk.h 0644 root bin +f none usr/include/mps/sparcv9/nssrwlkt.h 0644 root bin +f none usr/include/mps/sparcv9/ocsp.h 0644 root bin +f none usr/include/mps/sparcv9/ocspt.h 0644 root bin +f none usr/include/mps/sparcv9/p12.h 0644 root bin +f none usr/include/mps/sparcv9/p12plcy.h 0644 root bin +f none usr/include/mps/sparcv9/p12t.h 0644 root bin +f none usr/include/mps/sparcv9/pk11func.h 0644 root bin +f none usr/include/mps/sparcv9/pk11pqg.h 0644 root bin +f none usr/include/mps/sparcv9/pk11sdr.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs11.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs11f.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs11p.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs11t.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs11u.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs12.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs12t.h 0644 root bin +f none usr/include/mps/sparcv9/pkcs7t.h 0644 root bin +f none usr/include/mps/sparcv9/portreg.h 0644 root bin +f none usr/include/mps/sparcv9/pqgutil.h 0644 root bin +f none usr/include/mps/sparcv9/preenc.h 0644 root bin +f none usr/include/mps/sparcv9/secasn1.h 0644 root bin +f none usr/include/mps/sparcv9/secasn1t.h 0644 root bin +f none usr/include/mps/sparcv9/seccomon.h 0644 root bin +f none usr/include/mps/sparcv9/secder.h 0644 root bin +f none usr/include/mps/sparcv9/secdert.h 0644 root bin +f none usr/include/mps/sparcv9/secdig.h 0644 root bin +f none usr/include/mps/sparcv9/secdigt.h 0644 root bin +f none usr/include/mps/sparcv9/secerr.h 0644 root bin +f none usr/include/mps/sparcv9/sechash.h 0644 root bin +f none usr/include/mps/sparcv9/secitem.h 0644 root bin +f none usr/include/mps/sparcv9/secmime.h 0644 root bin +f none usr/include/mps/sparcv9/secmod.h 0644 root bin +f none usr/include/mps/sparcv9/secmodt.h 0644 root bin +f none usr/include/mps/sparcv9/secoid.h 0644 root bin +f none usr/include/mps/sparcv9/secoidt.h 0644 root bin +f none usr/include/mps/sparcv9/secpkcs5.h 0644 root bin +f none usr/include/mps/sparcv9/secpkcs7.h 0644 root bin +f none usr/include/mps/sparcv9/secport.h 0644 root bin +f none usr/include/mps/sparcv9/secrng.h 0644 root bin +f none usr/include/mps/sparcv9/secrngt.h 0644 root bin +f none usr/include/mps/sparcv9/smime.h 0644 root bin +f none usr/include/mps/sparcv9/ssl.h 0644 root bin +f none usr/include/mps/sparcv9/sslerr.h 0644 root bin +f none usr/include/mps/sparcv9/sslproto.h 0644 root bin +f none usr/include/mps/sparcv9/swfort.h 0644 root bin +f none usr/include/mps/sparcv9/swfortt.h 0644 root bin +f none usr/include/mps/sparcv9/watcomfx.h 0644 root bin diff --git a/security/nss/pkg/solaris/SUNWtlsu/Makefile b/security/nss/pkg/solaris/SUNWtlsu/Makefile new file mode 100755 index 000000000..a8aefbac1 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsu/Makefile @@ -0,0 +1,16 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +CORE_DEPTH = ../../../.. +include ../Makefile-tlsu.com + +DATAFILES += + +all:: $(FILES) +publish:: all pkg + +include ../Makefile-tlsu.targ diff --git a/security/nss/pkg/solaris/SUNWtlsu/pkgdepend b/security/nss/pkg/solaris/SUNWtlsu/pkgdepend new file mode 100755 index 000000000..8b348ba47 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsu/pkgdepend @@ -0,0 +1,22 @@ +# Copyright 2002 Microsystems, Inc. All Rights Reserved. +# Use is subject to license terms. +# +# $Id$ +# +# This package information file defines software dependencies associated +# with the pkg. You can define three types of pkg dependencies with this file: +# P indicates a prerequisite for installation +# I indicates an incompatible package +# R indicates a reverse dependency +# <pkg.abbr> see pkginfo(4), PKG parameter +# <name> see pkginfo(4), NAME parameter +# <version> see pkginfo(4), VERSION parameter +# <arch> see pkginfo(4), ARCH parameter +# <type> <pkg.abbr> <name> +# (<arch>)<version> +# (<arch>)<version> +# ... +# <type> <pkg.abbr> <name> +# ... + +P SUNWtls Netscape Security Services diff --git a/security/nss/pkg/solaris/SUNWtlsu/pkginfo.tmpl b/security/nss/pkg/solaris/SUNWtlsu/pkginfo.tmpl new file mode 100755 index 000000000..e5648316d --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsu/pkginfo.tmpl @@ -0,0 +1,34 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWtlsu" +NAME="Network Security Services Utilities" +ARCH="ISA" +VERSION="NSSVERS,REV=0.0.0" +SUNW_PRODNAME="Network Security Services Utilities" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Network Security Services Utilities Programs" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/security/nss/pkg/solaris/SUNWtlsu/prototype b/security/nss/pkg/solaris/SUNWtlsu/prototype new file mode 100755 index 000000000..2f57c370c --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsu/prototype @@ -0,0 +1,35 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i copyright +i pkginfo +i depend=pkgdepend +# +# source locations relative to the prototype file +# +# SUNWtlsu +# +d none usr 0755 root sys +d none usr/sfw 0755 root bin +d none usr/sfw/bin 0755 root bin +f none usr/sfw/bin/certutil 0755 root bin +f none usr/sfw/bin/cmsutil 0755 root bin +f none usr/sfw/bin/modutil 0755 root bin +f none usr/sfw/bin/pk12util 0755 root bin +f none usr/sfw/bin/signtool 0755 root bin +f none usr/sfw/bin/signver 0755 root bin +f none usr/sfw/bin/ssltap 0755 root bin diff --git a/security/nss/pkg/solaris/SUNWtlsux/Makefile b/security/nss/pkg/solaris/SUNWtlsux/Makefile new file mode 100755 index 000000000..a8aefbac1 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsux/Makefile @@ -0,0 +1,16 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# + +CORE_DEPTH = ../../../.. +include ../Makefile-tlsu.com + +DATAFILES += + +all:: $(FILES) +publish:: all pkg + +include ../Makefile-tlsu.targ diff --git a/security/nss/pkg/solaris/SUNWtlsux/pkgdepend b/security/nss/pkg/solaris/SUNWtlsux/pkgdepend new file mode 100755 index 000000000..ae1bf71a6 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsux/pkgdepend @@ -0,0 +1,22 @@ +# Copyright 2002 Microsystems, Inc. All Rights Reserved. +# Use is subject to license terms. +# +# $Id$ +# +# This package information file defines software dependencies associated +# with the pkg. You can define three types of pkg dependencies with this file: +# P indicates a prerequisite for installation +# I indicates an incompatible package +# R indicates a reverse dependency +# <pkg.abbr> see pkginfo(4), PKG parameter +# <name> see pkginfo(4), NAME parameter +# <version> see pkginfo(4), VERSION parameter +# <arch> see pkginfo(4), ARCH parameter +# <type> <pkg.abbr> <name> +# (<arch>)<version> +# (<arch>)<version> +# ... +# <type> <pkg.abbr> <name> +# ... + +P SUNWtlsx Netscape Security Services (64-bit) diff --git a/security/nss/pkg/solaris/SUNWtlsux/pkginfo.tmpl b/security/nss/pkg/solaris/SUNWtlsux/pkginfo.tmpl new file mode 100755 index 000000000..cc7972dc4 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsux/pkginfo.tmpl @@ -0,0 +1,34 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# +# This required package information file describes characteristics of the +# package, such as package abbreviation, full package name, package version, +# and package architecture. +# +PKG="SUNWtlsux" +NAME="Network Security Services Utilities (64-bit)" +ARCH="ISA" +VERSION="NSSVERS,REV=0.0.0" +SUNW_PRODNAME="Network Security Services Utilities (64-bit)" +SUNW_PRODVERS="RELEASE/VERSION" +SUNW_PKGTYPE="usr" +MAXINST="1000" +CATEGORY="system" +DESC="Network Security Services Utilities Programs (64-bit)" +VENDOR="Sun Microsystems, Inc." +HOTLINE="Please contact your local service provider" +EMAIL="" +CLASSES="none" +BASEDIR=/ +SUNW_PKGVERS="1.0" +#VSTOCK="<reserved by Release Engineering for package part #>" +#ISTATES="<developer defined>" +#RSTATES='<developer defined>' +#ULIMIT="<developer defined>" +#ORDER="<developer defined>" +#PSTAMP="<developer defined>" +#INTONLY="<developer defined>" diff --git a/security/nss/pkg/solaris/SUNWtlsux/prototype b/security/nss/pkg/solaris/SUNWtlsux/prototype new file mode 100755 index 000000000..4b0b33b25 --- /dev/null +++ b/security/nss/pkg/solaris/SUNWtlsux/prototype @@ -0,0 +1,37 @@ +# +# Copyright 2002 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "$Id$" +# +# This required package information file contains a list of package contents. +# The 'pkgmk' command uses this file to identify the contents of a package +# and their location on the development machine when building the package. +# Can be created via a text editor or through use of the 'pkgproto' command. + +#!search <pathname pathname ...> # where to find pkg objects +#!include <filename> # include another 'prototype' file +#!default <mode> <owner> <group> # default used if not specified on entry +#!<param>=<value> # puts parameter in pkg environment + +# packaging files +i copyright +i pkginfo +i depend=pkgdepend +# +# source locations relative to the prototype file +# +# SUNWtlsux +# +d none usr 0755 root sys +d none usr/sfw 0755 root bin +d none usr/sfw/bin 0755 root bin +s none usr/sfw/bin/64=sparcv9 +d none usr/sfw/bin/sparcv9 0755 root bin +f none usr/sfw/bin/sparcv9/certutil 0755 root bin +f none usr/sfw/bin/sparcv9/cmsutil 0755 root bin +f none usr/sfw/bin/sparcv9/modutil 0755 root bin +f none usr/sfw/bin/sparcv9/pk12util 0755 root bin +f none usr/sfw/bin/sparcv9/signtool 0755 root bin +f none usr/sfw/bin/sparcv9/signver 0755 root bin +f none usr/sfw/bin/sparcv9/ssltap 0755 root bin diff --git a/security/nss/tests/ssl/ssl.sh b/security/nss/tests/ssl/ssl.sh index 78c0c6444..a82c88429 100755 --- a/security/nss/tests/ssl/ssl.sh +++ b/security/nss/tests/ssl/ssl.sh @@ -127,7 +127,7 @@ wait_for_selfserv() html_failed "<TR><TD> Wait for Server " echo "RETRY: tstclnt -p ${PORT} -h ${HOST} -q -d . < ${REQUEST_FILE}" tstclnt -p ${PORT} -h ${HOST} -q -d . < ${REQUEST_FILE} - elif [ sparam = "-c ABCDEFabcdefghijklm" ] ; then # "$1" = "cov" ] ; then + elif [ sparam = "-c ABCDEFabcdefghijklmnvy" ] ; then # "$1" = "cov" ] ; then html_passed "<TR><TD> Wait for Server" fi is_selfserv_alive @@ -180,7 +180,7 @@ ssl_cov() html_head "SSL Cipher Coverage" testname="" - sparam="-c ABCDEFabcdefghijklm" + sparam="-c ABCDEFabcdefghijklmnvy" start_selfserv # Launch the server cat ${SSLCOV} | while read tls param testname diff --git a/security/nss/tests/ssl/sslcov.txt b/security/nss/tests/ssl/sslcov.txt index 8df8f4f2c..e60e06d28 100644 --- a/security/nss/tests/ssl/sslcov.txt +++ b/security/nss/tests/ssl/sslcov.txt @@ -35,3 +35,10 @@ # (NULL is not enabled by default) TLS i TLS RSA WITH NULL MD5 noTLS i SSL3 RSA WITH NULL MD5 +# added on nelson's request + TLS n TLS RSA WITH RC4 128 SHA + noTLS n SSL3 RSA WITH RC4 128 SHA + TLS v TLS RSA WITH AES 128 CBC SHA + noTLS v SSL3 RSA WITH AES 128 CBC SHA + TLS y TLS RSA WITH AES 256 CBC SHA + noTLS y SSL3 RSA WITH AES 256 CBC SHA |