summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrrelyea%redhat.com <devnull@localhost>2009-10-27 23:04:48 +0000
committerrrelyea%redhat.com <devnull@localhost>2009-10-27 23:04:48 +0000
commitfe21f07bc83703b442b0d91e77baf513800e27d4 (patch)
treefa80e0e267470079410c4e5efd3b31ef84dd13c8
parenta6ad5b0e66b95300ec49255465617f1ac462b38b (diff)
downloadnss-hg-fe21f07bc83703b442b0d91e77baf513800e27d4.tar.gz
Bug 453495 - Add new ref counted NSS_Shutdown-like function
r=nelson
-rw-r--r--security/nss/cmd/manifest.mn1
-rw-r--r--security/nss/cmd/multinit/Makefile79
-rw-r--r--security/nss/cmd/multinit/manifest.mn45
-rw-r--r--security/nss/cmd/multinit/multinit.c940
-rw-r--r--security/nss/lib/nss/nss.def3
-rw-r--r--security/nss/lib/nss/nss.h89
-rw-r--r--security/nss/lib/nss/nssinit.c612
-rw-r--r--security/nss/lib/pk11wrap/pk11load.c44
-rw-r--r--security/nss/lib/pk11wrap/pk11pars.c373
-rw-r--r--security/nss/lib/pk11wrap/pk11priv.h1
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c52
-rw-r--r--security/nss/lib/pk11wrap/secmodi.h15
-rwxr-xr-xsecurity/nss/tests/all.sh4
-rwxr-xr-xsecurity/nss/tests/multinit/multinit.sh191
-rw-r--r--security/nss/tests/multinit/multinit.txt79
-rw-r--r--security/nss/tests/tools/tools.sh34
16 files changed, 2320 insertions, 242 deletions
diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn
index d1b83e595..dc7c8a777 100644
--- a/security/nss/cmd/manifest.mn
+++ b/security/nss/cmd/manifest.mn
@@ -56,6 +56,7 @@ DIRS = lib \
digest \
fipstest \
makepqg \
+ multinit \
ocspclnt \
oidcalc \
p7content \
diff --git a/security/nss/cmd/multinit/Makefile b/security/nss/cmd/multinit/Makefile
new file mode 100644
index 000000000..9ee2a8f00
--- /dev/null
+++ b/security/nss/cmd/multinit/Makefile
@@ -0,0 +1,79 @@
+#! gmake
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#######################################################################
+# (1) Include initial platform-independent assignments (MANDATORY). #
+#######################################################################
+
+include manifest.mn
+
+#######################################################################
+# (2) Include "global" configuration information. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/config.mk
+
+#######################################################################
+# (3) Include "component" configuration information. (OPTIONAL) #
+#######################################################################
+
+#######################################################################
+# (4) Include "local" platform-dependent assignments (OPTIONAL). #
+#######################################################################
+
+include ../platlibs.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+include ../platrules.mk
+
diff --git a/security/nss/cmd/multinit/manifest.mn b/security/nss/cmd/multinit/manifest.mn
new file mode 100644
index 000000000..78867987e
--- /dev/null
+++ b/security/nss/cmd/multinit/manifest.mn
@@ -0,0 +1,45 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Red Hat, Inc.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+CORE_DEPTH = ../../..
+
+# MODULE public and private header directories are implicitly REQUIRED.
+MODULE = nss
+
+CSRCS = multinit.c
+
+PROGRAM = multinit
diff --git a/security/nss/cmd/multinit/multinit.c b/security/nss/cmd/multinit/multinit.c
new file mode 100644
index 000000000..c6ab216a7
--- /dev/null
+++ b/security/nss/cmd/multinit/multinit.c
@@ -0,0 +1,940 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Red Hat, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "nss.h"
+#include "secutil.h"
+#include "pk11pub.h"
+#include "cert.h"
+
+typedef struct commandDescriptStr {
+ int required;
+ char *arg;
+ char *des;
+} commandDescript;
+
+enum optionNames {
+ opt_liborder = 0,
+ opt_mainDB,
+ opt_lib1DB,
+ opt_lib2DB,
+ opt_mainRO,
+ opt_lib1RO,
+ opt_lib2RO,
+ opt_mainCMD,
+ opt_lib1CMD,
+ opt_lib2CMD,
+ opt_mainTokNam,
+ opt_lib1TokNam,
+ opt_lib2TokNam,
+ opt_oldStyle,
+ opt_verbose,
+ opt_summary,
+ opt_help,
+ opt_last
+};
+
+
+static const
+secuCommandFlag options_init[] =
+{
+ { /* opt_liborder */ 'o', PR_TRUE, "1M2zmi", PR_TRUE, "order" },
+ { /* opt_mainDB */ 'd', PR_TRUE, 0, PR_FALSE, "main_db" },
+ { /* opt_lib1DB */ '1', PR_TRUE, 0, PR_FALSE, "lib1_db" },
+ { /* opt_lib2DB */ '2', PR_TRUE, 0, PR_FALSE, "lib2_db" },
+ { /* opt_mainRO */ 'r', PR_FALSE, 0, PR_FALSE, "main_readonly" },
+ { /* opt_lib1RO */ 0, PR_FALSE, 0, PR_FALSE, "lib1_readonly" },
+ { /* opt_lib2RO */ 0, PR_FALSE, 0, PR_FALSE, "lib2_readonly" },
+ { /* opt_mainCMD */ 'c', PR_TRUE, 0, PR_FALSE, "main_command" },
+ { /* opt_lib1CMD */ 0, PR_TRUE, 0, PR_FALSE, "lib1_command" },
+ { /* opt_lib2CMD */ 0, PR_TRUE, 0, PR_FALSE, "lib2_command" },
+ { /* opt_mainTokNam */'t', PR_TRUE, 0, PR_FALSE, "main_token_name" },
+ { /* opt_lib1TokNam */ 0, PR_TRUE, 0, PR_FALSE, "lib1_token_name" },
+ { /* opt_lib2TokNam */ 0, PR_TRUE, 0, PR_FALSE, "lib2_token_name" },
+ { /* opt_oldStype */ 's', PR_FALSE, 0, PR_FALSE, "oldStype" },
+ { /* opt_verbose */ 'v', PR_FALSE, 0, PR_FALSE, "verbose" },
+ { /* opt_summary */ 'z', PR_FALSE, 0, PR_FALSE, "summary" },
+ { /* opt_help */ 'h', PR_FALSE, 0, PR_FALSE, "help" }
+};
+
+static const
+commandDescript options_des[] =
+{
+ { /* opt_liborder */ PR_FALSE, "initOrder",
+ " Specifies the order of NSS initialization and shutdown. Order is\n"
+ " given as a string where each character represents either an init or\n"
+ " a shutdown of the main program or one of the 2 test libraries\n"
+ " (library 1 and library 2). The valid characters are as follows:\n"
+ " M Init the main program\n 1 Init library 1\n"
+ " 2 Init library 2\n"
+ " m Shutdown the main program\n i Shutdown library 1\n"
+ " z Shutdown library 2\n" },
+ { /* opt_mainDB */ PR_TRUE, "nss_db",
+ " Specified the directory to open the nss database for the main\n"
+ " program. Must be specified if \"M\" is given in the order string\n"},
+ { /* opt_lib1DB */ PR_FALSE, "nss_db",
+ " Specified the directory to open the nss database for library 1.\n"
+ " Must be specified if \"1\" is given in the order string\n"},
+ { /* opt_lib2DB */ PR_FALSE, "nss_db",
+ " Specified the directory to open the nss database for library 2.\n"
+ " Must be specified if \"2\" is given in the order string\n"},
+ { /* opt_mainRO */ PR_FALSE, NULL,
+ " Open the main program's database read only.\n" },
+ { /* opt_lib1RO */ PR_FALSE, NULL,
+ " Open library 1's database read only.\n" },
+ { /* opt_lib2RO */ PR_FALSE, NULL,
+ " Open library 2's database read only.\n" },
+ { /* opt_mainCMD */ PR_FALSE, "nss_command",
+ " Specifies the NSS command to execute in the main program.\n"
+ " Valid commands are: \n"
+ " key_slot, list_slots, list_certs, add_cert, none.\n"
+ " Default is \"none\".\n" },
+ { /* opt_lib1CMD */ PR_FALSE, "nss_command",
+ " Specifies the NSS command to execute in library 1.\n" },
+ { /* opt_lib2CMD */ PR_FALSE, "nss_command",
+ " Specifies the NSS command to execute in library 2.\n" },
+ { /* opt_mainTokNam */PR_FALSE, "token_name",
+ " Specifies the name of PKCS11 token for the main program's "
+ "database.\n" },
+ { /* opt_lib1TokNam */PR_FALSE, "token_name",
+ " Specifies the name of PKCS11 token for library 1's database.\n" },
+ { /* opt_lib2TokNam */PR_FALSE, "token_name",
+ " Specifies the name of PKCS11 token for library 2's database.\n" },
+ { /* opt_oldStype */ PR_FALSE, NULL,
+ " Use NSS_Shutdown rather than NSS_ShutdownContext in the main\n"
+ " program.\n" },
+ { /* opt_verbose */ PR_FALSE, NULL,
+ " Noisily output status to standard error\n" },
+ { /* opt_summarize */ PR_FALSE, NULL,
+ "report a summary of the test results\n" },
+ { /* opt_help */ PR_FALSE, NULL, " give this message\n" }
+};
+
+/*
+ * output our short help (table driven). (does not exit).
+ */
+static void
+short_help(const char *prog)
+{
+ int count = opt_last;
+ int i,words_found;
+
+ /* make sure all the tables are up to date before we allow compiles to
+ * succeed */
+ PR_STATIC_ASSERT(sizeof(options_init)/sizeof(secuCommandFlag) == opt_last);
+ PR_STATIC_ASSERT(sizeof(options_init)/sizeof(secuCommandFlag) ==
+ sizeof(options_des)/sizeof(commandDescript));
+
+ /* print the base usage */
+ fprintf(stderr,"usage: %s ",prog);
+ for (i=0, words_found=0; i < count; i++) {
+ if (!options_des[i].required) {
+ fprintf(stderr,"[");
+ }
+ if (options_init[i].longform) {
+ fprintf(stderr, "--%s", options_init[i].longform);
+ words_found++;
+ } else {
+ fprintf(stderr, "-%c", options_init[i].flag);
+ }
+ if (options_init[i].needsArg) {
+ if (options_des[i].arg) {
+ fprintf(stderr," %s",options_des[i].arg);
+ } else {
+ fprintf(stderr," arg");
+ }
+ words_found++;
+ }
+ if (!options_des[i].required) {
+ fprintf(stderr,"]");
+ }
+ if (i < count-1 ) {
+ if (words_found >= 5) {
+ fprintf(stderr,"\n ");
+ words_found=0;
+ } else {
+ fprintf(stderr," ");
+ }
+ }
+ }
+ fprintf(stderr,"\n");
+}
+
+/*
+ * print out long help. like short_help, this does not exit
+ */
+static void
+long_help(const char *prog)
+{
+ int i;
+ int count = opt_last;
+
+ short_help(prog);
+ /* print the option descriptions */
+ fprintf(stderr,"\n");
+ for (i=0; i < count; i++) {
+ fprintf(stderr," ");
+ if (options_init[i].flag) {
+ fprintf(stderr, "-%c", options_init[i].flag);
+ if (options_init[i].longform) {
+ fprintf(stderr,",");
+ }
+ }
+ if (options_init[i].longform) {
+ fprintf(stderr,"--%s", options_init[i].longform);
+ }
+ if (options_init[i].needsArg) {
+ if (options_des[i].arg) {
+ fprintf(stderr," %s",options_des[i].arg);
+ } else {
+ fprintf(stderr," arg");
+ }
+ if (options_init[i].arg) {
+ fprintf(stderr," (default = \"%s\")",options_init[i].arg);
+ }
+ }
+ fprintf(stderr,"\n%s",options_des[i].des);
+ }
+}
+
+/*
+ * record summary data
+ */
+struct bufferData {
+ char * data; /* lowest address of the buffer */
+ char * next; /* pointer to the next element on the buffer */
+ int len; /* length of the buffer */
+};
+
+/* our actual buffer. If data is NULL, then all append ops
+ * except are noops */
+static struct bufferData buffer= { NULL, NULL, 0 };
+
+#define CHUNK_SIZE 1000
+
+/*
+ * get our initial data. and set the buffer variables up. on failure,
+ * just don't initialize the buffer.
+ */
+static void
+initBuffer(void)
+{
+ buffer.data = PORT_Alloc(CHUNK_SIZE);
+ if (!buffer.data) {
+ return;
+ }
+ buffer.next = buffer.data;
+ buffer.len = CHUNK_SIZE;
+}
+
+/*
+ * grow the buffer. If we can't get more data, record a 'D' in the second
+ * to last record and allow the rest of the data to overwrite the last
+ * element.
+ */
+static void
+growBuffer(void)
+{
+ char *new = PORT_Realloc(buffer.data, buffer.len + CHUNK_SIZE);
+ if (!new) {
+ buffer.data[buffer.len-2] = 'D'; /* signal malloc failure in summary */
+ /* buffer must always point to good memory if it exists */
+ buffer.next = buffer.data + (buffer.len -1);
+ return;
+ }
+ buffer.next = new + (buffer.next-buffer.data);
+ buffer.data = new;
+ buffer.len += CHUNK_SIZE;
+}
+
+/*
+ * append a label, doubles as appending a single character.
+ */
+static void
+appendLabel(char label)
+{
+ if (!buffer.data) {
+ return;
+ }
+
+ *buffer.next++ = label;
+ if (buffer.data+buffer.len >= buffer.next) {
+ growBuffer();
+ }
+}
+
+/*
+ * append a string onto the buffer. The result will be <string>
+ */
+static void
+appendString(char *string)
+{
+ if (!buffer.data) {
+ return;
+ }
+
+ appendLabel('<');
+ while (*string) {
+ appendLabel(*string++);
+ }
+ appendLabel('>');
+}
+
+/*
+ * append a bool, T= true, F=false
+ */
+static void
+appendBool(PRBool bool)
+{
+ if (!buffer.data) {
+ return;
+ }
+
+ if (bool) {
+ appendLabel('t');
+ } else {
+ appendLabel('f');
+ }
+}
+
+/*
+ * append a single hex nibble.
+ */
+static void
+appendHex(unsigned char nibble)
+{
+ if (nibble <= 9) {
+ appendLabel('0'+nibble);
+ } else {
+ appendLabel('a'+nibble-10);
+ }
+}
+
+/*
+ * append a secitem as colon separated hex bytes.
+ */
+static void
+appendItem(SECItem *item)
+{
+ int i;
+
+ if (!buffer.data) {
+ return;
+ }
+
+ appendLabel(':');
+ for (i=0; i < item->len; i++) {
+ unsigned char byte=item->data[i];
+ appendHex(byte >> 4);
+ appendHex(byte & 0xf);
+ appendLabel(':');
+ }
+}
+
+/*
+ * append a 32 bit integer (even on a 64 bit platform).
+ * for simplicity append it as a hex value, full extension with 0x prefix.
+ */
+static void
+appendInt(unsigned int value)
+{
+ int i;
+
+ if (!buffer.data) {
+ return;
+ }
+
+ appendLabel('0');
+ appendLabel('x');
+ value = value & 0xffffffff; /* only look at the buttom 8 bytes */
+ for (i=0; i < 8; i++) {
+ appendHex(value >> 28 );
+ value = value << 4;
+ }
+}
+
+/* append a trust flag */
+static void
+appendFlags(unsigned int flag)
+{
+ char trust[10];
+ char *cp=trust;
+
+ trust[0] = 0;
+ printflags(trust, flag);
+ while (*cp) {
+ appendLabel(*cp++);
+ }
+}
+
+/*
+ * dump our buffer out with a result= flag so we can find it easily.
+ * free the buffer as a side effect.
+ */
+static void
+dumpBuffer(void)
+{
+ if (!buffer.data) {
+ return;
+ }
+
+ appendLabel(0); /* terminate */
+ printf("\nresult=%s\n",buffer.data);
+ PORT_Free(buffer.data);
+ buffer.data = buffer.next = NULL;
+ buffer.len = 0;
+}
+
+
+/*
+ * usage, like traditional usage, automatically exit
+ */
+static void
+usage(const char *prog)
+{
+ short_help(prog);
+ dumpBuffer();
+ exit(1);
+}
+
+/*
+ * like usage, except prints the long version of help
+ */
+static void
+usage_long(const char *prog)
+{
+ long_help(prog);
+ dumpBuffer();
+ exit(1);
+}
+
+static const char *
+bool2String(PRBool bool)
+{
+ return bool ? "true" : "false";
+}
+
+/*
+ * print out interesting info about the given slot
+ */
+void
+print_slot(PK11SlotInfo *slot, int log)
+{
+ if (log) {
+ fprintf(stderr, "* Name=%s Token_Name=%s present=%s, ro=%s *\n",
+ PK11_GetSlotName(slot), PK11_GetTokenName(slot),
+ bool2String(PK11_IsPresent(slot)),
+ bool2String(PK11_IsReadOnly(slot)));
+ }
+ appendLabel('S');
+ appendString(PK11_GetTokenName(slot));
+ appendBool(PK11_IsPresent(slot));
+ appendBool(PK11_IsReadOnly(slot));
+}
+
+/*
+ * list all our slots
+ */
+void
+do_list_slots(const char *progName, int log)
+{
+ PK11SlotList *list;
+ PK11SlotListElement *le;
+
+ list= PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL);
+ if (list == NULL) {
+ fprintf(stderr,"ERROR: no tokens found %s\n",
+ SECU_Strerror(PORT_GetError()));
+ appendLabel('S');
+ appendString("none");
+ return;
+ }
+
+ for (le= PK11_GetFirstSafe(list); le;
+ le = PK11_GetNextSafe(list,le,PR_TRUE)) {
+ print_slot(le->slot, log);
+ }
+ PK11_FreeSlotList(list);
+}
+
+static PRBool
+sort_CN(CERTCertificate *certa, CERTCertificate *certb, void *arg)
+{
+ char *commonNameA, *commonNameB;
+ int ret;
+
+ commonNameA = CERT_GetCommonName(&certa->subject);
+ commonNameB = CERT_GetCommonName(&certb->subject);
+
+ if (commonNameA == NULL) {
+ PORT_Free(commonNameB);
+ return PR_TRUE;
+ }
+ if (commonNameB == NULL) {
+ PORT_Free(commonNameA);
+ return PR_FALSE;
+ }
+ ret = PORT_Strcmp(commonNameA,commonNameB);
+ PORT_Free(commonNameA);
+ PORT_Free(commonNameB);
+ return (ret < 0) ? PR_TRUE: PR_FALSE;
+}
+
+/*
+ * list all the certs
+ */
+void
+do_list_certs(const char *progName, int log)
+{
+ CERTCertList *list;
+ CERTCertList *sorted;
+ CERTCertListNode *node;
+ int i;
+
+ list = PK11_ListCerts(PK11CertListUnique, NULL);
+ if (list == NULL) {
+ fprintf(stderr,"ERROR: no certs found %s\n",
+ SECU_Strerror(PORT_GetError()));
+ appendLabel('C');
+ appendString("none");
+ return;
+ }
+
+ sorted = CERT_NewCertList();
+ if (sorted == NULL) {
+ fprintf(stderr,"ERROR: no certs found %s\n",
+ SECU_Strerror(PORT_GetError()));
+ appendLabel('C');
+ appendLabel('E');
+ appendInt(PORT_GetError());
+ return;
+ }
+
+ /* sort the list */
+ for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node,list);
+ node = CERT_LIST_NEXT(node)) {
+ CERT_AddCertToListSorted(sorted, node->cert, sort_CN, NULL);
+ }
+
+
+ for (node = CERT_LIST_HEAD(sorted); !CERT_LIST_END(node,sorted);
+ node = CERT_LIST_NEXT(node)) {
+ CERTCertificate *cert = node->cert;
+ char *commonName;
+
+ SECU_PrintCertNickname(node, stderr);
+ if (log) {
+ fprintf(stderr, "* Slot=%s*\n", cert->slot ?
+ PK11_GetTokenName(cert->slot) : "none");
+ fprintf(stderr, "* Nickname=%s*\n", cert->nickname);
+ fprintf(stderr, "* Subject=<%s>*\n", cert->subjectName);
+ fprintf(stderr, "* Issuer=<%s>*\n", cert->issuerName);
+ fprintf(stderr, "* SN=");
+ for (i=0; i < cert->serialNumber.len; i++) {
+ if (i!=0) fprintf(stderr,":");
+ fprintf(stderr, "%02x",cert->serialNumber.data[0]);
+ }
+ fprintf(stderr," *\n");
+ }
+ appendLabel('C');
+ commonName = CERT_GetCommonName(&cert->subject);
+ appendString(commonName?commonName:"*NoName*");
+ PORT_Free(commonName);
+ if (cert->trust) {
+ appendFlags(cert->trust->sslFlags);
+ appendFlags(cert->trust->emailFlags);
+ appendFlags(cert->trust->objectSigningFlags);
+ }
+ }
+ CERT_DestroyCertList(list);
+
+}
+
+/*
+ * need to implement yet... try to add a new certificate
+ */
+void
+do_add_cert(const char *progName, int log)
+{
+ PORT_Assert(/* do_add_cert not implemented */ 0);
+}
+
+/*
+ * display the current key slot
+ */
+void
+do_key_slot(const char *progName, int log)
+{
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ if (!slot) {
+ fprintf(stderr,"ERROR: no internal key slot found %s\n",
+ SECU_Strerror(PORT_GetError()));
+ appendLabel('K');
+ appendLabel('S');
+ appendString("none");
+ }
+ print_slot(slot, log);
+ PK11_FreeSlot(slot);
+}
+
+/*
+ * execute some NSS command.
+ */
+void
+do_command(const char *label, int initialized, secuCommandFlag *command,
+ const char *progName, int log)
+{
+ char * command_string;
+ if (!initialized) {
+ return;
+ }
+
+ if (command->activated) {
+ command_string = command->arg;
+ } else {
+ command_string = "none";
+ }
+
+ if (log) {
+ fprintf(stderr, "*Executing nss command \"%s\" for %s*\n",
+ command_string,label);
+ }
+
+ /* do something */
+ if (strcasecmp(command_string, "list_slots") == 0) {
+ do_list_slots(progName, log);
+ } else if (strcasecmp(command_string, "list_certs") == 0) {
+ do_list_certs(progName, log);
+ } else if (strcasecmp(command_string, "add_cert") == 0) {
+ do_add_cert(progName, log);
+ } else if (strcasecmp(command_string, "key_slot") == 0) {
+ do_key_slot(progName, log);
+ } else if (strcasecmp(command_string, "none") != 0) {
+ fprintf(stderr, ">> Unknown command (%s)\n", command_string);
+ appendLabel('E');
+ appendString("bc");
+ usage_long(progName);
+ }
+
+}
+
+
+/*
+ * functions do handle
+ * different library initializations.
+ */
+static int main_initialized;
+static int lib1_initialized;
+static int lib2_initialized;
+
+void
+main_Init(secuCommandFlag *db, secuCommandFlag *tokNam,
+ int readOnly, const char *progName, int log)
+{
+ SECStatus rv;
+ if (log) {
+ fprintf(stderr,"*NSS_Init for the main program*\n");
+ }
+ appendLabel('M');
+ if (!db->activated) {
+ fprintf(stderr, ">> No main_db has been specified\n");
+ usage(progName);
+ }
+ if (main_initialized) {
+ fprintf(stderr,"Warning: Second initialization of Main\n");
+ appendLabel('E');
+ appendString("2M");
+ }
+ if (tokNam->activated) {
+ PK11_ConfigurePKCS11(NULL, NULL, NULL, tokNam->arg,
+ NULL, NULL, NULL, NULL, 0, 0);
+ }
+ rv = NSS_Initialize(db->arg, "", "", "",
+ NSS_INIT_NOROOTINIT|(readOnly?NSS_INIT_READONLY:0));
+ if (rv != SECSuccess) {
+ appendLabel('E');
+ appendInt(PORT_GetError());
+ fprintf(stderr,">> %s\n", SECU_Strerror(PORT_GetError()));
+ dumpBuffer();
+ exit(1);
+ }
+ main_initialized = 1;
+}
+
+void
+main_Do(secuCommandFlag *command, const char *progName, int log)
+{
+ do_command("main", main_initialized, command, progName, log);
+}
+
+void
+main_Shutdown(int old_style, const char *progName, int log)
+{
+ SECStatus rv;
+ appendLabel('N');
+ if (log) {
+ fprintf(stderr,"*NSS_Shutdown for the main program*\n");
+ }
+ if (!main_initialized) {
+ fprintf(stderr,"Warning: Main shutdown without corresponding init\n");
+ }
+ if (old_style) {
+ rv = NSS_Shutdown();
+ } else {
+ rv = NSS_ShutdownContext(NULL);
+ }
+ fprintf(stderr, "Shutdown main state = %d\n", rv);
+ if (rv != SECSuccess) {
+ appendLabel('E');
+ appendInt(PORT_GetError());
+ fprintf(stderr,"ERROR: %s\n", SECU_Strerror(PORT_GetError()));
+ }
+ main_initialized = 0;
+}
+
+/* common library init */
+NSSInitContext *
+lib_Init(const char *lableString, char label, int initialized,
+ secuCommandFlag *db, secuCommandFlag *tokNam, int readonly,
+ const char *progName, int log)
+{
+ NSSInitContext *ctxt;
+ NSSInitParameters initStrings;
+ NSSInitParameters *initStringPtr = NULL;
+
+ appendLabel(label);
+ if (log) {
+ fprintf(stderr,"*NSS_Init for %s*\n", lableString);
+ }
+
+ if (!db->activated) {
+ fprintf(stderr, ">> No %s_db has been specified\n", lableString);
+ usage(progName);
+ }
+ if (initialized) {
+ fprintf(stderr,"Warning: Second initialization of %s\n", lableString);
+ }
+ if (tokNam->activated) {
+ PORT_Memset(&initStrings, 0, sizeof(initStrings));
+ initStrings.length = sizeof(initStrings);
+ initStrings.dbTokenDescription = tokNam->arg;
+ initStringPtr = &initStrings;
+ }
+ ctxt = NSS_InitContext(db->arg, "", "", "", initStringPtr,
+ NSS_INIT_NOROOTINIT|(readonly?NSS_INIT_READONLY:0));
+ if (ctxt == NULL) {
+ appendLabel('E');
+ appendInt(PORT_GetError());
+ fprintf(stderr,">> %s\n",SECU_Strerror(PORT_GetError()));
+ dumpBuffer();
+ exit(1);
+ }
+ return ctxt;
+}
+
+/* common library shutdown */
+void
+lib_Shutdown(const char *labelString, char label, NSSInitContext *ctx,
+ int initialize, const char *progName, int log)
+{
+ SECStatus rv;
+ appendLabel(label);
+ if (log) {
+ fprintf(stderr,"*NSS_Shutdown for %s\n*", labelString);
+ }
+ if (!initialize) {
+ fprintf(stderr,"Warning: %s shutdown without corresponding init\n",
+ labelString);
+ }
+ rv = NSS_ShutdownContext(ctx);
+ fprintf(stderr, "Shutdown %s state = %d\n", labelString, rv);
+ if (rv != SECSuccess) {
+ appendLabel('E');
+ appendInt(PORT_GetError());
+ fprintf(stderr,"ERROR: %s\n", SECU_Strerror(PORT_GetError()));
+ }
+}
+
+
+static NSSInitContext *lib1_context;
+static NSSInitContext *lib2_context;
+void
+lib1_Init(secuCommandFlag *db, secuCommandFlag *tokNam,
+ int readOnly, const char *progName, int log)
+{
+ lib1_context = lib_Init("lib1", '1', lib1_initialized, db, tokNam,
+ readOnly, progName, log);
+ lib1_initialized = 1;
+}
+
+void
+lib2_Init(secuCommandFlag *db, secuCommandFlag *tokNam,
+ int readOnly, const char *progName, int log)
+{
+ lib2_context = lib_Init("lib2", '2', lib2_initialized,
+ db, tokNam, readOnly, progName, log);
+ lib2_initialized = 1;
+}
+
+void
+lib1_Do(secuCommandFlag *command, const char *progName, int log)
+{
+ do_command("lib1", lib1_initialized, command, progName, log);
+}
+
+void
+lib2_Do(secuCommandFlag *command, const char *progName, int log)
+{
+ do_command("lib2", lib2_initialized, command, progName, log);
+}
+
+void
+lib1_Shutdown(const char *progName, int log)
+{
+ lib_Shutdown("lib1", 'I', lib1_context, lib1_initialized, progName, log);
+ lib1_initialized = 0;
+ /* don't clear lib1_Context, so we can test multiple attempts to close
+ * the same context produces correct errors*/
+}
+
+void
+lib2_Shutdown(const char *progName, int log)
+{
+ lib_Shutdown("lib2", 'Z', lib2_context, lib2_initialized, progName, log);
+ lib2_initialized = 0;
+ /* don't clear lib2_Context, so we can test multiple attempts to close
+ * the same context produces correct errors*/
+}
+
+int
+main(int argc, char **argv)
+{
+ SECStatus rv;
+ secuCommand libinit;
+ char *progName;
+ char *order;
+ secuCommandFlag *options;
+ int log = 0;
+
+ progName = strrchr(argv[0], '/');
+ progName = progName ? progName+1 : argv[0];
+
+ libinit.numCommands = 0;
+ libinit.commands = 0;
+ libinit.numOptions = opt_last;
+ options = (secuCommandFlag *)PORT_Alloc(sizeof(options_init));
+ if (options == NULL) {
+ fprintf(stderr, ">> %s:Not enough free memory to run command\n",
+ progName);
+ exit(1);
+ }
+ PORT_Memcpy(options, options_init, sizeof(options_init));
+ libinit.options = options;
+
+ rv = SECU_ParseCommandLine(argc, argv, progName, & libinit);
+ if (rv != SECSuccess) {
+ usage(progName);
+ }
+
+ if (libinit.options[opt_help].activated) {
+ long_help(progName);
+ exit (0);
+ }
+
+ log = libinit.options[opt_verbose].activated;
+ if (libinit.options[opt_summary].activated) {
+ initBuffer();
+ }
+
+ order = libinit.options[opt_liborder].arg;
+ if (!order) {
+ usage(progName);
+ }
+
+ if (log) {
+ fprintf(stderr,"* initializing with order \"%s\"*\n", order);
+ }
+
+ for (;*order; order++) {
+ switch (*order) {
+ case 'M':
+ main_Init(&libinit.options[opt_mainDB],
+ &libinit.options[opt_mainTokNam],
+ libinit.options[opt_mainRO].activated,
+ progName, log);
+ break;
+ case '1':
+ lib1_Init(&libinit.options[opt_lib1DB],
+ &libinit.options[opt_lib1TokNam],
+ libinit.options[opt_lib1RO].activated,
+ progName,log);
+ break;
+ case '2':
+ lib2_Init(&libinit.options[opt_lib2DB],
+ &libinit.options[opt_lib2TokNam],
+ libinit.options[opt_lib2RO].activated,
+ progName,log);
+ break;
+ case 'm':
+ main_Shutdown(libinit.options[opt_oldStyle].activated,
+ progName, log);
+ break;
+ case 'i':
+ lib1_Shutdown(progName, log);
+ break;
+ case 'z':
+ lib2_Shutdown(progName, log);
+ break;
+ default:
+ fprintf(stderr,">> Unknown init/shutdown command \"%c\"", *order);
+ usage_long(progName);
+ }
+ main_Do(&libinit.options[opt_mainCMD], progName, log);
+ lib1_Do(&libinit.options[opt_lib1CMD], progName, log);
+ lib2_Do(&libinit.options[opt_lib2CMD], progName, log);
+ }
+
+ if (NSS_IsInitialized()) {
+ appendLabel('X');
+ fprintf(stderr, "Warning: NSS is initialized\n");
+ }
+ dumpBuffer();
+
+ exit(0);
+}
+
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
index d8b47de8d..e058e6f11 100644
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -981,6 +981,9 @@ SECMOD_OpenNewSlot;
;+};
;+NSS_3.12.5 { # NSS 3.12.5 release
;+ global:
+CERT_AddCertToListSorted;
+NSS_InitContext;
+NSS_ShutdownContext;
SECMOD_GetDefaultModDBFlag;
SECMOD_GetSkipFirstFlag;
;+ local:
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
index e19ff707a..f136d7b8b 100644
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -77,6 +77,80 @@
#include "seccomon.h"
+typedef struct NSSInitParametersStr NSSInitParameters;
+
+/*
+ * parameters used to initialize softoken. Mostly strings used to
+ * internationalize softoken. Memory for the strings are owned by the caller,
+ * who is free to free them once NSS_ContextInit returns. If the string
+ * parameter is NULL (as opposed to empty, zero length), then the softoken
+ * default is used. These are equivalent to the parameters for
+ * PK11_ConfigurePKCS11().
+ *
+ * field names match their equivalent parameter names for softoken strings
+ * documented at https://developer.mozilla.org/en/PKCS11_Module_Specs.
+ *
+ * minPWLen
+ * Minimum password length in bytes.
+ * manufacturerID
+ * Override the default manufactureID value for the module returned in
+ * the CK_INFO, CK_SLOT_INFO, and CK_TOKEN_INFO structures with an
+ * internationalize string (UTF8). This value will be truncated at 32
+ * bytes (not including the trailing NULL, partial UTF8 characters will be
+ * dropped).
+ * libraryDescription
+ * Override the default libraryDescription value for the module returned in
+ * the CK_INFO structure with an internationalize string (UTF8). This value
+ * will be truncated at 32 bytes(not including the trailing NULL, partial
+ * UTF8 characters will be dropped).
+ * cryptoTokenDescription
+ * Override the default label value for the internal crypto token returned
+ * in the CK_TOKEN_INFO structure with an internationalize string (UTF8).
+ * This value will be truncated at 32 bytes (not including the trailing
+ * NULL, partial UTF8 characters will be dropped).
+ * dbTokenDescription
+ * Override the default label value for the internal DB token returned in
+ * the CK_TOKEN_INFO structure with an internationalize string (UTF8). This
+ * value will be truncated at 32 bytes (not including the trailing NULL,
+ * partial UTF8 characters will be dropped).
+ * FIPSTokenDescription
+ * Override the default label value for the internal FIPS token returned in
+ * the CK_TOKEN_INFO structure with an internationalize string (UTF8). This
+ * value will be truncated at 32 bytes (not including the trailing NULL,
+ * partial UTF8 characters will be dropped).
+ * cryptoSlotDescription
+ * Override the default slotDescription value for the internal crypto token
+ * returned in the CK_SLOT_INFO structure with an internationalize string
+ * (UTF8). This value will be truncated at 64 bytes (not including the
+ * trailing NULL, partial UTF8 characters will be dropped).
+ * dbSlotDescription
+ * Override the default slotDescription value for the internal DB token
+ * returned in the CK_SLOT_INFO structure with an internationalize string
+ * (UTF8). This value will be truncated at 64 bytes (not including the
+ * trailing NULL, partial UTF8 characters will be dropped).
+ * FIPSSlotDescription
+ * Override the default slotDecription value for the internal FIPS token
+ * returned in the CK_SLOT_INFO structure with an internationalize string
+ * (UTF8). This value will be truncated at 64 bytes (not including the
+ * trailing NULL, partial UTF8 characters will be dropped).
+ *
+ */
+struct NSSInitParametersStr {
+ unsigned int length; /* allow this structure to grow in the future,
+ * must be set */
+ PRBool passwordRequired;
+ int minPWLen;
+ char * manufactureID; /* variable names for strings match the */
+ char * libraryDescription; /* parameter name in softoken */
+ char * cryptoTokenDescription;
+ char * dbTokenDescription;
+ char * FIPSTokenDescription;
+ char * cryptoSlotDescription;
+ char * dbSlotDescription;
+ char * FIPSSlotDescription;
+};
+
+
SEC_BEGIN_PROTOS
/*
@@ -195,10 +269,19 @@ extern SECStatus NSS_InitReadWrite(const char *configdir);
#define SECMOD_DB "secmod.db"
#endif
+typedef struct NSSInitContextStr NSSInitContext;
+
+
extern SECStatus NSS_Initialize(const char *configdir,
const char *certPrefix, const char *keyPrefix,
const char *secmodName, PRUint32 flags);
+extern NSSInitContext *NSS_InitContext(const char *configdir,
+ const char *certPrefix, const char *keyPrefix,
+ const char *secmodName, NSSInitParameters *initParams, PRUint32 flags);
+
+extern SECStatus NSS_ShutdownContext(NSSInitContext *);
+
/*
* same as NSS_Init, but checks to see if we need to merge an
* old database in.
@@ -252,9 +335,9 @@ extern SECStatus NSS_Shutdown(void);
/*
* set the PKCS #11 strings for the internal token.
*/
-void PK11_ConfigurePKCS11(const char *man, const char *libdes,
- const char *tokdes, const char *ptokdes, const char *slotdes,
- const char *pslotdes, const char *fslotdes, const char *fpslotdes,
+void PK11_ConfigurePKCS11(const char *man, const char *libdesc,
+ const char *tokdesc, const char *ptokdesc, const char *slotdesc,
+ const char *pslotdesc, const char *fslotdesc, const char *fpslotdesc,
int minPwd, int pwRequired);
/*
diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c
index c2c1c562d..fad2fe83d 100644
--- a/security/nss/lib/nss/nssinit.c
+++ b/security/nss/lib/nss/nssinit.c
@@ -128,98 +128,121 @@ nss_makeFlags(PRBool readOnly, PRBool noCertDB,
return flags;
}
-/*
- * statics to remember the PK11_ConfigurePKCS11()
- * info.
- */
-static char * pk11_config_strings = NULL;
-static char * pk11_config_name = NULL;
-static PRBool pk11_password_required = PR_FALSE;
/*
- * this is a legacy configuration function which used to be part of
- * the PKCS #11 internal token.
+ * build config string from individual internationalized strings
*/
-void
-PK11_ConfigurePKCS11(const char *man, const char *libdes, const char *tokdes,
- const char *ptokdes, const char *slotdes, const char *pslotdes,
- const char *fslotdes, const char *fpslotdes, int minPwd, int pwRequired)
+char *
+nss_MkConfigString(const char *man, const char *libdesc, const char *tokdesc,
+ const char *ptokdesc, const char *slotdesc, const char *pslotdesc,
+ const char *fslotdesc, const char *fpslotdesc, int minPwd)
{
- char *strings = NULL;
- char *newStrings;
+ char *strings = NULL;
+ char *newStrings;
- /* make sure the internationalization was done correctly... */
- strings = PR_smprintf("");
- if (strings == NULL) return;
+ /* make sure the internationalization was done correctly... */
+ strings = PR_smprintf("");
+ if (strings == NULL) return NULL;
if (man) {
newStrings = PR_smprintf("%s manufacturerID='%s'",strings,man);
PR_smprintf_free(strings);
strings = newStrings;
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
- if (libdes) {
- newStrings = PR_smprintf("%s libraryDescription='%s'",strings,libdes);
+ if (libdesc) {
+ newStrings = PR_smprintf("%s libraryDescription='%s'",strings,libdesc);
PR_smprintf_free(strings);
strings = newStrings;
- if (pk11_config_name != NULL) {
- PORT_Free(pk11_config_name);
- }
- pk11_config_name = PORT_Strdup(libdes);
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
- if (tokdes) {
+ if (tokdesc) {
newStrings = PR_smprintf("%s cryptoTokenDescription='%s'",strings,
- tokdes);
+ tokdesc);
PR_smprintf_free(strings);
strings = newStrings;
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
- if (ptokdes) {
- newStrings = PR_smprintf("%s dbTokenDescription='%s'",strings,ptokdes);
+ if (ptokdesc) {
+ newStrings = PR_smprintf("%s dbTokenDescription='%s'",strings,ptokdesc);
PR_smprintf_free(strings);
strings = newStrings;
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
- if (slotdes) {
+ if (slotdesc) {
newStrings = PR_smprintf("%s cryptoSlotDescription='%s'",strings,
- slotdes);
+ slotdesc);
PR_smprintf_free(strings);
strings = newStrings;
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
- if (pslotdes) {
- newStrings = PR_smprintf("%s dbSlotDescription='%s'",strings,pslotdes);
+ if (pslotdesc) {
+ newStrings = PR_smprintf("%s dbSlotDescription='%s'",strings,pslotdesc);
PR_smprintf_free(strings);
strings = newStrings;
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
- if (fslotdes) {
+ if (fslotdesc) {
newStrings = PR_smprintf("%s FIPSSlotDescription='%s'",
- strings,fslotdes);
+ strings,fslotdesc);
PR_smprintf_free(strings);
strings = newStrings;
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
- if (fpslotdes) {
+ if (fpslotdesc) {
newStrings = PR_smprintf("%s FIPSTokenDescription='%s'",
- strings,fpslotdes);
+ strings,fpslotdesc);
PR_smprintf_free(strings);
strings = newStrings;
}
- if (strings == NULL) return;
+ if (strings == NULL) return NULL;
newStrings = PR_smprintf("%s minPS=%d", strings, minPwd);
PR_smprintf_free(strings);
strings = newStrings;
- if (strings == NULL) return;
+
+ return(strings);
+}
+
+/*
+ * statics to remember the PK11_ConfigurePKCS11()
+ * info.
+ */
+static char * pk11_config_strings = NULL;
+static char * pk11_config_name = NULL;
+static PRBool pk11_password_required = PR_FALSE;
+
+/*
+ * this is a legacy configuration function which used to be part of
+ * the PKCS #11 internal token.
+ */
+void
+PK11_ConfigurePKCS11(const char *man, const char *libdesc, const char *tokdesc,
+ const char *ptokdesc, const char *slotdesc, const char *pslotdesc,
+ const char *fslotdesc, const char *fpslotdesc, int minPwd,
+ int pwRequired)
+{
+ char * strings;
+
+ strings = nss_MkConfigString(man,libdesc,tokdesc,ptokdesc,slotdesc,
+ pslotdesc,fslotdesc,fpslotdesc,minPwd);
+ if (strings == NULL) {
+ return;
+ }
+
+ if (libdesc) {
+ if (pk11_config_name != NULL) {
+ PORT_Free(pk11_config_name);
+ }
+ pk11_config_name = PORT_Strdup(libdesc);
+ }
if (pk11_config_strings != NULL) {
PR_smprintf_free(pk11_config_strings);
@@ -242,56 +265,6 @@ void PK11_UnconfigurePKCS11(void)
}
}
-static char *
-nss_addEscape(const char *string, char quote)
-{
- char *newString = 0;
- int escapes = 0, size = 0;
- const char *src;
- char *dest;
-
- for (src=string; *src ; src++) {
- if ((*src == quote) || (*src == '\\')) escapes++;
- size++;
- }
-
- newString = PORT_ZAlloc(escapes+size+1);
- if (newString == NULL) {
- return NULL;
- }
-
- for (src=string, dest=newString; *src; src++,dest++) {
- if ((*src == '\\') || (*src == quote)) {
- *dest++ = '\\';
- }
- *dest = *src;
- }
-
- return newString;
-}
-
-static char *
-nss_doubleEscape(const char *string)
-{
- char *round1 = NULL;
- char *retValue = NULL;
- if (string == NULL) {
- goto done;
- }
- round1 = nss_addEscape(string,'\'');
- if (round1) {
- retValue = nss_addEscape(round1,'"');
- PORT_Free(round1);
- }
-
-done:
- if (retValue == NULL) {
- retValue = PORT_Strdup("");
- }
- return retValue;
-}
-
-
/*
* The following code is an attempt to automagically find the external root
* module.
@@ -389,46 +362,25 @@ nss_FindExternalRoot(const char *dbpath, const char* secmodprefix)
}
/*
- * OK there are now lots of options here, lets go through them all:
+ * see nss_Init for definitions of the various options.
*
- * configdir - base directory where all the cert, key, and module datbases live.
- * certPrefix - prefix added to the beginning of the cert database example: "
- * "https-server1-"
- * keyPrefix - prefix added to the beginning of the key database example: "
- * "https-server1-"
- * secmodName - name of the security module database (usually "secmod.db").
- * readOnly - Boolean: true if the databases are to be opened read only.
- * nocertdb - Don't open the cert DB and key DB's, just initialize the
- * Volatile certdb.
- * nomoddb - Don't open the security module DB, just initialize the
- * PKCS #11 module.
- * forceOpen - Continue to force initializations even if the databases cannot
- * be opened.
+ * this function builds a moduleSpec string from the options and previously
+ * set statics (from PKCS11_Configure, for instance), and uses it to kick off
+ * the loading of the various PKCS #11 modules.
*/
-
-static PRBool nss_IsInitted = PR_FALSE;
-static void* plContext = NULL;
-
-static SECStatus nss_InitShutdownList(void);
-
-#ifdef DEBUG
-static CERTCertificate dummyCert;
-#endif
-
static SECStatus
-nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
- const char *secmodName, const char *updateDir,
- const char *updCertPrefix, const char *updKeyPrefix,
- const char *updateID, const char *updateName,
- PRBool readOnly, PRBool noCertDB,
- PRBool noModDB, PRBool forceOpen, PRBool noRootInit,
- PRBool optimizeSpace, PRBool noSingleThreadedModules,
- PRBool allowAlreadyInitializedModules,
- PRBool dontFinalizeModules)
+nss_InitModules(const char *configdir, const char *certPrefix,
+ const char *keyPrefix, const char *secmodName,
+ const char *updateDir, const char *updCertPrefix,
+ const char *updKeyPrefix, const char *updateID,
+ const char *updateName, char *configName, char *configStrings,
+ PRBool pwRequired, PRBool readOnly, PRBool noCertDB,
+ PRBool noModDB, PRBool forceOpen, PRBool optimizeSpace,
+ PRBool isContextInit)
{
+ SECStatus rv = SECFailure;
char *moduleSpec = NULL;
char *flags = NULL;
- SECStatus rv = SECFailure;
char *lconfigdir = NULL;
char *lcertPrefix = NULL;
char *lkeyPrefix = NULL;
@@ -438,88 +390,62 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
char *lupdKeyPrefix = NULL;
char *lupdateID = NULL;
char *lupdateName = NULL;
- PKIX_UInt32 actualMinorVersion = 0;
- PKIX_Error *pkixError = NULL;;
-
- if (nss_IsInitted) {
- return SECSuccess;
- }
-
- /* New option bits must not change the size of CERTCertificate. */
- PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
-
- if (SECSuccess != cert_InitLocks()) {
- return SECFailure;
- }
-
- if (SECSuccess != InitCRLCache()) {
- return SECFailure;
- }
-
- if (SECSuccess != OCSP_InitGlobal()) {
- return SECFailure;
- }
flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen,
- pk11_password_required, optimizeSpace);
+ pwRequired, optimizeSpace);
if (flags == NULL) return rv;
/*
* configdir is double nested, and Windows uses the same character
* for file seps as we use for escapes! (sigh).
*/
- lconfigdir = nss_doubleEscape(configdir);
+ lconfigdir = secmod_DoubleEscape(configdir, '\'', '\"');
if (lconfigdir == NULL) {
goto loser;
}
- lcertPrefix = nss_doubleEscape(certPrefix);
+ lcertPrefix = secmod_DoubleEscape(certPrefix, '\'', '\"');
if (lcertPrefix == NULL) {
goto loser;
}
- lkeyPrefix = nss_doubleEscape(keyPrefix);
+ lkeyPrefix = secmod_DoubleEscape(keyPrefix, '\'', '\"');
if (lkeyPrefix == NULL) {
goto loser;
}
- lsecmodName = nss_doubleEscape(secmodName);
+ lsecmodName = secmod_DoubleEscape(secmodName, '\'', '\"');
if (lsecmodName == NULL) {
goto loser;
}
- lupdateDir = nss_doubleEscape(updateDir);
+ lupdateDir = secmod_DoubleEscape(updateDir, '\'', '\"');
if (lupdateDir == NULL) {
goto loser;
}
- lupdCertPrefix = nss_doubleEscape(updCertPrefix);
+ lupdCertPrefix = secmod_DoubleEscape(updCertPrefix, '\'', '\"');
if (lupdCertPrefix == NULL) {
goto loser;
}
- lupdKeyPrefix = nss_doubleEscape(updKeyPrefix);
+ lupdKeyPrefix = secmod_DoubleEscape(updKeyPrefix, '\'', '\"');
if (lupdKeyPrefix == NULL) {
goto loser;
}
- lupdateID = nss_doubleEscape(updateID);
+ lupdateID = secmod_DoubleEscape(updateID, '\'', '\"');
if (lupdateID == NULL) {
goto loser;
}
- lupdateName = nss_doubleEscape(updateName);
+ lupdateName = secmod_DoubleEscape(updateName, '\'', '\"');
if (lupdateName == NULL) {
goto loser;
}
- if (noSingleThreadedModules || allowAlreadyInitializedModules ||
- dontFinalizeModules) {
- pk11_setGlobalOptions(noSingleThreadedModules,
- allowAlreadyInitializedModules,
- dontFinalizeModules);
- }
moduleSpec = PR_smprintf(
"name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' "
"secmod='%s' flags=%s updatedir='%s' updateCertPrefix='%s' "
"updateKeyPrefix='%s' updateid='%s' updateTokenDescription='%s' %s\" "
- "NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"",
- pk11_config_name ? pk11_config_name : NSS_DEFAULT_MOD_NAME,
+ "NSS=\"flags=internal,moduleDB,moduleDBOnly,critical%s%s\"",
+ configName ? configName : NSS_DEFAULT_MOD_NAME,
lconfigdir,lcertPrefix,lkeyPrefix,lsecmodName,flags,
lupdateDir, lupdCertPrefix, lupdKeyPrefix, lupdateID,
- lupdateName, pk11_config_strings ? pk11_config_strings : "");
+ lupdateName, configStrings ? configStrings : "",
+ isContextInit ? "" : ",defaultModDB,internalKeySlot");
loser:
PORT_Free(flags);
@@ -541,65 +467,262 @@ loser:
SECMOD_DestroyModule(module);
}
}
+ return rv;
+}
- if (rv == SECSuccess) {
- if (SECOID_Init() != SECSuccess) {
+/*
+ * OK there are now lots of options here, lets go through them all:
+ *
+ * configdir - base directory where all the cert, key, and module datbases live.
+ * certPrefix - prefix added to the beginning of the cert database example: "
+ * "https-server1-"
+ * keyPrefix - prefix added to the beginning of the key database example: "
+ * "https-server1-"
+ * secmodName - name of the security module database (usually "secmod.db").
+ * updateDir - used in initMerge, old directory to update from.
+ * updateID - used in initMerge, unique ID to represent the updated directory.
+ * updateName - used in initMerge, token name when updating.
+ * initContextPtr - used in initContext, pointer to return a unique context
+ * value.
+ * readOnly - Boolean: true if the databases are to be opened read only.
+ * nocertdb - Don't open the cert DB and key DB's, just initialize the
+ * Volatile certdb.
+ * nomoddb - Don't open the security module DB, just initialize the
+ * PKCS #11 module.
+ * forceOpen - Continue to force initializations even if the databases cannot
+ * be opened.
+ * noRootInit - don't try to automatically load the root cert store if one is
+ * not found.
+ * optimizeSpace - tell NSS to use fewer hash table buckets.
+ *
+ * The next three options are used in an attempt to share PKCS #11 modules
+ * with other loaded, running libraries. PKCS #11 was not designed with this
+ * sort of sharing in mind, so use of these options may lead to questionable
+ * results. These options are may be incompatible with NSS_LoadContext() calls.
+ *
+ * noSingleThreadedModules - don't load modules that are not thread safe (many
+ * smart card tokens will not work).
+ * allowAlreadyInitializedModules - if a module has already been loaded and
+ * initialize try to use it.
+ * don'tFinalizeModules - dont shutdown modules we may have loaded.
+ */
+
+static PRBool nssIsInitted = PR_FALSE;
+static NSSInitContext *nssInitContextList = NULL;
+static void* plContext = NULL;
+
+struct NSSInitContextStr {
+ NSSInitContext *next;
+ PRUint32 magic;
+};
+
+#define NSS_INIT_MAGIC 0x1413A91C
+static SECStatus nss_InitShutdownList(void);
+
+#ifdef DEBUG
+static CERTCertificate dummyCert;
+#endif
+
+static SECStatus
+nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
+ const char *secmodName, const char *updateDir,
+ const char *updCertPrefix, const char *updKeyPrefix,
+ const char *updateID, const char *updateName,
+ NSSInitContext ** initContextPtr,
+ NSSInitParameters *initParams,
+ PRBool readOnly, PRBool noCertDB,
+ PRBool noModDB, PRBool forceOpen, PRBool noRootInit,
+ PRBool optimizeSpace, PRBool noSingleThreadedModules,
+ PRBool allowAlreadyInitializedModules,
+ PRBool dontFinalizeModules)
+{
+ SECStatus rv = SECFailure;
+ PKIX_UInt32 actualMinorVersion = 0;
+ PKIX_Error *pkixError = NULL;;
+ PRBool isReallyInitted;
+ char *configStrings = NULL;
+ char *configName = NULL;
+ PRBool passwordRequired = PR_FALSE;
+
+ /* if we are trying to init with a traditional NSS_Init call, maintain
+ * the traditional idempotent behavior. */
+ if (!initContextPtr && nssIsInitted) {
+ return SECSuccess;
+ }
+
+ /* this tells us whether or not some library has already initialized us.
+ * if so, we don't want to double call some of the basic initialization
+ * functions */
+ isReallyInitted = NSS_IsInitialized();
+
+ if (!isReallyInitted) {
+ /* New option bits must not change the size of CERTCertificate. */
+ PORT_Assert(sizeof(dummyCert.options) == sizeof(void *));
+
+ if (SECSuccess != cert_InitLocks()) {
+ return SECFailure;
+ }
+
+ if (SECSuccess != InitCRLCache()) {
+ return SECFailure;
+ }
+
+ if (SECSuccess != OCSP_InitGlobal()) {
+ return SECFailure;
+ }
+ }
+
+ if (noSingleThreadedModules || allowAlreadyInitializedModules ||
+ dontFinalizeModules) {
+ pk11_setGlobalOptions(noSingleThreadedModules,
+ allowAlreadyInitializedModules,
+ dontFinalizeModules);
+ }
+
+ if (initContextPtr) {
+ *initContextPtr = PORT_ZNew(NSSInitContext);
+ if (*initContextPtr == NULL) {
return SECFailure;
}
+ /*
+ * For traditional NSS_Init, we used the PK11_Configure() call to set
+ * globals. with InitContext, we pass those strings in as parameters.
+ *
+ * This allows old NSS_Init calls to work as before, while at the same
+ * time new calls and old calls will not interfere with each other.
+ */
+ if (initParams) {
+ if (initParams->length < sizeof(NSSInitParameters)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ configStrings = nss_MkConfigString(initParams->manufactureID,
+ initParams->libraryDescription,
+ initParams->cryptoTokenDescription,
+ initParams->dbTokenDescription,
+ initParams->cryptoSlotDescription,
+ initParams->dbSlotDescription,
+ initParams->FIPSSlotDescription,
+ initParams->FIPSTokenDescription,
+ initParams->minPWLen);
+ if (configStrings == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ configName = initParams->libraryDescription;
+ passwordRequired = initParams->passwordRequired;
+ }
+ } else {
+ configStrings = pk11_config_strings;
+ configName = pk11_config_name;
+ passwordRequired = pk11_password_required;
+ }
+
+ /* we always try to initialize the modules */
+ rv = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName,
+ updateDir, updCertPrefix, updKeyPrefix, updateID,
+ updateName, configName, configStrings, passwordRequired,
+ readOnly, noCertDB, noModDB, forceOpen, optimizeSpace,
+ (initContextPtr != NULL));
+
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+
+ /* finish up initialization */
+ if (!isReallyInitted) {
+ if (SECOID_Init() != SECSuccess) {
+ goto loser;
+ }
if (STAN_LoadDefaultNSS3TrustDomain() != PR_SUCCESS) {
- return SECFailure;
+ goto loser;
}
if (nss_InitShutdownList() != SECSuccess) {
- return SECFailure;
+ goto loser;
}
CERT_SetDefaultCertDB((CERTCertDBHandle *)
STAN_GetDefaultTrustDomain());
if ((!noModDB) && (!noCertDB) && (!noRootInit)) {
if (!SECMOD_HasRootCerts()) {
const char *dbpath = configdir;
+ /* handle supported database modifiers */
if (strncmp(dbpath, "sql:", 4) == 0) {
dbpath += 4;
+ } else if(strncmp(dbpath, "dbm:", 4) == 0) {
+ dbpath += 4;
+ } else if(strncmp(dbpath, "extern:", 7) == 0) {
+ dbpath += 7;
+ } else if(strncmp(dbpath, "rdb:", 4) == 0) {
+ /* if rdb: is specified, the configdir isn't really a
+ * path. Skip it */
+ dbpath = NULL;
+ }
+ if (dbpath) {
+ nss_FindExternalRoot(dbpath, secmodName);
}
- nss_FindExternalRoot(dbpath, secmodName);
}
}
+
pk11sdr_Init();
cert_CreateSubjectKeyIDHashTable();
- nss_IsInitted = PR_TRUE;
- }
- if (SECSuccess == rv) {
pkixError = PKIX_Initialize
(PKIX_FALSE, PKIX_MAJOR_VERSION, PKIX_MINOR_VERSION,
PKIX_MINOR_VERSION, &actualMinorVersion, &plContext);
if (pkixError != NULL) {
- rv = SECFailure;
+ goto loser;
} else {
char *ev = getenv("NSS_ENABLE_PKIX_VERIFY");
if (ev && ev[0]) {
CERT_SetUsePKIXForValidation(PR_TRUE);
}
}
+
+
}
- return rv;
+ /*
+ * Now mark the appropriate init state. If initContextPtr was passed
+ * in, then return the new context pointer and add it to the
+ * nssInitContextList. Otherwise set the global nss_isInitted flag
+ */
+ if (!initContextPtr) {
+ nssIsInitted = PR_TRUE;
+ } else {
+ (*initContextPtr)->magic = NSS_INIT_MAGIC;
+ (*initContextPtr)->next = nssInitContextList;
+ nssInitContextList = (*initContextPtr);
+ }
+
+ return SECSuccess;
+
+loser:
+ if (initContextPtr && *initContextPtr) {
+ PORT_Free(*initContextPtr);
+ *initContextPtr = NULL;
+ if (configStrings) {
+ PR_smprintf_free(configStrings);
+ }
+ }
+ return SECFailure;
}
SECStatus
NSS_Init(const char *configdir)
{
- return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "",
- PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
+ return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL,
+ NULL, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
}
SECStatus
NSS_InitReadWrite(const char *configdir)
{
- return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "",
- PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
+ return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL,
+ NULL, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
}
@@ -656,7 +779,7 @@ NSS_Initialize(const char *configdir, const char *certPrefix,
const char *keyPrefix, const char *secmodName, PRUint32 flags)
{
return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
- "", "", "", "", "",
+ "", "", "", "", "", NULL, NULL,
((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
@@ -668,6 +791,27 @@ NSS_Initialize(const char *configdir, const char *certPrefix,
((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE));
}
+NSSInitContext *
+NSS_InitContext(const char *configdir, const char *certPrefix,
+ const char *keyPrefix, const char *secmodName,
+ NSSInitParameters *initParams, PRUint32 flags)
+{
+ SECStatus rv;
+ NSSInitContext *context;
+
+ rv = nss_Init(configdir, certPrefix, keyPrefix, secmodName,
+ "", "", "", "", "", &context, initParams,
+ ((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
+ ((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
+ ((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
+ ((flags & NSS_INIT_FORCEOPEN) == NSS_INIT_FORCEOPEN), PR_TRUE,
+ ((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE),
+ ((flags & NSS_INIT_PK11THREADSAFE) == NSS_INIT_PK11THREADSAFE),
+ ((flags & NSS_INIT_PK11RELOAD) == NSS_INIT_PK11RELOAD),
+ ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE));
+ return (rv == SECSuccess) ? context : NULL;
+}
+
SECStatus
NSS_InitWithMerge(const char *configdir, const char *certPrefix,
const char *keyPrefix, const char *secmodName,
@@ -676,7 +820,8 @@ NSS_InitWithMerge(const char *configdir, const char *certPrefix,
const char *updateName, PRUint32 flags)
{
return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
- updateDir, updCertPrefix, updKeyPrefix, updateID, updateName,
+ updateDir, updCertPrefix, updKeyPrefix, updateID, updateName,
+ NULL, NULL,
((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
@@ -694,7 +839,7 @@ NSS_InitWithMerge(const char *configdir, const char *certPrefix,
SECStatus
NSS_NoDB_Init(const char * configdir)
{
- return nss_Init("","","","", "", "", "", "", "",
+ return nss_Init("","","","", "", "", "", "", "", NULL, NULL,
PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,
PR_FALSE,PR_FALSE,PR_FALSE);
}
@@ -722,7 +867,7 @@ nss_GetShutdownEntry(NSS_ShutdownFunc sFunc, void *appData)
{
int count, i;
count = nssShutdownList.peakFuncs;
- /* expect the list to be short, just do a linear search */
+
for (i=0; i < count; i++) {
if ((nssShutdownList.funcs[i].func == sFunc) &&
(nssShutdownList.funcs[i].appData == appData)){
@@ -740,7 +885,7 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
{
int i;
- if (!nss_IsInitted) {
+ if (!nssIsInitted) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
@@ -794,7 +939,7 @@ SECStatus
NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
{
int i;
- if (!nss_IsInitted) {
+ if (!nssIsInitted) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
@@ -821,6 +966,9 @@ NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
static SECStatus
nss_InitShutdownList(void)
{
+ if (nssShutdownList.lock != NULL) {
+ return SECSuccess;
+ }
nssShutdownList.lock = PZ_NewLock(nssILockOther);
if (nssShutdownList.lock == NULL) {
return SECFailure;
@@ -869,16 +1017,12 @@ nss_ShutdownShutdownList(void)
extern const NSSError NSS_ERROR_BUSY;
SECStatus
-NSS_Shutdown(void)
+nss_Shutdown(void)
{
SECStatus shutdownRV = SECSuccess;
SECStatus rv;
PRStatus status;
-
- if (!nss_IsInitted) {
- PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
- return SECFailure;
- }
+ NSSInitContext *temp;
rv = nss_ShutdownShutdownList();
if (rv != SECSuccess) {
@@ -891,6 +1035,7 @@ NSS_Shutdown(void)
SECOID_Shutdown();
status = STAN_Shutdown();
cert_DestroySubjectKeyIDHashTable();
+ pk11_SetInternalKeySlot(NULL);
rv = SECMOD_Shutdown();
if (rv != SECSuccess) {
shutdownRV = SECFailure;
@@ -911,14 +1056,87 @@ NSS_Shutdown(void)
}
shutdownRV = SECFailure;
}
- nss_IsInitted = PR_FALSE;
+ nssIsInitted = PR_FALSE;
+ temp = nssInitContextList;
+ nssInitContextList = NULL;
+ /* free the old list. This is necessary when we are called from
+ * NSS_Shutdown(). */
+ while (temp) {
+ NSSInitContext *next = temp->next;
+ temp->magic = 0;
+ PORT_Free(temp);
+ temp = next;
+ }
return shutdownRV;
}
+SECStatus
+NSS_Shutdown(void)
+{
+ if (!nssIsInitted) {
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return SECFailure;
+ }
+
+ return nss_Shutdown();
+}
+
+/*
+ * remove the context from a list. return true if found, false if not
+ */
+PRBool
+nss_RemoveList(NSSInitContext *context) {
+ NSSInitContext *this = nssInitContextList;
+ NSSInitContext **last = &nssInitContextList;
+
+ while (this) {
+ if (this == context) {
+ *last = this->next;
+ this->magic = 0;
+ PORT_Free(this);
+ return PR_TRUE;
+ }
+ last = &this->next;
+ this=this->next;
+ }
+ return PR_FALSE;
+}
+
+/*
+ * This form of shutdown is safe in the case where we may have multiple
+ * entities using NSS in a single process. Each entity calls shutdown with
+ * it's own context. The application (which doesn't get a context), calls
+ * shutdown with NULL. Once all users have 'checked in' NSS will shutdown.
+ * This is different than NSS_Shutdown, where calling it will shutdown NSS
+ * irreguardless of who else may have NSS open.
+ */
+SECStatus
+NSS_ShutdownContext(NSSInitContext *context)
+{
+ if (!context) {
+ if (!nssIsInitted) {
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return SECFailure;
+ }
+ nssIsInitted = 0;
+ } else if (! nss_RemoveList(context)) {
+ /* context was already freed or wasn't valid */
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return SECFailure;
+ }
+ if ((nssIsInitted == 0) && (nssInitContextList == NULL)) {
+ return nss_Shutdown();
+ }
+ return SECSuccess;
+}
+
+
+
+
PRBool
NSS_IsInitialized(void)
{
- return nss_IsInitted;
+ return (nssIsInitted) || (nssInitContextList != NULL);
}
diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c
index be15398ed..900be9053 100644
--- a/security/nss/lib/pk11wrap/pk11load.c
+++ b/security/nss/lib/pk11wrap/pk11load.c
@@ -132,19 +132,44 @@ PRBool pk11_getFinalizeModulesOption(void)
* initialize.
*/
static SECStatus
-secmod_handleReload(SECMODModule *oldModule, char *modulespec)
+secmod_handleReload(SECMODModule *oldModule, SECMODModule *newModule)
{
PK11SlotInfo *slot;
+ char *modulespec;
char *newModuleSpec;
char **children;
CK_SLOT_ID *ids;
SECStatus rv;
+ SECMODConfigList *conflist;
+ int count = 0;
/* first look for tokens= key words from the module spec */
- newModuleSpec = secmod_ParseModuleSpecForTokens(modulespec,&children,&ids);
+ modulespec = newModule->libraryParams;
+ newModuleSpec = secmod_ParseModuleSpecForTokens(PR_TRUE,
+ newModule->isFIPS, modulespec, &children, &ids);
if (!newModuleSpec) {
return SECFailure;
}
+
+ /*
+ * We are now trying to open a new slot on an already loaded module.
+ * If that slot represents a cert/key database, we don't want to open
+ * multiple copies of that same database. Unfortunately we understand
+ * the softoken flags well enough to be able to do this, so we can only get
+ * the list of already loaded databases if we are trying to open another
+ * internal module.
+ */
+ if (oldModule->internal) {
+ conflist = secmod_GetConfigList(oldModule->isFIPS,
+ oldModule->libraryParams, &count);
+ }
+
+
+ /* don't open multiple of the same db */
+ if (conflist && secmod_MatchConfigList(newModuleSpec, conflist, count)) {
+ rv = SECSuccess;
+ goto loser;
+ }
slot = SECMOD_OpenNewSlot(oldModule, newModuleSpec);
if (slot) {
int newID;
@@ -152,10 +177,18 @@ secmod_handleReload(SECMODModule *oldModule, char *modulespec)
CK_SLOT_ID *thisID;
char *oldModuleSpec;
+ if (secmod_IsInternalKeySlot(newModule)) {
+ pk11_SetInternalKeySlot(slot);
+ }
newID = slot->slotID;
PK11_FreeSlot(slot);
for (thisChild=children, thisID=ids; thisChild && *thisChild;
thisChild++,thisID++) {
+ if (conflist &&
+ secmod_MatchConfigList(*thisChild, conflist, count)) {
+ *thisID = (CK_SLOT_ID) -1;
+ continue;
+ }
slot = SECMOD_OpenNewSlot(oldModule, *thisChild);
if (slot) {
*thisID = slot->slotID;
@@ -177,8 +210,13 @@ secmod_handleReload(SECMODModule *oldModule, char *modulespec)
rv = SECSuccess;
}
+
+loser:
secmod_FreeChildren(children, ids);
PORT_Free(newModuleSpec);
+ if (conflist) {
+ secmod_FreeConfigList(conflist, count);
+ }
return rv;
}
@@ -224,7 +262,7 @@ secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
* reloading */
if (oldModule) {
SECStatus rv;
- rv = secmod_handleReload(oldModule, mod->libraryParams);
+ rv = secmod_handleReload(oldModule, mod);
if (rv == SECSuccess) {
/* This module should go away soon, since we've
* simply expanded the slots on the old module.
diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c
index 1ddcc4d04..c36cd25d8 100644
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -107,28 +107,28 @@ secmod_NewModule(void)
}
-/* private flags. */
+/* private flags for isModuleDB (field in SECMODModule). */
/* The meaing of these flags is as follows:
*
- * SECMOD_FLAG_IS_MODULE_DB - This is a module that accesses the database of
- * other modules to load. Module DBs are loadable modules that tells
- * NSS which PKCS #11 modules to load and when. These module DBs are
+ * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the
+ * database of other modules to load. Module DBs are loadable modules that
+ * tells NSS which PKCS #11 modules to load and when. These module DBs are
* chainable. That is, one module DB can load another one. NSS system init
* design takes advantage of this feature. In system NSS, a fixed system
* module DB loads the system defined libraries, then chains out to the
* traditional module DBs to load any system or user configured modules
* (like smart cards). This bit is the same as the already existing meaning
- * of isModuleDB = PR_TRUE. None of the other flags should be set if this
- * flag isn't on.
+ * of isModuleDB = PR_TRUE. None of the other module db flags should be set
+ * if this flag isn't on.
*
- * SECMOD_FLAG_SKIP_FIRST - This flag tells NSS to skip the first
+ * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first
* PKCS #11 module presented by a module DB. This allows the OS to load a
* softoken from the system module, then ask the existing module DB code to
* load the other PKCS #11 modules in that module DB (skipping it's request
* to load softoken). This gives the system init finer control over the
* configuration of that softoken module.
*
- * SECMOD_FLAG_DEFAULT_MODDB - This flag allows system init to mark a
+ * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a
* different module DB as the 'default' module DB (the one in which
* 'Add module' changes will go). Without this flag NSS takes the first
* module as the default Module DB, but in system NSS, that first module
@@ -137,10 +137,27 @@ secmod_NewModule(void)
* preserving the user's ability to load new PKCS #11 modules (which only
* affect him), from existing applications like Firefox.
*/
-#define SECMOD_FLAG_IS_MODULE_DB 0x01 /* must be set if any of the other flags
- * are set */
-#define SECMOD_FLAG_SKIP_FIRST 0x02
-#define SECMOD_FLAG_DEFAULT_MODDB 0x04
+#define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB 0x01 /* must be set if any of the
+ *other flags are set */
+#define SECMOD_FLAG_MODULE_DB_SKIP_FIRST 0x02
+#define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04
+
+
+/* private flags for internal (field in SECMODModule). */
+/* The meaing of these flags is as follows:
+ *
+ * SECMOD_FLAG_INTERNAL_IS_INTERNAL - This is a marks the the module is
+ * the internal module (that is, softoken). This bit is the same as the
+ * already existing meaning of internal = PR_TRUE. None of the other
+ * internal flags should be set if this flag isn't on.
+ *
+ * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark
+ * a different slot returned byt PK11_GetInternalKeySlot(). The 'primary'
+ * slot defined by this module will be the new internal key slot.
+ */
+#define SECMOD_FLAG_INTERNAL_IS_INTERNAL 0x01 /* must be set if any of
+ *the other flags are set */
+#define SECMOD_FLAG_INTERNAL_KEY_SLOT 0x02
/*
* for 3.4 we continue to use the old SECMODModule structure
@@ -188,17 +205,26 @@ SECMOD_CreateModule(const char *library, const char *moduleName,
* all platforms. These flags are only valid if moduleDB is set, so
* code checking if (mod->isModuleDB) will continue to work correctly. */
if (mod->isModuleDB) {
- char flags = SECMOD_FLAG_IS_MODULE_DB;
+ char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB;
if (secmod_argHasFlag("flags","skipFirst",nssc)) {
- flags |= SECMOD_FLAG_SKIP_FIRST;
+ flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST;
}
if (secmod_argHasFlag("flags","defaultModDB",nssc)) {
- flags |= SECMOD_FLAG_DEFAULT_MODDB;
+ flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB;
}
/* additional moduleDB flags could be added here in the future */
mod->isModuleDB = (PRBool) flags;
}
+ if (mod->internal) {
+ char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL;
+
+ if (secmod_argHasFlag("flags", "internalKeySlot", nssc)) {
+ flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
+ }
+ mod->internal = (PRBool) flags;
+ }
+
ciphers = secmod_argGetParamValue("ciphers",nssc);
secmod_argSetNewCipherFlags(&mod->ssl[0],ciphers);
if (ciphers) PORT_Free(ciphers);
@@ -213,7 +239,7 @@ SECMOD_GetSkipFirstFlag(SECMODModule *mod)
{
char flags = (char) mod->isModuleDB;
- return (flags & SECMOD_FLAG_SKIP_FIRST) ? PR_TRUE : PR_FALSE;
+ return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE;
}
PRBool
@@ -221,7 +247,59 @@ SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
{
char flags = (char) mod->isModuleDB;
- return (flags & SECMOD_FLAG_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE;
+ return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE;
+}
+
+PRBool
+secmod_IsInternalKeySlot(SECMODModule *mod)
+{
+ char flags = (char) mod->internal;
+
+ return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE;
+}
+
+/* forward declarations */
+static int secmod_escapeSize(const char *string, char quote);
+static char *secmod_addEscape(const char *string, char quote);
+
+/*
+ * copy desc and value into target. Target is known to be big enough to
+ * hold desc +2 +value, which is good because the result of this will be
+ * *desc"*value". We may, however, have to add some escapes for special
+ * characters imbedded into value (rare). This string potentially comes from
+ * a user, so we don't want the user overflowing the target buffer by using
+ * excessive escapes. To prevent this we count the escapes we need to add and
+ * try to expand the buffer with Realloc.
+ */
+static char *
+secmod_doDescCopy(char *target, int *targetLen, const char *desc,
+ int descLen, char *value)
+{
+ int diff, esc_len;
+
+ esc_len = secmod_escapeSize(value, '\"') - 1;
+ diff = esc_len - strlen(value);
+ if (diff > 0) {
+ /* we need to escape... expand newSpecPtr as well to make sure
+ * we don't overflow it */
+ char *newPtr = PORT_Realloc(target, *targetLen * diff);
+ if (!newPtr) {
+ return target; /* not enough space, just drop the whole copy */
+ }
+ *targetLen += diff;
+ target = newPtr;
+ value = secmod_addEscape(value, '\"');
+ if (value == NULL) {
+ return target; /* couldn't escape value, just drop the copy */
+ }
+ }
+ PORT_Memcpy(target, desc, descLen);
+ target += descLen;
+ *target++='\"';
+ PORT_Memcpy(target, value, esc_len);
+ target += esc_len;
+ *target++='\"';
+ return target;
}
#define SECMOD_SPEC_COPY(new, start, end) \
@@ -230,6 +308,9 @@ SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
PORT_Memcpy(new, start, _cnt); \
new += _cnt; \
}
+#define SECMOD_TOKEN_DESCRIPTION "tokenDescription="
+#define SECMOD_SLOT_DESCRIPTION "slotDescription="
+
/*
* Find any tokens= values in the module spec.
@@ -241,13 +322,16 @@ SECMOD_GetDefaultModDBFlag(SECMODModule *mod)
* spec.
*/
char *
-secmod_ParseModuleSpecForTokens(char *moduleSpec, char ***children,
+secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
+ char *moduleSpec, char ***children,
CK_SLOT_ID **ids)
{
- char *newSpec = PORT_Alloc(PORT_Strlen(moduleSpec)+2);
+ int newSpecLen = PORT_Strlen(moduleSpec)+2;
+ char *newSpec = PORT_Alloc(newSpecLen);
char *newSpecPtr = newSpec;
char *modulePrev = moduleSpec;
char *target = NULL;
+ char *tmp = NULL;
char **childArray = NULL;
char *tokenIndex;
CK_SLOT_ID *idArray = NULL;
@@ -265,6 +349,28 @@ secmod_ParseModuleSpecForTokens(char *moduleSpec, char ***children,
moduleSpec = secmod_argStrip(moduleSpec);
SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
+ /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening
+ * a new softoken module takes the following parameters to name the
+ * various tokens:
+ *
+ * cryptoTokenDescription: name of the non-fips crypto token.
+ * cryptoSlotDescription: name of the non-fips crypto slot.
+ * dbTokenDescription: name of the non-fips db token.
+ * dbSlotDescription: name of the non-fips db slot.
+ * FIPSTokenDescription: name of the fips db/crypto token.
+ * FIPSSlotDescription: name of the fips db/crypto slot.
+ *
+ * if we are opening a new slot, we need to have the following
+ * parameters:
+ * tokenDescription: name of the token.
+ * slotDescription: name of the slot.
+ *
+ *
+ * The convert flag tells us to drop the unnecessary *TokenDescription
+ * and *SlotDescription arguments and convert the appropriate pair
+ * (either db or FIPS based on the isFIPS flag) to tokenDescription and
+ * slotDescription).
+ */
/*
* walk down the list. if we find a tokens= argument, save it,
* otherise copy the argument.
@@ -274,9 +380,53 @@ secmod_ParseModuleSpecForTokens(char *moduleSpec, char ***children,
modulePrev = moduleSpec;
SECMOD_HANDLE_STRING_ARG(moduleSpec, target, "tokens=",
modulePrev = moduleSpec; /* skip copying */ )
+ SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoTokenDescription=",
+ if (convert) { modulePrev = moduleSpec; } );
+ SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoSlotDescription=",
+ if (convert) { modulePrev = moduleSpec; } );
+ SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "dbTokenDescription=",
+ if (convert) {
+ modulePrev = moduleSpec;
+ if (!isFIPS) {
+ newSpecPtr = secmod_doDescCopy(newSpecPtr,
+ &newSpecLen, SECMOD_TOKEN_DESCRIPTION,
+ sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp);
+ }
+ });
+ SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "dbSlotDescription=",
+ if (convert) {
+ modulePrev = moduleSpec; /* skip copying */
+ if (!isFIPS) {
+ newSpecPtr = secmod_doDescCopy(newSpecPtr,
+ &newSpecLen, SECMOD_SLOT_DESCRIPTION,
+ sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp);
+ }
+ } );
+ SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSTokenDescription=",
+ if (convert) {
+ modulePrev = moduleSpec; /* skip copying */
+ if (isFIPS) {
+ newSpecPtr = secmod_doDescCopy(newSpecPtr,
+ &newSpecLen, SECMOD_TOKEN_DESCRIPTION,
+ sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp);
+ }
+ } );
+ SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSSlotDescription=",
+ if (convert) {
+ modulePrev = moduleSpec; /* skip copying */
+ if (isFIPS) {
+ newSpecPtr = secmod_doDescCopy(newSpecPtr,
+ &newSpecLen, SECMOD_SLOT_DESCRIPTION,
+ sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp);
+ }
+ } );
SECMOD_HANDLE_FINAL_ARG(moduleSpec)
SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
}
+ if (tmp) {
+ PORT_Free(tmp);
+ tmp = NULL;
+ }
*newSpecPtr = 0;
/* no target found, return the newSpec */
@@ -341,6 +491,185 @@ secmod_ParseModuleSpecForTokens(char *moduleSpec, char ***children,
return newSpec;
}
+/* get the database and flags from the spec */
+static char *
+secmod_getConfigDir(char *spec, char **certPrefix, char **keyPrefix,
+ PRBool *readOnly)
+{
+ char * config = NULL;
+
+ *certPrefix = NULL;
+ *keyPrefix = NULL;
+ *readOnly = secmod_argHasFlag("flags","readOnly",spec);
+
+ spec = secmod_argStrip(spec);
+ while (*spec) {
+ int next;
+ SECMOD_HANDLE_STRING_ARG(spec, config, "configdir=", ;)
+ SECMOD_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;)
+ SECMOD_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;)
+ SECMOD_HANDLE_FINAL_ARG(spec)
+ }
+ return config;
+}
+
+struct SECMODConfigListStr {
+ char *config;
+ char *certPrefix;
+ char *keyPrefix;
+ PRBool isReadOnly;
+};
+
+/*
+ * return an array of already openned databases from a spec list.
+ */
+SECMODConfigList *
+secmod_GetConfigList(PRBool isFIPS, char *spec, int *count)
+{
+ char **children;
+ CK_SLOT_ID *ids;
+ char *strippedSpec;
+ int childCount;
+ SECMODConfigList *conflist = NULL;
+ int i;
+
+ strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS,
+ spec,&children,&ids);
+ if (strippedSpec == NULL) {
+ return NULL;
+ }
+
+ for (childCount=0; children && children[childCount]; childCount++) ;
+ *count = childCount+1; /* include strippedSpec */
+ conflist = PORT_NewArray(SECMODConfigList,*count);
+ if (conflist == NULL) {
+ *count = 0;
+ goto loser;
+ }
+
+ conflist[0].config = secmod_getConfigDir(strippedSpec,
+ &conflist[0].certPrefix,
+ &conflist[0].keyPrefix,
+ &conflist[0].isReadOnly);
+ for (i=0; i < childCount; i++) {
+ conflist[i+1].config = secmod_getConfigDir(children[i],
+ &conflist[i+1].certPrefix,
+ &conflist[i+1].keyPrefix,
+ &conflist[i+1].isReadOnly);
+ }
+
+loser:
+ secmod_FreeChildren(children, ids);
+ PORT_Free(strippedSpec);
+ return conflist;
+}
+
+/*
+ * determine if we are trying to open an old dbm database. For this test
+ * RDB databases should return PR_FALSE.
+ */
+static PRBool
+secmod_configIsDBM(char *configDir)
+{
+ char *env;
+
+ /* explicit dbm open */
+ if (strncmp(configDir, "dbm:", 4) == 0) {
+ return PR_TRUE;
+ }
+ /* explicit open of a non-dbm database */
+ if ((strncmp(configDir, "sql:",4) == 0)
+ || (strncmp(configDir, "rdb:", 4) == 0)
+ || (strncmp(configDir, "extern:", 7) == 0)) {
+ return PR_FALSE;
+ }
+ env = PR_GetEnv("NSS_DEFAULT_DB_TYPE");
+ /* implicit dbm open */
+ if ((env == NULL) || (strcmp(env,"dbm") == 0)) {
+ return PR_TRUE;
+ }
+ /* implicit non-dbm open */
+ return PR_FALSE;
+}
+
+/*
+ * match two prefixes. prefix may be NULL. NULL patches '\0'
+ */
+static PRBool
+secmod_matchPrefix(char *prefix1, char *prefix2)
+{
+ if ((prefix1 == NULL) || (*prefix1 == 0)) {
+ if ((prefix2 == NULL) || (*prefix2 == 0)) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+ }
+ if (strcmp(prefix1, prefix2) == 0) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+/*
+ * return true if we are requesting a database that is already openned.
+ */
+PRBool
+secmod_MatchConfigList(char *spec, SECMODConfigList *conflist, int count)
+{
+ char *config;
+ char *certPrefix;
+ char *keyPrefix;
+ PRBool isReadOnly;
+ PRBool ret=PR_FALSE;
+ int i;
+
+ config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly);
+ if (!config) {
+ ret=PR_TRUE;
+ goto done;
+ }
+
+ /* NOTE: we dbm isn't multiple open safe. If we open the same database
+ * twice from two different locations, then we can corrupt our database
+ * (the cache will be inconsistent). Protect against this by claiming
+ * for comparison only that we are always openning dbm databases read only.
+ */
+ if (secmod_configIsDBM(config)) {
+ isReadOnly = 1;
+ }
+ for (i=0; i < count; i++) {
+ if ((strcmp(config,conflist[i].config) == 0) &&
+ secmod_matchPrefix(certPrefix, conflist[i].certPrefix) &&
+ secmod_matchPrefix(keyPrefix, conflist[i].keyPrefix) &&
+ /* this last test -- if we just need the DB open read only,
+ * than any open will suffice, but if we requested it read/write
+ * and it's only open read only, we need to open it again */
+ (isReadOnly || !conflist[i].isReadOnly)) {
+ ret = PR_TRUE;
+ goto done;
+ }
+ }
+
+ ret = PR_FALSE;
+done:
+ PORT_Free(config);
+ PORT_Free(certPrefix);
+ PORT_Free(keyPrefix);
+ return ret;
+}
+
+void
+secmod_FreeConfigList(SECMODConfigList *conflist, int count)
+{
+ int i;
+ for (i=0; i < count; i++) {
+ PORT_Free(conflist[i].config);
+ PORT_Free(conflist[i].certPrefix);
+ PORT_Free(conflist[i].keyPrefix);
+ }
+ PORT_Free(conflist);
+}
+
void
secmod_FreeChildren(char **children, CK_SLOT_ID *ids)
{
@@ -515,7 +844,8 @@ secmod_MkAppendTokensList(PRArenaPool *arena, char *oldParam, char *newToken,
SECStatus rv;
/* first strip out and save the old tokenlist */
- rawParam = secmod_ParseModuleSpecForTokens(oldParam,&oldChildren,&oldIds);
+ rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE,PR_FALSE,
+ oldParam,&oldChildren,&oldIds);
if (!rawParam) {
goto loser;
}
@@ -769,6 +1099,9 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
}
if (parent) {
module->parent = SECMOD_ReferenceModule(parent);
+ if (module->internal && secmod_IsInternalKeySlot(parent)) {
+ module->internal = parent->internal;
+ }
}
/* load it */
diff --git a/security/nss/lib/pk11wrap/pk11priv.h b/security/nss/lib/pk11wrap/pk11priv.h
index 6b90c25d7..6f88e9330 100644
--- a/security/nss/lib/pk11wrap/pk11priv.h
+++ b/security/nss/lib/pk11wrap/pk11priv.h
@@ -114,6 +114,7 @@ SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts);
void PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot);
PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot);
SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot);
+void pk11_SetInternalKeySlot(PK11SlotInfo *slot);
/*********************************************************************
* Mechanism Mapping functions
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index 9a9216a56..dc5483e67 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -1129,6 +1129,8 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
PR_TRUE : PR_FALSE);
slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ?
PR_TRUE : PR_FALSE);
+
+
slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
slot->protectedAuthPath =
((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
@@ -1248,7 +1250,33 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
PK11_FreeSlot(int_slot);
}
}
-
+ /* work around a problem in softoken where it incorrectly
+ * reports databases opened read only as read/write. */
+ if (slot->isInternal && !slot->readOnly) {
+ CK_SESSION_HANDLE session = CK_INVALID_SESSION;
+
+ /* try to open a R/W session */
+ crv =PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
+ CKF_RW_SESSION|CKF_SERIAL_SESSION, slot, pk11_notify ,&session);
+ /* what a well behaved token should return if you open
+ * a RW session on a read only token */
+ if (crv == CKR_TOKEN_WRITE_PROTECTED) {
+ slot->readOnly = PR_TRUE;
+ } else if (crv == CKR_OK) {
+ CK_SESSION_INFO sessionInfo;
+
+ /* Because of a second bug in softoken, which silently returns
+ * a RO session, we need to check what type of session we got. */
+ crv = PK11_GETTAB(slot)->C_GetSessionInfo(session, &sessionInfo);
+ if (crv == CKR_OK) {
+ if ((sessionInfo.flags & CKF_RW_SESSION) == 0) {
+ /* session was readonly, so this softoken slot must be * readonly */
+ slot->readOnly = PR_TRUE;
+ }
+ }
+ PK11_GETTAB(slot)->C_CloseSession(session);
+ }
+ }
return SECSuccess;
}
@@ -1697,12 +1725,29 @@ PK11_NeedUserInit(PK11SlotInfo *slot)
return (PRBool)((slot->flags & CKF_USER_PIN_INITIALIZED) == 0);
}
+static PK11SlotInfo *pk11InternalKeySlot = NULL;
+void
+pk11_SetInternalKeySlot(PK11SlotInfo *slot)
+{
+ if (pk11InternalKeySlot) {
+ PK11_FreeSlot(pk11InternalKeySlot);
+ }
+ pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL;
+}
+
+
/* get the internal key slot. FIPS has only one slot for both key slots and
* default slots */
PK11SlotInfo *
PK11_GetInternalKeySlot(void)
{
- SECMODModule *mod = SECMOD_GetInternalModule();
+ SECMODModule *mod;
+
+ if (pk11InternalKeySlot) {
+ return PK11_ReferenceSlot(pk11InternalKeySlot);
+ }
+
+ mod = SECMOD_GetInternalModule();
PORT_Assert(mod != NULL);
if (!mod) {
PORT_SetError( SEC_ERROR_NO_MODULE );
@@ -1721,6 +1766,9 @@ PK11_GetInternalSlot(void)
PORT_SetError( SEC_ERROR_NO_MODULE );
return NULL;
}
+ if (mod->isFIPS) {
+ return PK11_GetInternalKeySlot();
+ }
return PK11_ReferenceSlot(mod->slots[0]);
}
diff --git a/security/nss/lib/pk11wrap/secmodi.h b/security/nss/lib/pk11wrap/secmodi.h
index 879edce30..b67e6df99 100644
--- a/security/nss/lib/pk11wrap/secmodi.h
+++ b/security/nss/lib/pk11wrap/secmodi.h
@@ -89,12 +89,25 @@ extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags
SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
SECStatus SECMOD_UnloadModule(SECMODModule *);
void SECMOD_SetInternalModule(SECMODModule *);
+PRBool secmod_IsInternalKeySlot(SECMODModule *);
+
+/* tools for checking if we are loading the same database twice */
+typedef struct SECMODConfigListStr SECMODConfigList;
+/* collect all the databases in a given spec */
+SECMODConfigList *secmod_GetConfigList(PRBool isFIPS, char *spec, int *count);
+/* see is a spec matches a database on the list */
+PRBool secmod_MatchConfigList(char *spec,
+ SECMODConfigList *conflist, int count);
+/* free our list of databases */
+void secmod_FreeConfigList(SECMODConfigList *conflist, int count);
/* parsing parameters */
/* returned char * must be freed by caller with PORT_Free */
/* children and ids are null terminated arrays which must be freed with
* secmod_FreeChildren */
-char *secmod_ParseModuleSpecForTokens(char *moduleSpec,
+char *secmod_ParseModuleSpecForTokens(PRBool convert,
+ PRBool isFIPS,
+ char *moduleSpec,
char ***children,
CK_SLOT_ID **ids);
void secmod_FreeChildren(char **children, CK_SLOT_ID *ids);
diff --git a/security/nss/tests/all.sh b/security/nss/tests/all.sh
index 4de519b40..6cf5cf4e4 100755
--- a/security/nss/tests/all.sh
+++ b/security/nss/tests/all.sh
@@ -188,7 +188,7 @@ run_cycle_pkix()
export NSS_ENABLE_PKIX_VERIFY
TESTS="${ALL_TESTS}"
- TESTS_SKIP="cipher dbtests sdr crmf smime merge"
+ TESTS_SKIP="cipher dbtests sdr crmf smime merge multinit"
echo "${NSS_SSL_TESTS}" | grep "_" > /dev/null
RET=$?
@@ -306,7 +306,7 @@ run_cycles()
cycles="standard pkix upgradedb sharedb"
CYCLES=${NSS_CYCLES:-$cycles}
-tests="cipher libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains"
+tests="cipher libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains multinit"
TESTS=${NSS_TESTS:-$tests}
ALL_TESTS=${TESTS}
diff --git a/security/nss/tests/multinit/multinit.sh b/security/nss/tests/multinit/multinit.sh
new file mode 100755
index 000000000..998e66f80
--- /dev/null
+++ b/security/nss/tests/multinit/multinit.sh
@@ -0,0 +1,191 @@
+#! /bin/sh
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+########################################################################
+#
+# mozilla/security/nss/tests/multinit/multinit.sh
+#
+# Script to test NSS multinit
+#
+# needs to work on all Unix and Windows platforms
+#
+# special strings
+# ---------------
+# FIXME ... known problems, search for this string
+# NOTE .... unexpected behavior
+#
+########################################################################
+
+############################## multinit_init ##############################
+# local shell function to initialize this script
+########################################################################
+multinit_init()
+{
+ SCRIPTNAME=multinit.sh # sourced - $0 would point to all.sh
+
+ if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
+ CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
+ fi
+
+ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
+ cd ../common
+ . ./init.sh
+ fi
+ if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here
+ cd ../cert
+ . ./cert.sh
+ fi
+ SCRIPTNAME=multinit.sh
+
+ html_head "MULTI Tests"
+
+ grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || {
+ Exit 11 "Fatal - S/MIME of cert.sh needs to pass first"
+ }
+
+ # set up our directories
+ MULTINITDIR=${HOSTDIR}/multinit
+ MULTINITDIR_1=${MULTINITDIR}/dir1
+ MULTINITDIR_2=${MULTINITDIR}/dir2
+ MULTINITDIR_3=${MULTINITDIR}/dir3
+ R_MULINITDIR=../multinit
+ R_MULTINITDIR_1=${R_MULTINITDIR}/dir1
+ R_MULTINITDIR_2=${R_MULTINITDIR}/dir2
+ R_MULTINITDIR_3=${R_MULTINITDIR}/dir3
+ # first create them all
+ mkdir -p ${MULTINITDIR}
+ mkdir -p ${MULTINITDIR_1}
+ mkdir -p ${MULTINITDIR_2}
+ mkdir -p ${MULTINITDIR_3}
+ # now copy them fro alice, bob, and dave
+ cd ${MULTINITDIR}
+ cp ${P_R_ALICEDIR}/* ${MULTINITDIR_1}/
+ cp ${P_R_BOBDIR}/* ${MULTINITDIR_2}/
+ cp ${P_R_DAVEDIR}/* ${MULTINITDIR_3}/
+ # finally delete the RootCerts module to keep the certificate noice in the
+ # summary lines down
+ echo | modutil -delete RootCerts -dbdir ${MULTINITDIR_1}
+ echo | modutil -delete RootCerts -dbdir ${MULTINITDIR_2}
+ echo | modutil -delete RootCerts -dbdir ${MULTINITDIR_3}
+ MULTINIT_TESTS=${QADIR}/multinit/multinit.txt
+}
+
+
+############################## multinit_main ##############################
+# local shell function to test basic signed and enveloped messages
+# from 1 --> 2"
+########################################################################
+multinit_main()
+{
+ html_head "Multi init interface testing"
+ exec < ${MULTINIT_TESTS}
+ while read order commands shutdown_type dirs readonly testname
+ do
+ if [ "$order" != "#" ]; then
+ read tag expected_result
+
+ # handle the case where we expect different results based on
+ # the database type.
+ if [ "$tag" != "all" ]; then
+ read tag2 expected_result2
+ if [ "$NSS_DEFAULT_DB_TYPE" == "$tag2" ]; then
+ expected_result=$expected_result2
+ fi
+ fi
+
+ # convert shutdown type to option flags
+ shutdown_command="";
+ if [ "$shutdown_type" == "old" ]; then
+ shutdown_command="--oldStype"
+ fi
+
+ # convert read only to option flags
+ ro_command="";
+ case $readonly in
+ all) ro_command="--main_readonly --lib1_readonly --lib2_readonly";;
+ libs) ro_command="--lib1_readonly --lib2_readonly";;
+ main) ro_command="--main_readonly";;
+ lib1) ro_command="--lib1_readonly";;
+ lib2) ro_command="--lib2_readonly";;
+ none) ;;
+ *) ;;
+ esac
+
+ # convert commands to option flags
+ main_command=`echo $commands | sed -e 's;,.*$;;'`
+ lib1_command=`echo $commands | sed -e 's;,.*,;+&+;' -e 's;^.*+,;;' -e 's;,+.*$;;'`
+ lib2_command=`echo $commands | sed -e 's;^.*,;;'`
+
+ # convert db's to option flags
+ main_db=`echo $dirs | sed -e 's;,.*$;;'`
+ lib1_db=`echo $dirs | sed -e 's;,.*,;+&+;' -e 's;^.*+,;;' -e 's;,+.*$;;'`
+ lib2_db=`echo $dirs | sed -e 's;^.*,;;'`
+
+ # show us the command we are executing
+ echo ${PROFILETOOL} ${BINDIR}/multinit --order $order --main_command $main_command --lib1_command $lib1_command --lib2_command $lib2_command $shutdown_command --main_db $main_db --lib1_db $lib1_db --lib2_db $lib2_db $ro_command --main_token_name "Main" --lib1_token_name "Lib1" --lib2_token_name "Lib2" --verbose --summary
+
+ # execute the command an collect the result. Most of the user
+ # visible output goes to stderr, so it's not captured by the pipe
+ actual_result=`${PROFILETOOL} ${BINDIR}/multinit --order $order --main_command $main_command --lib1_command $lib1_command --lib2_command $lib2_command $shutdown_command --main_db $main_db --lib1_db $lib1_db --lib2_db $lib2_db $ro_command --main_token_name "Main" --lib1_token_name "Lib1" --lib2_token_name "Lib2" --verbose --summary | grep "^result=" | sed -e 's;^result=;;'`
+
+ # show what we got and what we expected for diagnostic purposes
+ echo "actual = |$actual_result|"
+ echo "expected = |$expected_result|"
+ test "$actual_result" == "$expected_result"
+ html_msg $? 0 "$testname"
+ fi
+ done
+}
+
+############################## multinit_cleanup ###########################
+# local shell function to finish this script (no exit since it might be
+# sourced)
+########################################################################
+multinit_cleanup()
+{
+ html "</TABLE><BR>"
+ cd ${QADIR}
+ . common/cleanup.sh
+}
+
+################## main #################################################
+
+multinit_init
+multinit_main
+multinit_cleanup
diff --git a/security/nss/tests/multinit/multinit.txt b/security/nss/tests/multinit/multinit.txt
new file mode 100644
index 000000000..d5296dc0e
--- /dev/null
+++ b/security/nss/tests/multinit/multinit.txt
@@ -0,0 +1,79 @@
+#
+# This file defines the tests for multiple initialization of NSS in
+# different libraries.
+#
+# Test description lines control the parameters for the multinit test program.
+#
+# Init order: Upper case/digits indicate an init call, lower case indicate
+# a shutdown call.
+# M,m-Main 1,i-lib1, 2,z-lib2
+# Main calls the traditional NSS init calls (simulating the main application)
+# lib1 and lib2 call NSS_InitContext().
+#
+# All functions call NSS_ShutdownContext unless 'main shutdown type' is set to
+# 'old', in which case main will call the traditional NSS_Shutdown().
+#
+# Commands: comma separated list of commands to execute. These simulate
+# executing commands from either a library or main. In each cycle, multinit
+# will do one initialize or shutdown, then execute all the commands
+# for any of the libraries or main that is currently initialized. The same
+# command is executed in each cycle that it's library is initialized.
+#
+# Commands are given in order or 'main','lib1','lib2'. Valid commands are:
+# none - don't execute any commands for this library (or main).
+# list_certs - list all the visible certs in the system.
+# list_slots - list all the slots in the system.
+# key_slot - list the current default key slot.
+#
+# Main Shutdown Type - which kind of shutdown does main call. See Init order.
+#
+# Directories - which directory should each init open. Listed in order of:
+# (main init directory),(lib1 init directory),(lib2 init directory).
+#
+# RO - Which databases to open up read only, valid values are:
+# all - main, lib1, and lib2
+# none - open all directories R/W
+# libs - lib1 & lib2
+# main, lib1, lib2 - their respective directories only.
+#
+# Test description lines are followed by their expected summary output.
+# output lines are of the form:
+#
+# tag expected output.
+#
+# where tag is one of
+# all - applies to all database types
+# sql - expected output for sql databases
+# dbm - expected output for dbm databases
+#
+# if you do not specify all, you must have one line each for sql and dbm
+#
+# main
+# init main,lib1,lib2 shutdown main,lib1,lib2 Test Case name
+# order commands type directories RO
+# ------ ------------------------ --- ----------- ----- --------------
+ 1M2zmi list_slots,list_certs,none new dir1,dir2,dir3 all Progressive init
+all 1C<Bob>uuuC<Dave>pppC<Eve>pppC<NSS Test CA>CTCCMS<NSS Generic Crypto Services>ttS<Main>ttS<Lib1>ttC<Alice>uuuC<Bob>pupupuC<Dave>pppC<Eve>pppC<NSS Test CA>CTCC2S<NSS Generic Crypto Services>ttS<Lib2>ttS<Main>ttS<Lib1>ttC<Alice>uuuC<Bob>pupupuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCZS<NSS Generic Crypto Services>ttS<Lib2>ttS<Main>ttS<Lib1>ttC<Alice>uuuC<Bob>pupupuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCNC<Alice>uuuC<Bob>pupupuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCI
+ 1M2zmi list_certs,none,none old dir1,dir2,dir3 all Progressive init - oldStyle
+all 1MC<Alice>uuuC<Bob>pupupuC<Dave>pppC<Eve>pppC<NSS Test CA>CTCC2C<Alice>uuuC<Bob>pupupuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCZC<Alice>uuuC<Bob>pupupuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCNIE0xffffe09a
+ 12Mizm none,list_certs,none new dir1,dir2,dir3 all Sequenced init
+all 1C<Bob>uuuC<Dave>pppC<Eve>pppC<NSS Test CA>CTCC2C<Bob>uuuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCMC<Alice>uuuC<Bob>pupupuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCIZN
+ 12Mizm none,list_certs,none old dir1,dir2,dir3 all Sequenced init - old Style
+all 1C<Bob>uuuC<Dave>pppC<Eve>pppC<NSS Test CA>CTCC2C<Bob>uuuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCMC<Alice>uuuC<Bob>pupupuC<Dave>pupupuC<Eve>pppC<NSS Test CA>CTCCIZN
+ 1Mi2mz none,list_certs,list_slots new dir1,dir2,dir3 all Overlap shutdown
+all 1C<Bob>uuuC<Dave>pppC<Eve>pppC<NSS Test CA>CTCCMC<Alice>uuuC<Bob>pupupuC<Dave>pppC<Eve>pppC<NSS Test CA>CTCCI2S<NSS Generic Crypto Services>ttS<Lib2>ttS<Main>ttS<Lib1>ttNS<NSS Generic Crypto Services>ttS<Lib2>ttS<Main>ttS<Lib1>ttZ
+ 1Mi2mz none,key_slot,none new dir1,dir2,dir3 all Keyslot test
+all 1S<Lib1>ttMS<Main>ttI2NZ
+ M12miz none,key_slot,none new dir1,dir2,dir3 all Main init first
+all M1S<Main>tt2S<Main>ttNS<Main>ttIZ
+ M12miz key_slot,none,none old dir1,dir2,dir3 all Main init first - old Style
+all MS<Main>tt1S<Main>tt2S<Main>ttNIE0xffffe09aZE0xffffe09a
+ M12miz list_slots,none,none new dir1,dir1,dir2 all Loading the same directory twice
+all MS<NSS Generic Crypto Services>ttS<Main>tt1S<NSS Generic Crypto Services>ttS<Main>tt2S<NSS Generic Crypto Services>ttS<Lib2>ttS<Main>ttNIZ
+ M12miz list_slots,none,none new dir1,dir1,dir2 libs Loading the same directory twice - r/w then ro
+all MS<NSS Generic Crypto Services>ttS<Main>tf1S<NSS Generic Crypto Services>ttS<Main>tf2S<NSS Generic Crypto Services>ttS<Lib2>ttS<Main>tfNIZ
+ M12miz list_slots,none,none new dir1,dir1,dir2 main Loading the same directory twice - ro then r/w
+sql MS<NSS Generic Crypto Services>ttS<Main>tt1S<NSS Generic Crypto Services>ttS<Lib1>tfS<Main>tt2S<NSS Generic Crypto Services>ttS<Lib2>tfS<Lib1>tfS<Main>ttNIZ
+dbm MS<NSS Generic Crypto Services>ttS<Main>tt1S<NSS Generic Crypto Services>ttS<Main>tt2S<NSS Generic Crypto Services>ttS<Lib2>tfS<Main>ttNIZ
+ M12miM1zim key_slot,none,none old dir1,dir2,dir3 all Properly detect shutdown of a closed handle
+all MS<Main>tt1S<Main>tt2S<Main>ttNIE0xffffe09aMS<Main>tt1S<Main>ttZE0xffffe09aS<Main>ttIS<Main>ttN
diff --git a/security/nss/tests/tools/tools.sh b/security/nss/tests/tools/tools.sh
index 545b742bb..8861543a7 100644
--- a/security/nss/tests/tools/tools.sh
+++ b/security/nss/tests/tools/tools.sh
@@ -121,16 +121,22 @@ tools_init()
TOOLSDIR=${HOSTDIR}/tools
COPYDIR=${TOOLSDIR}/copydir
+ SIGNDIR=${TOOLSDIR}/signdir
R_TOOLSDIR=../tools
R_COPYDIR=../tools/copydir
+ R_SIGNDIR=../tools/signdir
P_R_COPYDIR=${R_COPYDIR}
+ P_R_SIGNDIR=${R_SIGNDIR}
if [ -n "${MULTIACCESS_DBM}" ]; then
P_R_COPYDIR="multiaccess:Tools.$version"
+ P_R_SIGNDIR="multiaccess:Tools.sign.$version"
fi
mkdir -p ${TOOLSDIR}
mkdir -p ${COPYDIR}
+ mkdir -p ${SIGNDIR}
+ cp ${ALICEDIR}/* ${SIGNDIR}/
mkdir -p ${TOOLSDIR}/html
cp ${QADIR}/tools/sign*.html ${TOOLSDIR}/html
@@ -455,8 +461,8 @@ check_tmpfile()
tools_sign()
{
echo "$SCRIPTNAME: Create objsign cert -------------------------------"
- echo "signtool -G \"objectsigner\" -d ${P_R_ALICEDIR} -p \"nss\""
- ${BINDIR}/signtool -G "objsigner" -d ${P_R_ALICEDIR} -p "nss" 2>&1 <<SIGNSCRIPT
+ echo "signtool -G \"objectsigner\" -d ${P_R_SIGNDIR} -p \"nss\""
+ ${BINDIR}/signtool -G "objsigner" -d ${P_R_SIGNDIR} -p "nss" 2>&1 <<SIGNSCRIPT
y
TEST
MOZ
@@ -469,37 +475,37 @@ SIGNSCRIPT
html_msg $? 0 "Create objsign cert (signtool -G)"
echo "$SCRIPTNAME: Signing a jar of files ----------------------------"
- echo "signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p \"nss\" -k objsigner \\"
+ echo "signtool -Z nojs.jar -d ${P_R_SIGNDIR} -p \"nss\" -k objsigner \\"
echo " ${R_TOOLSDIR}/html"
- ${BINDIR}/signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p "nss" -k objsigner \
+ ${BINDIR}/signtool -Z nojs.jar -d ${P_R_SIGNDIR} -p "nss" -k objsigner \
${R_TOOLSDIR}/html
html_msg $? 0 "Signing a jar of files (signtool -Z)"
echo "$SCRIPTNAME: Listing signed files in jar ----------------------"
- echo "signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner"
- ${BINDIR}/signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner
+ echo "signtool -v nojs.jar -d ${P_R_SIGNDIR} -p nss -k objsigner"
+ ${BINDIR}/signtool -v nojs.jar -d ${P_R_SIGNDIR} -p nss -k objsigner
html_msg $? 0 "Listing signed files in jar (signtool -v)"
echo "$SCRIPTNAME: Show who signed jar ------------------------------"
- echo "signtool -w nojs.jar -d ${P_R_ALICEDIR}"
- ${BINDIR}/signtool -w nojs.jar -d ${P_R_ALICEDIR}
+ echo "signtool -w nojs.jar -d ${P_R_SIGNDIR}"
+ ${BINDIR}/signtool -w nojs.jar -d ${P_R_SIGNDIR}
html_msg $? 0 "Show who signed jar (signtool -w)"
echo "$SCRIPTNAME: Signing a xpi of files ----------------------------"
- echo "signtool -Z nojs.xpi -X -d ${P_R_ALICEDIR} -p \"nss\" -k objsigner \\"
+ echo "signtool -Z nojs.xpi -X -d ${P_R_SIGNDIR} -p \"nss\" -k objsigner \\"
echo " ${R_TOOLSDIR}/html"
- ${BINDIR}/signtool -Z nojs.xpi -X -d ${P_R_ALICEDIR} -p "nss" -k objsigner \
+ ${BINDIR}/signtool -Z nojs.xpi -X -d ${P_R_SIGNDIR} -p "nss" -k objsigner \
${R_TOOLSDIR}/html
html_msg $? 0 "Signing a xpi of files (signtool -Z -X)"
echo "$SCRIPTNAME: Listing signed files in xpi ----------------------"
- echo "signtool -v nojs.xpi -d ${P_R_ALICEDIR} -p nss -k objsigner"
- ${BINDIR}/signtool -v nojs.xpi -d ${P_R_ALICEDIR} -p nss -k objsigner
+ echo "signtool -v nojs.xpi -d ${P_R_SIGNDIR} -p nss -k objsigner"
+ ${BINDIR}/signtool -v nojs.xpi -d ${P_R_SIGNDIR} -p nss -k objsigner
html_msg $? 0 "Listing signed files in xpi (signtool -v)"
echo "$SCRIPTNAME: Show who signed xpi ------------------------------"
- echo "signtool -w nojs.xpi -d ${P_R_ALICEDIR}"
- ${BINDIR}/signtool -w nojs.xpi -d ${P_R_ALICEDIR}
+ echo "signtool -w nojs.xpi -d ${P_R_SIGNDIR}"
+ ${BINDIR}/signtool -w nojs.xpi -d ${P_R_SIGNDIR}
html_msg $? 0 "Show who signed xpi (signtool -w)"
}