summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsaul.edwards%sun.com <devnull@localhost>2003-12-10 22:18:16 +0000
committersaul.edwards%sun.com <devnull@localhost>2003-12-10 22:18:16 +0000
commita2c774e24f030c9d522432380cb5782a90e5c3e4 (patch)
treed2fd3a60e51b4ea797f292893e8309e307b0396a
parent421562498d32729fe5f6113316b6100e72ff94bc (diff)
downloadnss-hg-a2c774e24f030c9d522432380cb5782a90e5c3e4.tar.gz
Bringing 3.3.4.2 up to date with 3.3.8; neuter the cert7 upgrade.
-rw-r--r--security/nss/Makefile10
-rw-r--r--security/nss/cmd/platlibs.mk4
-rw-r--r--security/nss/cmd/selfserv/selfserv.c78
-rw-r--r--security/nss/cmd/signtool/util.c11
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c11
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c22
-rw-r--r--security/nss/lib/certdb/alg1485.c3
-rw-r--r--security/nss/lib/certdb/cdbhdl.h4
-rw-r--r--security/nss/lib/certdb/certdb.h6
-rw-r--r--security/nss/lib/certdb/dbmshim.c671
-rw-r--r--security/nss/lib/certdb/genname.c555
-rw-r--r--security/nss/lib/certdb/manifest.mn1
-rw-r--r--security/nss/lib/certdb/pcertdb.c259
-rw-r--r--security/nss/lib/certdb/secname.c92
-rw-r--r--security/nss/lib/cryptohi/seckey.c11
-rw-r--r--security/nss/lib/freebl/Makefile1
-rw-r--r--security/nss/lib/freebl/md5.c248
-rw-r--r--security/nss/lib/freebl/prng_fips1861.c2
-rw-r--r--security/nss/lib/freebl/rijndael.c263
-rw-r--r--security/nss/lib/freebl/rsa.c3
-rw-r--r--security/nss/lib/freebl/sha_fast.c3
-rw-r--r--security/nss/lib/nss/nssinit.c17
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c129
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c35
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h6
-rw-r--r--security/nss/lib/pkcs7/p7decode.c5
-rw-r--r--security/nss/lib/softoken/alghmac.c6
-rw-r--r--security/nss/lib/softoken/alghmac.h3
-rw-r--r--security/nss/lib/softoken/pkcs11.c88
-rw-r--r--security/nss/lib/softoken/pkcs11c.c112
-rw-r--r--security/nss/lib/softoken/pkcs11i.h77
-rw-r--r--security/nss/lib/softoken/pkcs11u.c40
-rw-r--r--security/nss/lib/ssl/ssl3con.c57
-rw-r--r--security/nss/lib/ssl/sslenum.c8
-rw-r--r--security/nss/lib/ssl/sslimpl.h5
-rw-r--r--security/nss/lib/ssl/sslproto.h16
-rw-r--r--security/nss/lib/ssl/sslsock.c6
-rw-r--r--security/nss/lib/util/secasn1d.c606
-rw-r--r--security/nss/lib/util/secasn1t.h2
-rw-r--r--security/nss/lib/util/secitem.c18
-rw-r--r--security/nss/lib/util/secoid.c74
-rw-r--r--security/nss/lib/util/secoidt.h17
-rw-r--r--security/nss/pkg/linux/Makefile28
-rw-r--r--security/nss/pkg/linux/sun-nss.spec5
-rw-r--r--security/nss/pkg/solaris/Makefile40
-rwxr-xr-xsecurity/nss/pkg/solaris/Makefile-devl.com33
-rwxr-xr-xsecurity/nss/pkg/solaris/Makefile-devl.targ26
-rwxr-xr-xsecurity/nss/pkg/solaris/Makefile-tlsu.com33
-rwxr-xr-xsecurity/nss/pkg/solaris/Makefile-tlsu.targ26
-rw-r--r--security/nss/pkg/solaris/Makefile.com3
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsd/Makefile16
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsd/pkgdepend23
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsd/pkginfo.tmpl34
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsd/prototype121
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsdx/Makefile16
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsdx/pkgdepend23
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsdx/pkginfo.tmpl35
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsdx/prototype122
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsu/Makefile16
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsu/pkgdepend22
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsu/pkginfo.tmpl34
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsu/prototype35
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsux/Makefile16
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsux/pkgdepend22
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsux/pkginfo.tmpl34
-rwxr-xr-xsecurity/nss/pkg/solaris/SUNWtlsux/prototype37
-rwxr-xr-xsecurity/nss/tests/ssl/ssl.sh4
-rw-r--r--security/nss/tests/ssl/sslcov.txt7
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, &current->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, &current->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, &current->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, &current->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,
+ &current->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, &current->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