diff options
author | wtchang%redhat.com <devnull@localhost> | 2006-03-03 01:58:08 +0000 |
---|---|---|
committer | wtchang%redhat.com <devnull@localhost> | 2006-03-03 01:58:08 +0000 |
commit | 0d50b07a731cd876c2abad8caaf9a7161357ba19 (patch) | |
tree | ab1c77ee7c97cfe3a5be176e6c240cb150260d31 | |
parent | 77603280103d5ba2aa3356aad4234386c1d35ab8 (diff) | |
parent | cabbde8a8b861f114acb38c135a294af20769b84 (diff) | |
download | nss-hg-0d50b07a731cd876c2abad8caaf9a7161357ba19.tar.gz |
Bugzilla Bug 317620: upgraded the NSS version on the MOZILLA_1_8_BRANCH to
NSS 3.11.1 Beta.
Tag: MOZILLA_1_8_BRANCH
37 files changed, 6269 insertions, 0 deletions
diff --git a/security/nss/cmd/cmdlib/Makefile b/security/nss/cmd/cmdlib/Makefile new file mode 100644 index 000000000..c4f18fb5d --- /dev/null +++ b/security/nss/cmd/cmdlib/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 config.mk + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + diff --git a/security/nss/cmd/cmdlib/cmdline.c b/security/nss/cmd/cmdlib/cmdline.c new file mode 100644 index 000000000..164b03835 --- /dev/null +++ b/security/nss/cmd/cmdlib/cmdline.c @@ -0,0 +1,477 @@ +/* ***** 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 ***** */ + +#include <string.h> +#include <ctype.h> + +#include "cmdutil.h" + +static int s_indent_size = 4; + +void +CMD_SetIndentSize(int size) +{ + s_indent_size = size; +} + +#if 0 +static void +indent(PRFileDesc *out, int level) +{ + int i, j; + for (i=0; i<level; i++) + for (j=0; j<s_indent_size; j++) + PR_fprintf(out, " "); +} +#endif + +struct cmdPrintStateStr { + PRFileDesc *file; + int width; + int indent; + int linepos; +}; + +static void +init_print_ps(cmdPrintState *ps, PRFileDesc *outfile, int width, int indent) +{ + ps->file = (outfile) ? outfile : PR_STDOUT; + ps->width = (width > 0) ? width : 80; + ps->indent = (indent > 0) ? indent : 0; + ps->linepos = 0; +} + +static void +print_ps_indent(cmdPrintState *ps) +{ + int j; + if (ps->linepos != 0) { + PR_fprintf(ps->file, "\n"); + ps->linepos = 0; + } + for (j=0; j<=ps->indent; j++) PR_fprintf(ps->file, " "); + ps->linepos = ps->indent; +} + +static void +print_ps_to_indent(cmdPrintState *ps) +{ + if (ps->linepos > ps->indent) + PR_fprintf(ps->file, "\n"); + while (ps->linepos <= ps->indent) { + PR_fprintf(ps->file, " "); + ps->linepos++; + } +} + +static void +nprintbuf(cmdPrintState *ps, char *buf, int start, int len) +{ + int j; + for (j=start; j<start + len; j++) { + if (buf[j] == '\n') { + PR_fprintf(ps->file, "\n"); + ps->linepos = 0; + print_ps_indent(ps); + } else { + PR_fprintf(ps->file, "%c", buf[j]); + ps->linepos++; + } + } +} + +static void +nprintf(cmdPrintState *ps, char *msg, ...) +{ + char buf[256]; + int i, len, grouplen; + PRBool openquote, openbracket, openparen, openangle, itsaword; + va_list args; + va_start(args, msg); + vsprintf(buf, msg, args); + len = strlen(buf); + /* print_ps_indent(ps); */ + if (len < ps->width - ps->linepos) { + nprintbuf(ps, buf, 0, len + 1); + return; + } + /* group in this order: " [ ( < word > ) ] " */ + i=0; + openquote=openbracket=openparen=openangle=itsaword=PR_FALSE; + while (i<len) { + grouplen = 0; + if (buf[i] == '\"') { openquote = PR_TRUE; grouplen = 1; } + else if (buf[i] == '[') { openbracket = PR_TRUE; grouplen = 1; } + else if (buf[i] == '(') { openparen = PR_TRUE; grouplen = 1; } + else if (buf[i] == '<') { openangle = PR_TRUE; grouplen = 1; } + else itsaword = PR_TRUE; + while (grouplen < len && buf[i+grouplen] != '\0' && + ((openquote && buf[i+grouplen] != '\"') || + (openbracket && buf[i+grouplen] != ']') || + (openparen && buf[i+grouplen] != ')') || + (openangle && buf[i+grouplen] != '>') || + (itsaword && !isspace(buf[i+grouplen])))) + grouplen++; + grouplen++; /* grab the terminator (whitespace for word) */ + if (!itsaword && isspace(buf[i+grouplen])) grouplen++; + if (grouplen < ps->width - ps->linepos) { + nprintbuf(ps, buf, i, grouplen); + } else if (grouplen < ps->width - ps->indent) { + print_ps_indent(ps); + nprintbuf(ps, buf, i, grouplen); + } else { + /* it's just too darn long. what to do? */ + } + i += grouplen; + openquote=openbracket=openparen=openangle=itsaword=PR_FALSE; + } + va_end(args); +} + +void +CMD_PrintUsageString(cmdPrintState *ps, char *str) +{ + nprintf(ps, "%s", str); +} + +/* void because it exits with Usage() if failure */ +static void +command_line_okay(cmdCommand *cmd, char *progName) +{ + int i, c = -1; + /* user asked for help. hope somebody gives it to them. */ + if (cmd->opt[0].on) return; + /* check that the command got all of its needed options */ + for (i=0; i<cmd->ncmd; i++) { + if (cmd->cmd[i].on) { + if (c > 0) { + fprintf(stderr, + "%s: only one command can be given at a time.\n", + progName); + CMD_Usage(progName, cmd); + } else { + c = i; + } + } + } + if (cmd->cmd[c].argUse == CMDArgReq && cmd->cmd[c].arg == NULL) { + /* where's the arg when you need it... */ + fprintf(stderr, "%s: command --%s requires an argument.\n", + progName, cmd->cmd[c].s); + fprintf(stderr, "type \"%s --%s --help\" for help.\n", + progName, cmd->cmd[c].s); + CMD_Usage(progName, cmd); + } + for (i=0; i<cmd->nopt; i++) { + if (cmd->cmd[c].req & CMDBIT(i)) { + /* command requires this option */ + if (!cmd->opt[i].on) { + /* but it ain't there */ + fprintf(stderr, "%s: command --%s requires option --%s.\n", + progName, cmd->cmd[c].s, cmd->opt[i].s); + } else { + /* okay, its there, but does it have an arg? */ + if (cmd->opt[i].argUse == CMDArgReq && !cmd->opt[i].arg) { + fprintf(stderr, "%s: option --%s requires an argument.\n", + progName, cmd->opt[i].s); + } + } + } else if (cmd->cmd[c].opt & CMDBIT(i)) { + /* this option is optional */ + if (cmd->opt[i].on) { + /* okay, its there, but does it have an arg? */ + if (cmd->opt[i].argUse == CMDArgReq && !cmd->opt[i].arg) { + fprintf(stderr, "%s: option --%s requires an argument.\n", + progName, cmd->opt[i].s); + } + } + } else { + /* command knows nothing about it */ + if (cmd->opt[i].on) { + /* so why the h--- is it on? */ + fprintf(stderr, "%s: option --%s not used with command --%s.\n", + progName, cmd->opt[i].s, cmd->cmd[c].s); + } + } + } +} + +static char * +get_arg(char *curopt, char **nextopt, int argc, int *index) +{ + char *str; + if (curopt) { + str = curopt; + } else { + if (*index + 1 >= argc) return NULL; + /* not really an argument but another flag */ + if (nextopt[*index+1][0] == '-') return NULL; + str = nextopt[++(*index)]; + } + /* parse the option */ + return strdup(str); +} + +int +CMD_ParseCommandLine(int argc, char **argv, char *progName, cmdCommand *cmd) +{ + int i, j, k; + int cmdToRun = -1; + char *flag; + i=1; + if (argc <= 1) return -2; /* gross hack for cmdless things like atob */ + do { + flag = argv[i]; + if (strlen(flag) < 2) /* huh? */ + return -1; + if (flag[0] != '-') + return -1; + /* ignore everything after lone "--" (app-specific weirdness there) */ + if (strcmp(flag, "--") == 0) + return cmdToRun; + /* single hyphen means short alias (single-char) */ + if (flag[1] != '-') { + j=1; + /* collect a set of opts, ex. -abc */ + while (flag[j] != '\0') { + PRBool found = PR_FALSE; + /* walk the command set looking for match */ + for (k=0; k<cmd->ncmd; k++) { + if (flag[j] == cmd->cmd[k].c) { + /* done - only take one command at a time */ + if (j > 1) return -1; + cmd->cmd[k].on = found = PR_TRUE; + cmdToRun = k; + if (cmd->cmd[k].argUse != CMDNoArg) + cmd->cmd[k].arg = get_arg(NULL, argv, argc, &i); + goto next_flag; + } + } + /* wasn't found in commands, try options */ + for (k=0; k<cmd->nopt; k++) { + if (flag[j] == cmd->opt[k].c) { + /* collect this option and keep going */ + cmd->opt[k].on = found = PR_TRUE; + if (flag[j+1] == '\0') { + if (cmd->opt[k].argUse != CMDNoArg) + cmd->opt[k].arg = get_arg(NULL, argv, argc, &i); + goto next_flag; + } + } + } + j++; + if (!found) return -1; + } + } else { /* long alias, ex. --list */ + char *fl = NULL, *arg = NULL; + PRBool hyphened = PR_FALSE; + fl = &flag[2]; + arg = strchr(fl, '='); + if (arg) { + *arg++ = '\0'; + } else { + arg = strchr(fl, '-'); + if (arg) { + hyphened = PR_TRUE; /* watch this, see below */ + *arg++ = '\0'; + } + } + for (k=0; k<cmd->ncmd; k++) { + if (strcmp(fl, cmd->cmd[k].s) == 0) { + cmd->cmd[k].on = PR_TRUE; + cmdToRun = k; + if (cmd->cmd[k].argUse != CMDNoArg || hyphened) { + cmd->cmd[k].arg = get_arg(arg, argv, argc, &i); + } + if (arg) arg[-1] = '='; + goto next_flag; + } + } + for (k=0; k<cmd->nopt; k++) { + if (strcmp(fl, cmd->opt[k].s) == 0) { + cmd->opt[k].on = PR_TRUE; + if (cmd->opt[k].argUse != CMDNoArg || hyphened) { + cmd->opt[k].arg = get_arg(arg, argv, argc, &i); + } + if (arg) arg[-1] = '='; + goto next_flag; + } + } + return -1; + } +next_flag: + i++; + } while (i < argc); + command_line_okay(cmd, progName); + return cmdToRun; +} + +void +CMD_LongUsage(char *progName, cmdCommand *cmd, cmdUsageCallback usage) +{ + int i, j; + PRBool oneCommand = PR_FALSE; + cmdPrintState ps; + init_print_ps(&ps, PR_STDERR, 80, 0); + nprintf(&ps, "\n%s: ", progName); + /* prints app-specific header */ + ps.indent = strlen(progName) + 4; + usage(&ps, 0, PR_FALSE, PR_TRUE, PR_FALSE); + for (i=0; i<cmd->ncmd; i++) if (cmd->cmd[i].on) oneCommand = PR_TRUE; + for (i=0; i<cmd->ncmd; i++) { + if ((oneCommand && cmd->cmd[i].on) || !oneCommand) { + ps.indent = 0; + print_ps_indent(&ps); + if (cmd->cmd[i].c != 0) { + nprintf(&ps, "-%c, ", cmd->cmd[i].c); + nprintf(&ps, "--%-16s ", cmd->cmd[i].s); + } else { + nprintf(&ps, "--%-20s ", cmd->cmd[i].s); + } + ps.indent += 20; + usage(&ps, i, PR_TRUE, PR_FALSE, PR_FALSE); + for (j=0; j<cmd->nopt; j++) { + if (cmd->cmd[i].req & CMDBIT(j)) { + ps.indent = 0; + print_ps_indent(&ps); + nprintf(&ps, "%3s* ", ""); + if (cmd->opt[j].c != 0) { + nprintf(&ps, "-%c, ", cmd->opt[j].c); + nprintf(&ps, "--%-16s ", cmd->opt[j].s); + } else { + nprintf(&ps, "--%-20s ", cmd->opt[j].s); + } + ps.indent += 29; + usage(&ps, j, PR_FALSE, PR_FALSE, PR_FALSE); + } + } + for (j=0; j<cmd->nopt; j++) { + if (cmd->cmd[i].opt & CMDBIT(j)) { + ps.indent = 0; + print_ps_indent(&ps); + nprintf(&ps, "%5s", ""); + if (cmd->opt[j].c != 0) { + nprintf(&ps, "-%c, ", cmd->opt[j].c); + nprintf(&ps, "--%-16s ", cmd->opt[j].s); + } else { + nprintf(&ps, "--%-20s ", cmd->opt[j].s); + } + ps.indent += 29; + usage(&ps, j, PR_FALSE, PR_FALSE, PR_FALSE); + } + } + } + nprintf(&ps, "\n"); + } + ps.indent = 0; + nprintf(&ps, "\n* - required flag for command\n\n"); + /* prints app-specific footer */ + usage(&ps, 0, PR_FALSE, PR_FALSE, PR_TRUE); + /*nprintf(&ps, "\n\n");*/ + exit(1); +} + +void +CMD_Usage(char *progName, cmdCommand *cmd) +{ + int i, j, inc; + PRBool first; + cmdPrintState ps; + init_print_ps(&ps, PR_STDERR, 80, 0); + nprintf(&ps, "%s", progName); + ps.indent = strlen(progName) + 1; + print_ps_to_indent(&ps); + for (i=0; i<cmd->ncmd; i++) { + if (cmd->cmd[i].c != 0) { + nprintf(&ps, "-%c", cmd->cmd[i].c); + inc = 4; + } else { + nprintf(&ps, "--%s", cmd->cmd[i].s); + inc = 4 + strlen(cmd->cmd[i].s); + } + first = PR_TRUE; + ps.indent += inc; + print_ps_to_indent(&ps); + for (j=0; j<cmd->nopt; j++) { + if (cmd->cmd[i].req & CMDBIT(j)) { + if (cmd->opt[j].c != 0 && cmd->opt[j].argUse == CMDNoArg) { + if (first) { + nprintf(&ps, "-"); + first = !first; + } + nprintf(&ps, "%c", cmd->opt[j].c); + } + } + } + for (j=0; j<cmd->nopt; j++) { + if (cmd->cmd[i].req & CMDBIT(j)) { + if (cmd->opt[j].c != 0) + nprintf(&ps, "-%c ", cmd->opt[j].c); + else + nprintf(&ps, "--%s ", cmd->opt[j].s); + if (cmd->opt[j].argUse != CMDNoArg) + nprintf(&ps, "%s ", cmd->opt[j].s); + } + } + first = PR_TRUE; + for (j=0; j<cmd->nopt; j++) { + if (cmd->cmd[i].opt & CMDBIT(j)) { + if (cmd->opt[j].c != 0 && cmd->opt[j].argUse == CMDNoArg) { + if (first) { + nprintf(&ps, "[-"); + first = !first; + } + nprintf(&ps, "%c", cmd->opt[j].c); + } + } + } + if (!first) nprintf(&ps, "] "); + for (j=0; j<cmd->nopt; j++) { + if (cmd->cmd[i].opt & CMDBIT(j) && + cmd->opt[j].argUse != CMDNoArg) { + if (cmd->opt[j].c != 0) + nprintf(&ps, "[-%c %s] ", cmd->opt[j].c, cmd->opt[j].s); + else + nprintf(&ps, "[--%s %s] ", cmd->opt[j].s, cmd->opt[j].s); + } + } + ps.indent -= inc; + print_ps_indent(&ps); + } + ps.indent = 0; + nprintf(&ps, "\n"); + exit(1); +} diff --git a/security/nss/cmd/cmdlib/cmdutil.h b/security/nss/cmd/cmdlib/cmdutil.h new file mode 100644 index 000000000..a51583f1c --- /dev/null +++ b/security/nss/cmd/cmdlib/cmdutil.h @@ -0,0 +1,118 @@ +/* ***** 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 ***** */ + +#ifndef _CMDUTIL_H_ +#define _CMDUTIL_H_ + +#include <stdio.h> +#include "nspr.h" +#include "nssbase.h" + +typedef int +(* CMD_PPFunc)(PRFileDesc *out, NSSItem *item, char *msg, int level); + + +/* + * Command Line Parsing routines + * + * The attempt here is to provide common functionality for command line + * parsing across an array of tools. The tools should obey the historical + * rules of: + * + * (1) one command per line, + * (2) the command should be uppercase, + * (3) options should be lowercase, + * (4) a short usage statement is presented in case of error, + * (5) a long usage statement is given by -? or --help + */ + +/* To aid in formatting usage output. XXX Uh, why exposed? */ +typedef struct cmdPrintStateStr cmdPrintState; + +typedef enum { + CMDArgReq = 0, + CMDArgOpt, + CMDNoArg +} CMDArg; + +struct cmdCommandLineArgStr { + char c; /* one-character alias for flag */ + char *s; /* string alias for flag */ + CMDArg argUse; /* flag takes an argument */ + char *arg; /* argument given for flag */ + PRBool on; /* flag was issued at command-line */ + int req; /* required arguments for commands */ + int opt; /* optional arguments for commands */ +}; + +struct cmdCommandLineOptStr { + char c; /* one-character alias for flag */ + char *s; /* string alias for flag */ + CMDArg argUse; /* flag takes an argument */ + char *arg; /* argument given for flag */ + PRBool on; /* flag was issued at command-line */ +}; + +typedef struct cmdCommandLineArgStr cmdCommandLineArg; +typedef struct cmdCommandLineOptStr cmdCommandLineOpt; + +struct cmdCommandStr { + int ncmd; + int nopt; + cmdCommandLineArg *cmd; + cmdCommandLineOpt *opt; +}; + +typedef struct cmdCommandStr cmdCommand; + +int +CMD_ParseCommandLine(int argc, char **argv, char *progName, cmdCommand *cmd); + +typedef void +(* cmdUsageCallback)(cmdPrintState *, int, PRBool, PRBool, PRBool); + +#define CMDBIT(n) (1<<n) + +void +CMD_Usage(char *progName, cmdCommand *cmd); + +void +CMD_LongUsage(char *progName, cmdCommand *cmd, cmdUsageCallback use); + +void +CMD_PrintUsageString(cmdPrintState *ps, char *str); + +#endif /* _CMDUTIL_H_ */ diff --git a/security/nss/cmd/cmdlib/config.mk b/security/nss/cmd/cmdlib/config.mk new file mode 100644 index 000000000..665828c63 --- /dev/null +++ b/security/nss/cmd/cmdlib/config.mk @@ -0,0 +1,47 @@ +# +# ***** 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 ***** + +# +# Override TARGETS variable so that only static libraries +# are specifed as dependencies within rules.mk. +# + +TARGETS = $(LIBRARY) +SHARED_LIBRARY = +IMPORT_LIBRARY = +PROGRAM = + diff --git a/security/nss/cmd/cmdlib/manifest.mn b/security/nss/cmd/cmdlib/manifest.mn new file mode 100644 index 000000000..1456a6a38 --- /dev/null +++ b/security/nss/cmd/cmdlib/manifest.mn @@ -0,0 +1,53 @@ +# +# ***** 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 ***** +CORE_DEPTH = ../../.. + +LIBRARY_NAME = cmdutil + +# MODULE public and private header directories are implicitly REQUIRED. +MODULE = seccmd + +DEFINES = -DNSPR20 + +EXPORTS = cmdutil.h \ + $(NULL) + +CSRCS = cmdline.c \ + $(NULL) + +REQUIRES = nss nspr dbm + diff --git a/security/nss/cmd/ilock/Makefile b/security/nss/cmd/ilock/Makefile new file mode 100644 index 000000000..9ee2a8f00 --- /dev/null +++ b/security/nss/cmd/ilock/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/ilock/ilock.c b/security/nss/cmd/ilock/ilock.c new file mode 100644 index 000000000..a62f9aacb --- /dev/null +++ b/security/nss/cmd/ilock/ilock.c @@ -0,0 +1,202 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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 Portable Runtime (NSPR). + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-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 ***** */ + +/* +** File: ilock.c +** Description: ilock.c is a unit test for nssilock. ilock.c +** tests the basic operation of nssilock. It should not be +** considered a complete test suite. +** +** To check that logging works, before running this test, +** define the following environment variables: +** +** +** +** +** +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <plgetopt.h> +#include <nspr.h> +#include <nssilock.h> + + +/* +** Test harness infrastructure +*/ +PRLogModuleInfo *lm; +PRLogModuleLevel msgLevel = PR_LOG_NONE; +PRIntn debug = 0; +PRUint32 failed_already = 0; +/* end Test harness infrastructure */ + +PRIntn optIterations = 1; /* default iterations */ + +PRIntn main(PRIntn argc, char *argv[]) +{ + PRIntn i; + { + /* + ** Get command line options + */ + PLOptStatus os; + PLOptState *opt = PL_CreateOptState(argc, argv, "hdvi:"); + + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) + { + if (PL_OPT_BAD == os) continue; + switch (opt->option) + { + case 'd': /* debug */ + debug = 1; + msgLevel = PR_LOG_ERROR; + break; + case 'v': /* verbose mode */ + msgLevel = PR_LOG_DEBUG; + break; + case 'i': /* number of iterations */ + optIterations = atol( opt->value ); + if ( 0 == optIterations ) optIterations = 1; /* coerce default on zero */ + break; + default: + break; + } + } + PL_DestroyOptState(opt); + } + + for ( i = 0 ; i < optIterations ; i++ ) { + /* First, test Lock */ + { + PZLock *pl; + PZMonitor *pm; + PZCondVar *cv; + PRStatus rc; + + pl = PZ_NewLock( nssILockOther ); + if ( NULL == pl ) { + failed_already = PR_TRUE; + goto Finished; + } + PZ_Lock( pl ); + + rc = PZ_Unlock( pl ); + if ( PR_FAILURE == rc ) { + failed_already = PR_TRUE; + goto Finished; + } + PZ_DestroyLock( pl ); + + /* now, test CVar */ + /* re-create the lock we just destroyed */ + pl = PZ_NewLock( nssILockOther ); + if ( NULL == pl ) { + failed_already = PR_TRUE; + goto Finished; + } + + cv = PZ_NewCondVar( pl ); + if ( NULL == cv ) { + failed_already = PR_TRUE; + goto Finished; + } + + PZ_Lock( pl ); + rc = PZ_NotifyCondVar( cv ); + if ( PR_FAILURE == rc ) { + failed_already = PR_TRUE; + goto Finished; + } + + rc = PZ_NotifyAllCondVar( cv ); + if ( PR_FAILURE == rc ) { + failed_already = PR_TRUE; + goto Finished; + } + + rc = PZ_WaitCondVar( cv, PR_SecondsToInterval(1)); + if ( PR_FAILURE == rc ) { + if ( PR_UNKNOWN_ERROR != PR_GetError()) { + failed_already = PR_TRUE; + goto Finished; + } + } + PZ_Unlock( pl ); + PZ_DestroyCondVar( cv ); + + /* Now, test Monitor */ + pm = PZ_NewMonitor( nssILockOther ); + if ( NULL == pm ) { + failed_already = PR_TRUE; + goto Finished; + } + + PZ_EnterMonitor( pm ); + + rc = PZ_Notify( pm ); + if ( PR_FAILURE == rc ) { + failed_already = PR_TRUE; + goto Finished; + } + rc = PZ_NotifyAll( pm ); + if ( PR_FAILURE == rc ) { + failed_already = PR_TRUE; + goto Finished; + } + rc = PZ_Wait( pm, PR_INTERVAL_NO_WAIT ); + if ( PR_FAILURE == rc ) { + failed_already = PR_TRUE; + goto Finished; + } + rc = PZ_ExitMonitor( pm ); + if ( PR_FAILURE == rc ) { + failed_already = PR_TRUE; + goto Finished; + } + PZ_DestroyMonitor( pm ); + } + } /* --- end for() --- */ + + +Finished: + if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS"); + return( (failed_already == PR_TRUE )? 1 : 0 ); +} /* main() */ +/* end ilock.c */ + diff --git a/security/nss/cmd/ilock/manifest.mn b/security/nss/cmd/ilock/manifest.mn new file mode 100644 index 000000000..055b0a05b --- /dev/null +++ b/security/nss/cmd/ilock/manifest.mn @@ -0,0 +1,48 @@ +# +# ***** 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 ***** +CORE_DEPTH = ../../.. + +DEFINES += -DNSPR20 + +# MODULE public and private header directories are implicitly REQUIRED. +MODULE = nss + +CSRCS = ilock.c + +PROGRAM = ilock +# PROGRAM = ./$(OBJDIR)/ilock.exe + diff --git a/security/nss/cmd/include/secnew.h b/security/nss/cmd/include/secnew.h new file mode 100644 index 000000000..b8310596b --- /dev/null +++ b/security/nss/cmd/include/secnew.h @@ -0,0 +1,166 @@ +/* ***** 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 ***** */ +#ifndef __secnew_h_ +#define __secnew_h_ + +#include <stdio.h> + +typedef struct BERTemplateStr BERTemplate; +typedef struct BERParseStr BERParse; +typedef struct SECArbStr SECArb; + +/* + * An array of these structures define an encoding for an object using + * DER. The array is terminated with an entry where kind == 0. + */ +struct BERTemplateStr { + /* Kind of item to decode/encode */ + unsigned long kind; + + /* + * Offset from base of structure to SECItem that will hold + * decoded/encoded value. + */ + unsigned short offset; + + /* + * Used with DER_SET or DER_SEQUENCE. If not zero then points to a + * sub-template. The sub-template is filled in and completed before + * continuing on. + */ + BERTemplate *sub; + + /* + * Argument value, dependent on kind. Size of structure to allocate + * when kind==DER_POINTER For Context-Specific Implicit types its the + * underlying type to use. + */ + unsigned long arg; +}; + +/* + * an arbitrary object + */ +struct SECArbStr { + unsigned long tag; /* NOTE: does not support high tag form */ + unsigned long length; /* as reported in stream */ + union { + SECItem item; + struct { + int numSubs; + SECArb **subs; + } cons; + } body; +}; + +/* + * Decode a piece of der encoded data. + * "dest" points to a structure that will be filled in with the + * decoding results. + * "t" is a template structure which defines the shape of the + * expected data. + * "src" is the ber encoded data. + */ + +extern SECStatus BER_Decode(PRArenaPool * arena, void *dest, BERTemplate *t, + SECArb *arb); + + +/* + * Encode a data structure into DER. + * "dest" will be filled in (and memory allocated) to hold the der + * encoded structure in "src" + * "t" is a template structure which defines the shape of the + * stored data + * "src" is a pointer to the structure that will be encoded + */ + +extern SECStatus BER_Encode(PRArenaPool *arena, SECItem *dest, BERTemplate *t, + void *src); + +/* + * Client provided function that will get called with all the bytes + * passing through the parser + */ +typedef void (*BERFilterProc)(void *instance, unsigned char *buf, int length); + +/* + * Client provided function that can will be called after the tag and + * length information has been collected. It can be set up to be called + * either before or after the data has been colleced. + */ +typedef void (*BERNotifyProc)( + void *instance, SECArb *arb, int depth, PRBool before); + +extern BERParse *BER_ParseInit(PRArenaPool *arena, PRBool forceDER); +extern SECArb *BER_ParseFini(BERParse *h); +extern SECStatus BER_ParseSome(BERParse *h, unsigned char *buf, int len); + +extern void BER_SetFilter(BERParse *h, BERFilterProc proc, void *instance); +extern void BER_SetLeafStorage(BERParse *h, PRBool keep); +extern void BER_SetNotifyProc(BERParse *h, BERNotifyProc proc, void *instance, + PRBool beforeData); + +/* + * A BERUnparseProc is used as a callback to put the encoded SECArb tree + * tree to some stream. It returns PR_TRUE if the unparsing is to be + * aborted. + */ +typedef SECStatus (*BERUnparseProc)( + void *instance, unsigned char *data, int length, SECArb* arb); + +/* + * BER_Unparse walks the SECArb tree calling the BERUnparseProc with + * various pieces. It returns SECFailure if there was an error during that + * tree walk. + */ +extern SECStatus BER_Unparse(SECArb *arb, BERUnparseProc proc, void *instance); + +/* + * BER_ResolveLengths does a recursive walk through the tree generating + * non-zero entries for the length field of each node. It will fail if it + * discoveres a non-constructed node with a unknown length data field. + * Leaves are supposed to be of known length. + */ +extern SECStatus BER_ResolveLengths(SECArb *arb); + +/* + * BER_PRettyPrintArb will write an ASCII version of the tree to the FILE + * out. + */ +extern SECStatus BER_PrettyPrintArb(FILE *out, SECArb* a); + +#endif /* __secnew_h_ */ diff --git a/security/nss/cmd/keyutil/Makefile b/security/nss/cmd/keyutil/Makefile new file mode 100644 index 000000000..eab21f369 --- /dev/null +++ b/security/nss/cmd/keyutil/Makefile @@ -0,0 +1,77 @@ +#! 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/keyutil/keyutil.c b/security/nss/cmd/keyutil/keyutil.c new file mode 100644 index 000000000..4da43a1bd --- /dev/null +++ b/security/nss/cmd/keyutil/keyutil.c @@ -0,0 +1,344 @@ +/* ***** 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 ***** */ + +#include <stdio.h> +#include <string.h> +#include "secutil.h" + +#if defined(XP_UNIX) +#include <unistd.h> +#include <sys/time.h> +#include <termios.h> +#endif + +#include "secopt.h" + +#if defined(XP_WIN) +#include <time.h> +#include <conio.h> +#endif + +#if defined(__sun) && !defined(SVR4) +extern int fclose(FILE*); +extern int fprintf(FILE *, char *, ...); +extern int getopt(int, char**, char*); +extern int isatty(int); +extern char *optarg; +extern char *sys_errlist[]; +#define strerror(errno) sys_errlist[errno] +#endif + +#include "nspr.h" +#include "prtypes.h" +#include "prtime.h" +#include "prlong.h" + +static char *progName; + +static SECStatus +ListKeys(SECKEYKeyDBHandle *handle, FILE *out) +{ + int rt; + + rt = SECU_PrintKeyNames(handle, out); + if (rt) { + SECU_PrintError(progName, "unable to list nicknames"); + return SECFailure; + } + return SECSuccess; +} + +static SECStatus +DumpPublicKey(SECKEYKeyDBHandle *handle, char *nickname, FILE *out) +{ + SECKEYLowPrivateKey *privKey; + SECKEYLowPublicKey *publicKey; + + /* check if key actually exists */ + if (SECU_CheckKeyNameExists(handle, nickname) == PR_FALSE) { + SECU_PrintError(progName, "the key \"%s\" does not exist", nickname); + return SECFailure; + } + + /* Read in key */ + privKey = SECU_GetPrivateKey(handle, nickname); + if (!privKey) { + return SECFailure; + } + + publicKey = SECKEY_LowConvertToPublicKey(privKey); + + /* Output public key (in the clear) */ + switch(publicKey->keyType) { + case rsaKey: + fprintf(out, "RSA Public-Key:\n"); + SECU_PrintInteger(out, &publicKey->u.rsa.modulus, "modulus", 1); + SECU_PrintInteger(out, &publicKey->u.rsa.publicExponent, + "publicExponent", 1); + break; + case dsaKey: + fprintf(out, "DSA Public-Key:\n"); + SECU_PrintInteger(out, &publicKey->u.dsa.params.prime, "prime", 1); + SECU_PrintInteger(out, &publicKey->u.dsa.params.subPrime, + "subPrime", 1); + SECU_PrintInteger(out, &publicKey->u.dsa.params.base, "base", 1); + SECU_PrintInteger(out, &publicKey->u.dsa.publicValue, "publicValue", 1); + break; + default: + fprintf(out, "unknown key type\n"); + break; + } + return SECSuccess; +} + +static SECStatus +DumpPrivateKey(SECKEYKeyDBHandle *handle, char *nickname, FILE *out) +{ + SECKEYLowPrivateKey *key; + + /* check if key actually exists */ + if (SECU_CheckKeyNameExists(handle, nickname) == PR_FALSE) { + SECU_PrintError(progName, "the key \"%s\" does not exist", nickname); + return SECFailure; + } + + /* Read in key */ + key = SECU_GetPrivateKey(handle, nickname); + if (!key) { + SECU_PrintError(progName, "error retrieving key"); + return SECFailure; + } + + switch(key->keyType) { + case rsaKey: + fprintf(out, "RSA Private-Key:\n"); + SECU_PrintInteger(out, &key->u.rsa.modulus, "modulus", 1); + SECU_PrintInteger(out, &key->u.rsa.publicExponent, "publicExponent", 1); + SECU_PrintInteger(out, &key->u.rsa.privateExponent, + "privateExponent", 1); + SECU_PrintInteger(out, &key->u.rsa.prime1, "prime1", 1); + SECU_PrintInteger(out, &key->u.rsa.prime2, "prime2", 1); + SECU_PrintInteger(out, &key->u.rsa.exponent1, "exponent1", 1); + SECU_PrintInteger(out, &key->u.rsa.exponent2, "exponent2", 1); + SECU_PrintInteger(out, &key->u.rsa.coefficient, "coefficient", 1); + break; + case dsaKey: + fprintf(out, "DSA Private-Key:\n"); + SECU_PrintInteger(out, &key->u.dsa.params.prime, "prime", 1); + SECU_PrintInteger(out, &key->u.dsa.params.subPrime, "subPrime", 1); + SECU_PrintInteger(out, &key->u.dsa.params.base, "base", 1); + SECU_PrintInteger(out, &key->u.dsa.publicValue, "publicValue", 1); + SECU_PrintInteger(out, &key->u.dsa.privateValue, "privateValue", 1); + break; + default: + fprintf(out, "unknown key type\n"); + break; + } + return SECSuccess; +} + +static SECStatus +ChangePassword(SECKEYKeyDBHandle *handle) +{ + SECStatus rv; + + /* Write out database with a new password */ + rv = SECU_ChangeKeyDBPassword(handle, NULL); + if (rv) { + SECU_PrintError(progName, "unable to change key password"); + } + return rv; +} + +static SECStatus +DeletePrivateKey (SECKEYKeyDBHandle *keyHandle, char *nickName) +{ + SECStatus rv; + + rv = SECU_DeleteKeyByName (keyHandle, nickName); + if (rv != SECSuccess) + fprintf(stderr, "%s: problem deleting private key (%s)\n", + progName, SECU_Strerror(PR_GetError())); + return (rv); + +} + + +static void +Usage(const char *progName) +{ + fprintf(stderr, + "Usage: %s -p name [-d keydir]\n", progName); + fprintf(stderr, + " %s -P name [-d keydir]\n", progName); + fprintf(stderr, + " %s -D name [-d keydir]\n", progName); + fprintf(stderr, + " %s -l [-d keydir]\n", progName); + fprintf(stderr, + " %s -c [-d keydir]\n", progName); + + fprintf(stderr, "%-20s Pretty print public key info for named key\n", + "-p nickname"); + fprintf(stderr, "%-20s Pretty print private key info for named key\n", + "-P nickname"); + fprintf(stderr, "%-20s Delete named private key from the key database\n", + "-D nickname"); + fprintf(stderr, "%-20s List the nicknames for the keys in a database\n", + "-l"); + fprintf(stderr, "%-20s Change the key database password\n", + "-c"); + fprintf(stderr, "\n"); + fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n", + "-d keydir"); + + exit(-1); +} + +int main(int argc, char **argv) +{ + int o, changePassword, deleteKey, dumpPublicKey, dumpPrivateKey, list; + char *nickname; + SECStatus rv; + SECKEYKeyDBHandle *keyHandle; + + progName = strrchr(argv[0], '/'); + progName = progName ? progName+1 : argv[0]; + + /* Parse command line arguments */ + changePassword = deleteKey = dumpPublicKey = dumpPrivateKey = list = 0; + nickname = NULL; + + while ((o = getopt(argc, argv, "ADP:cd:glp:")) != -1) { + switch (o) { + case '?': + Usage(progName); + break; + + case 'A': + fprintf(stderr, "%s: Can no longer add a key.", progName); + fprintf(stderr, " Use pkcs12 to import a key.\n\n"); + Usage(progName); + break; + + case 'D': + deleteKey = 1; + nickname = optarg; + break; + + case 'P': + dumpPrivateKey = 1; + nickname = optarg; + break; + + case 'c': + changePassword = 1; + break; + + case 'd': + SECU_ConfigDirectory(optarg); + break; + + case 'g': + fprintf(stderr, "%s: Can no longer generate a key.", progName); + fprintf(stderr, " Use certutil to generate a cert request.\n\n"); + Usage(progName); + break; + + case 'l': + list = 1; + break; + + case 'p': + dumpPublicKey = 1; + nickname = optarg; + break; + } + } + + if (dumpPublicKey+changePassword+dumpPrivateKey+list+deleteKey != 1) + Usage(progName); + + if ((list || changePassword) && nickname) + Usage(progName); + + if ((dumpPublicKey || dumpPrivateKey || deleteKey) && !nickname) + Usage(progName); + + + /* Call the libsec initialization routines */ + PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + SEC_Init(); + + /* + * XXX Note that the following opens the key database writable. + * If dumpPublicKey or dumpPrivateKey or list, though, we only want + * to open it read-only. There needs to be a better interface + * to the initialization routines so that we can specify which way + * to open it. + */ + rv = SECU_PKCS11Init(); + if (rv != SECSuccess) { + SECU_PrintError(progName, "SECU_PKCS11Init failed"); + return -1; + } + + keyHandle = SECKEY_GetDefaultKeyDB(); + if (keyHandle == NULL) { + SECU_PrintError(progName, "could not open key database"); + return -1; + } + + SECU_RegisterDynamicOids(); + if (dumpPublicKey) { + rv = DumpPublicKey(keyHandle, nickname, stdout); + } else + if (changePassword) { + rv = ChangePassword(keyHandle); + } else + if (dumpPrivateKey) { + rv = DumpPrivateKey(keyHandle, nickname, stdout); + } else + if (list) { + rv = ListKeys(keyHandle, stdout); + } else + if (deleteKey) { + rv = DeletePrivateKey(keyHandle, nickname); + } + + + return rv ? -1 : 0; +} diff --git a/security/nss/cmd/keyutil/manifest.mn b/security/nss/cmd/keyutil/manifest.mn new file mode 100644 index 000000000..ec2d043c8 --- /dev/null +++ b/security/nss/cmd/keyutil/manifest.mn @@ -0,0 +1,54 @@ +# +# ***** 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 ***** + +CORE_DEPTH = ../../.. + +DEFINES += -DNSPR20 + +# MODULE public and private header directories are implicitly REQUIRED. +MODULE = nss + +CSRCS = \ + keyutil.c \ + $(NULL) + +# The MODULE is always implicitly required. +# Listing it here in REQUIRES makes it appear twice in the cc command line. +REQUIRES = seccmd dbm + + +PROGRAM = keyutil diff --git a/security/nss/cmd/pkiutil/Makefile b/security/nss/cmd/pkiutil/Makefile new file mode 100644 index 000000000..865888882 --- /dev/null +++ b/security/nss/cmd/pkiutil/Makefile @@ -0,0 +1,80 @@ +#! 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/pkiutil/manifest.mn b/security/nss/cmd/pkiutil/manifest.mn new file mode 100644 index 000000000..e82483ca1 --- /dev/null +++ b/security/nss/cmd/pkiutil/manifest.mn @@ -0,0 +1,51 @@ +# +# ***** 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 ***** + +CORE_DEPTH = ../../.. + +# MODULE public and private header directories are implicitly REQUIRED. +MODULE = nss + +CSRCS = \ + pkiutil.c \ + $(NULL) + +# The MODULE is always implicitly required. +# Listing it here in REQUIRES makes it appear twice in the cc command line. +REQUIRES = dbm seccmd + +PROGRAM = pkiutil diff --git a/security/nss/cmd/pkiutil/pkiutil.c b/security/nss/cmd/pkiutil/pkiutil.c new file mode 100644 index 000000000..b059baa87 --- /dev/null +++ b/security/nss/cmd/pkiutil/pkiutil.c @@ -0,0 +1,376 @@ +/* ***** 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 ***** */ + +#include "nspr.h" +#include "prtypes.h" +#include "prtime.h" +#include "prlong.h" +#include "nss.h" +#include "cmdutil.h" +#include "nsspki.h" +/* hmmm...*/ +#include "pki.h" + +#define PKIUTIL_VERSION_STRING "pkiutil version 0.1" + +char *progName = NULL; + +typedef struct { + PRBool raw; + PRBool ascii; + char *name; + PRFileDesc *file; +} objOutputMode; + +typedef enum { + PKIUnknown = -1, + PKICertificate, + PKIPublicKey, + PKIPrivateKey, + PKIAny +} PKIObjectType; + +static PKIObjectType +get_object_class(char *type) +{ + if (strcmp(type, "certificate") == 0 || strcmp(type, "cert") == 0 || + strcmp(type, "Certificate") == 0 || strcmp(type, "Cert") == 0) { + return PKICertificate; + } else if (strcmp(type, "public_key") == 0 || + strcmp(type, "PublicKey") == 0) { + return PKIPublicKey; + } else if (strcmp(type, "private_key") == 0 || + strcmp(type, "PrivateKey") == 0) { + return PKIPrivateKey; + } else if (strcmp(type, "all") == 0 || strcmp(type, "any") == 0) { + return PKIAny; + } + fprintf(stderr, "%s: \"%s\" is not a valid PKCS#11 object type.\n", + progName, type); + return PKIUnknown; +} + +static PRStatus +print_cert_callback(NSSCertificate *c, void *arg) +{ + int i; + NSSUTF8 *label; + NSSItem *id; + label = NSSCertificate_GetLabel(c); + printf("%s\n", label); + nss_ZFreeIf((void*)label); +#if 0 + id = NSSCertificate_GetID(c); + for (i=0; i<id->size; i++) { + printf("%c", ((char *)id->data)[i]); + } + printf("\n"); +#endif + return PR_SUCCESS; +} + +/* pkiutil commands */ +enum { + cmd_Add = 0, + cmd_Dump, + cmd_List, + cmd_Version, + pkiutil_num_commands +}; + +/* pkiutil options */ +enum { + opt_Help = 0, + opt_Ascii, + opt_ProfileDir, + opt_TokenName, + opt_InputFile, + opt_Nickname, + opt_OutputFile, + opt_Binary, + opt_Trust, + opt_Type, + pkiutil_num_options +}; + +static cmdCommandLineArg pkiutil_commands[] = +{ + { /* cmd_Add */ 'A', "add", CMDNoArg, 0, PR_FALSE, + CMDBIT(opt_Nickname) | CMDBIT(opt_Trust), + CMDBIT(opt_Ascii) | CMDBIT(opt_ProfileDir) + | CMDBIT(opt_TokenName) | CMDBIT(opt_InputFile) + | CMDBIT(opt_Binary) | CMDBIT(opt_Type) }, + { /* cmd_Dump */ 0 , "dump", CMDNoArg, 0, PR_FALSE, + CMDBIT(opt_Nickname), + CMDBIT(opt_Ascii) | CMDBIT(opt_ProfileDir) + | CMDBIT(opt_TokenName) | CMDBIT(opt_Binary) + | CMDBIT(opt_Type) }, + { /* cmd_List */ 'L', "list", CMDNoArg, 0, PR_FALSE, 0, + CMDBIT(opt_Ascii) | CMDBIT(opt_ProfileDir) + | CMDBIT(opt_TokenName) | CMDBIT(opt_Binary) + | CMDBIT(opt_Nickname) | CMDBIT(opt_Type) }, + { /* cmd_Version */ 'Y', "version", CMDNoArg, 0, PR_FALSE, 0, 0 } +}; + +static cmdCommandLineOpt pkiutil_options[] = +{ + { /* opt_Help */ '?', "help", CMDNoArg, 0, PR_FALSE }, + { /* opt_Ascii */ 'a', "ascii", CMDNoArg, 0, PR_FALSE }, + { /* opt_ProfileDir */ 'd', "dbdir", CMDArgReq, 0, PR_FALSE }, + { /* opt_TokenName */ 'h', "token", CMDArgReq, 0, PR_FALSE }, + { /* opt_InputFile */ 'i', "infile", CMDArgReq, 0, PR_FALSE }, + { /* opt_Nickname */ 'n', "nickname", CMDArgReq, 0, PR_FALSE }, + { /* opt_OutputFile */ 'o', "outfile", CMDArgReq, 0, PR_FALSE }, + { /* opt_Binary */ 'r', "raw", CMDNoArg, 0, PR_FALSE }, + { /* opt_Trust */ 't', "trust", CMDArgReq, 0, PR_FALSE }, + { /* opt_Type */ 0 , "type", CMDArgReq, 0, PR_FALSE } +}; + +void pkiutil_usage(cmdPrintState *ps, + int num, PRBool cmd, PRBool header, PRBool footer) +{ +#define pusg CMD_PrintUsageString + if (header) { + pusg(ps, "utility for managing PKCS#11 objects (certs and keys)\n"); + } else if (footer) { + /* + printf("certificate trust can be:\n"); + printf(" p - valid peer, P - trusted peer (implies p)\n"); + printf(" c - valid CA\n"); + printf(" T - trusted CA to issue client certs (implies c)\n"); + printf(" C - trusted CA to issue server certs (implies c)\n"); + printf(" u - user cert\n"); + printf(" w - send warning\n"); + */ + } else if (cmd) { + switch(num) { + case cmd_Add: + pusg(ps, "Add an object to the token"); break; + case cmd_Dump: + pusg(ps, "Dump a single object"); break; + case cmd_List: + pusg(ps, "List objects on the token (-n for single object)"); break; + case cmd_Version: + pusg(ps, "Report version"); break; + default: + pusg(ps, "Unrecognized command"); break; + } + } else { + switch(num) { + case opt_Ascii: + pusg(ps, "Use ascii (base-64 encoded) mode for I/O"); break; + case opt_ProfileDir: + pusg(ps, "Directory containing security databases (def: \".\")"); + break; + case opt_TokenName: + pusg(ps, "Name of PKCS#11 token to use (def: internal)"); break; + case opt_InputFile: + pusg(ps, "File for input (def: stdin)"); break; + case opt_Nickname: + pusg(ps, "Nickname of object"); break; + case opt_OutputFile: + pusg(ps, "File for output (def: stdout)"); break; + case opt_Binary: + pusg(ps, "Use raw (binary der-encoded) mode for I/O"); break; + case opt_Trust: + pusg(ps, "Trust level for certificate"); break; + case opt_Help: break; + default: + pusg(ps, "Unrecognized option"); + } + } +} + +int +main(int argc, char **argv) +{ + PRFileDesc *infile = NULL; + PRFileDesc *outfile = NULL; + char *profiledir = "./"; +#if 0 + secuPWData pwdata = { PW_NONE, 0 }; +#endif + int objclass = 3; /* ANY */ + NSSTrustDomain *root_cert_td = NULL; + char *rootpath = NULL; + char builtin_name[]= "libnssckbi.so"; /* temporary hardcode */ + PRStatus rv = PR_SUCCESS; + + int cmdToRun; + cmdCommand pkiutil; + pkiutil.ncmd = pkiutil_num_commands; + pkiutil.nopt = pkiutil_num_options; + pkiutil.cmd = pkiutil_commands; + pkiutil.opt = pkiutil_options; + + progName = strrchr(argv[0], '/'); + progName = progName ? progName+1 : argv[0]; + + cmdToRun = CMD_ParseCommandLine(argc, argv, progName, &pkiutil); + +#if 0 + { int i, nc; + for (i=0; i<pkiutil.ncmd; i++) + printf("%s: %s <%s>\n", pkiutil.cmd[i].s, + (pkiutil.cmd[i].on) ? "on" : "off", + pkiutil.cmd[i].arg); + for (i=0; i<pkiutil.nopt; i++) + printf("%s: %s <%s>\n", pkiutil.opt[i].s, + (pkiutil.opt[i].on) ? "on" : "off", + pkiutil.opt[i].arg); + } +#endif + + if (pkiutil.opt[opt_Help].on) + CMD_LongUsage(progName, &pkiutil, pkiutil_usage); + + if (cmdToRun < 0) + CMD_Usage(progName, &pkiutil); + + /* -d */ + if (pkiutil.opt[opt_ProfileDir].on) { + profiledir = strdup(pkiutil.opt[opt_ProfileDir].arg); + } + + /* -i */ + if (pkiutil.opt[opt_InputFile].on) { + char *fn = pkiutil.opt[opt_InputFile].arg; + infile = PR_Open(fn, PR_RDONLY, 0660); + } else { + infile = PR_STDIN; + } + + /* -o */ + if (pkiutil.opt[opt_OutputFile].on) { + char *fn = pkiutil.opt[opt_OutputFile].arg; + outfile = PR_Open(fn, PR_WRONLY | PR_CREATE_FILE, 0660); + } else { + outfile = PR_STDOUT; + } + + /* --type can be found on many options */ + if (pkiutil.opt[opt_Type].on) + objclass = get_object_class(pkiutil.opt[opt_Type].arg); + else if (cmdToRun == cmd_Dump && pkiutil.cmd[cmd_Dump].arg) + objclass = get_object_class(pkiutil.cmd[cmd_Dump].arg); + else if (cmdToRun == cmd_List && pkiutil.cmd[cmd_List].arg) + objclass = get_object_class(pkiutil.cmd[cmd_List].arg); + else if (cmdToRun == cmd_Add && pkiutil.cmd[cmd_Add].arg) + objclass = get_object_class(pkiutil.cmd[cmd_Add].arg); + if (objclass < 0) + goto done; + + /* --print is an alias for --list --nickname */ + if (cmdToRun == cmd_Dump) cmdToRun = cmd_List; + + /* if list has raw | ascii must have -n. can't have both raw and ascii */ + if (pkiutil.opt[opt_Binary].on || pkiutil.opt[opt_Ascii].on) { + if (cmdToRun == cmd_List && !pkiutil.opt[opt_Nickname].on) { + fprintf(stderr, "%s: specify a object to output with -n\n", + progName); + CMD_LongUsage(progName, &pkiutil, pkiutil_usage); + } + } + + /* initialize */ + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + /* NSS_InitReadWrite(profiledir); */ + NSS_NoDB_Init(NULL); + + /* Display version info and exit */ + if (cmdToRun == cmd_Version) { + printf("%s\nNSS Version %s\n", PKIUTIL_VERSION_STRING, NSS_VERSION); + goto done; + } + + /* XXX okay - bootstrap stan by loading the root cert module for testing */ + root_cert_td = NSSTrustDomain_Create(NULL, NULL, NULL, NULL); + { + int rootpathlen = strlen(profiledir) + strlen(builtin_name) + 1; + rootpath = (char *)malloc(rootpathlen); + memcpy(rootpath, profiledir, strlen(profiledir)); + memcpy(rootpath + strlen(profiledir), + builtin_name, strlen(builtin_name)); + rootpath[rootpathlen - 1] = '\0'; + } + NSSTrustDomain_LoadModule(root_cert_td, "Builtin Root Module", rootpath, + NULL, NULL); + + printf("\n"); + if (pkiutil.opt[opt_Nickname].on) { + int i; + NSSCertificate **certs; + NSSCertificate *cert; + certs = NSSTrustDomain_FindCertificatesByNickname(root_cert_td, + pkiutil.opt[opt_Nickname].arg, NULL, 0, NULL); + i = 0; + while ((cert = certs[i++]) != NULL) { + printf("Found cert:\n"); + print_cert_callback(cert, NULL); + } + } else { + NSSTrustDomain_TraverseCertificates(root_cert_td, print_cert_callback, 0); + } + + NSSTrustDomain_Destroy(root_cert_td); + + /* List token objects */ + if (cmdToRun == cmd_List) { +#if 0 + rv = list_token_objects(slot, objclass, + pkiutil.opt[opt_Nickname].arg, + pkiutil.opt[opt_Binary].on, + pkiutil.opt[opt_Ascii].on, + outfile, &pwdata); +#endif + goto done; + } + +#if 0 + /* Import an object into the token. */ + if (cmdToRun == cmd_Add) { + rv = add_object_to_token(slot, object); + goto done; + } +#endif + +done: + if (NSS_Shutdown() != SECSuccess) { + exit(1); + } + + return rv; +} diff --git a/security/nss/cmd/pkiutil/platlibs.mk b/security/nss/cmd/pkiutil/platlibs.mk new file mode 100644 index 000000000..d0cd7ee58 --- /dev/null +++ b/security/nss/cmd/pkiutil/platlibs.mk @@ -0,0 +1,57 @@ +# +# ***** 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 ***** + +# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS) +EXTRA_LIBS += \ + $(DIST)/lib/libcmdutil.$(LIB_SUFFIX) \ + $(NULL) + +ifeq ($(OS_ARCH), AIX) +EXTRA_SHARED_LIBS += -brtl +endif + +# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS) +# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX. +EXTRA_SHARED_LIBS += \ + -L$(DIST)/lib/ \ + -lnsspki3 \ + -lnss3 \ + -lplc4 \ + -lplds4 \ + -lnspr4 \ + $(NULL) + diff --git a/security/nss/cmd/sslstrength/Makefile b/security/nss/cmd/sslstrength/Makefile new file mode 100644 index 000000000..7cfeaac2a --- /dev/null +++ b/security/nss/cmd/sslstrength/Makefile @@ -0,0 +1,86 @@ +#! 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 + +ifeq (,$(filter-out WINNT WIN95 WIN16,$(OS_TARGET))) # omits WINCE +ifndef BUILD_OPT +LDFLAGS += /subsystem:console /profile /debug /machine:I386 /incremental:no +OS_CFLAGS += -D_CONSOLE +endif +endif + + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + +#include ../platlibs.mk + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +include ../platrules.mk + diff --git a/security/nss/cmd/sslstrength/manifest.mn b/security/nss/cmd/sslstrength/manifest.mn new file mode 100644 index 000000000..ceb49dd59 --- /dev/null +++ b/security/nss/cmd/sslstrength/manifest.mn @@ -0,0 +1,54 @@ +# ***** 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 ***** + +CORE_DEPTH = ../../.. + +MODULE = nss + +EXPORTS = + +CSRCS = sslstrength.c \ + $(NULL) + +PROGRAM = sslstrength + +REQUIRES = dbm seccmd + +DEFINES += -DDLL_PREFIX=\"$(DLL_PREFIX)\" -DDLL_SUFFIX=\"$(DLL_SUFFIX)\" + +PACKAGE_FILES = sslstrength + +ARCHIVE_NAME = sslstrength diff --git a/security/nss/cmd/sslstrength/sslstr.cgi b/security/nss/cmd/sslstrength/sslstr.cgi new file mode 100644 index 000000000..dc632eebf --- /dev/null +++ b/security/nss/cmd/sslstrength/sslstr.cgi @@ -0,0 +1,300 @@ +#!/usr/bin/perl +# +# ***** 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 ***** + + +use CGI qw(:standard); + + + +# Replace this will the full path to the sslstrength executable. +$sslstrength = "./sslstrength"; + + +# Replace this with the name of this CGI. + +$sslcgi = "sslstr.cgi"; + + +$query = new CGI; + +print header; + +print "<HTML><HEAD> +<SCRIPT language='javascript'> + +function doexport(form) { + form.ssl2ciphers.options[0].selected=0; + form.ssl2ciphers.options[1].selected=0; + form.ssl2ciphers.options[2].selected=0; + form.ssl2ciphers.options[3].selected=0; + form.ssl2ciphers.options[4].selected=1; + form.ssl2ciphers.options[5].selected=1; + + form.ssl3ciphers.options[0].selected=1; + form.ssl3ciphers.options[1].selected=1; + form.ssl3ciphers.options[2].selected=0; + form.ssl3ciphers.options[3].selected=1; + form.ssl3ciphers.options[4].selected=1; + form.ssl3ciphers.options[5].selected=1; + form.ssl3ciphers.options[6].selected=0; + form.ssl3ciphers.options[7].selected=0; + + +} + +function dodomestic(form) { + form.ssl2ciphers.options[0].selected=1; + form.ssl2ciphers.options[1].selected=1; + form.ssl2ciphers.options[2].selected=1; + form.ssl2ciphers.options[3].selected=1; + form.ssl2ciphers.options[4].selected=1; + form.ssl2ciphers.options[5].selected=1; + + form.ssl3ciphers.options[0].selected=1; + form.ssl3ciphers.options[1].selected=1; + form.ssl3ciphers.options[2].selected=1; + form.ssl3ciphers.options[3].selected=1; + form.ssl3ciphers.options[4].selected=1; + form.ssl3ciphers.options[5].selected=1; + form.ssl3ciphers.options[6].selected=1; + form.ssl3ciphers.options[7].selected=1; + +} + +function doclearssl2(form) { + form.ssl2ciphers.options[0].selected=0; + form.ssl2ciphers.options[1].selected=0; + form.ssl2ciphers.options[2].selected=0; + form.ssl2ciphers.options[3].selected=0; + form.ssl2ciphers.options[4].selected=0; + form.ssl2ciphers.options[5].selected=0; +} + + +function doclearssl3(form) { + form.ssl3ciphers.options[0].selected=0; + form.ssl3ciphers.options[1].selected=0; + form.ssl3ciphers.options[2].selected=0; + form.ssl3ciphers.options[3].selected=0; + form.ssl3ciphers.options[4].selected=0; + form.ssl3ciphers.options[5].selected=0; + form.ssl3ciphers.options[6].selected=0; + form.ssl3ciphers.options[7].selected=0; + +} + +function dohost(form,hostname) { + form.host.value=hostname; + } + + + +</SCRIPT> +<TITLE>\n"; +print "SSLStrength\n"; +print "</TITLE></HEAD>\n"; + +print "<h1>SSLStrength</h1>\n"; + +if ($query->param('dotest')) { + print "Output from sslstrength: \n"; + print "<pre>\n"; + + $cs = ""; + + @ssl2ciphers = $query->param('ssl2ciphers'); + for $cipher (@ssl2ciphers) { + if ($cipher eq "SSL_EN_RC2_128_WITH_MD5") { $cs .= "a"; } + if ($cipher eq "SSL_EN_RC2_128_CBC_WITH_MD5") { $cs .= "b"; } + if ($cipher eq "SSL_EN_DES_192_EDE3_CBC_WITH_MD5") { $cs .= "c"; } + if ($cipher eq "SSL_EN_DES_64_CBC_WITH_MD5") { $cs .= "d"; } + if ($cipher eq "SSL_EN_RC4_128_EXPORT40_WITH_MD5") { $cs .= "e"; } + if ($cipher eq "SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5") { $cs .= "f"; } + } + + @ssl3ciphers = $query->param('ssl3ciphers'); + for $cipher (@ssl3ciphers) { + if ($cipher eq "SSL_RSA_WITH_RC4_128_MD5") { $cs .= "i"; } + if ($cipher eq "SSL_RSA_WITH_3DES_EDE_CBC_SHA") { $cs .= "j"; } + if ($cipher eq "SSL_RSA_WITH_DES_CBC_SHA") { $cs .= "k"; } + if ($cipher eq "SSL_RSA_EXPORT_WITH_RC4_40_MD5") { $cs .= "l"; } + if ($cipher eq "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5") { $cs .= "m"; } + if ($cipher eq "SSL_RSA_WITH_NULL_MD5") { $cs .= "o"; } + if ($cipher eq "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA") { $cs .= "p"; } + if ($cipher eq "SSL_RSA_FIPS_WITH_DES_CBC_SHA") { $cs .= "q"; } + } + + $hs = $query->param('host'); + if ($hs eq "") { + print "</pre>You must specify a host to connect to.<br><br>\n"; + exit(0); + } + + $ps = $query->param('policy'); + + $cmdstring = "$sslstrength $hs policy=$ps ciphers=$cs"; + + print "running sslstrength:\n"; + print "$cmdstring\n"; + + $r = open(SSLS, "$cmdstring |"); + if ($r == 0) { + print "<pre>There was a problem starting $cmdstring<br><br>\n"; + exit(0); + } + while (<SSLS>) { + print "$_"; + } + close(SSLS); + + + print "</pre>\n"; + +} + +else { +print "<FORM method=post action=$sslcgi>\n"; +print "<hr> +<h2>Host Name</h2> +<TABLE BORDER=0 CELLPADDING=20> +<TR> +<TD> +Type hostname here:<br> +<input type=text name=host size=30> <br><br> +<TD> + <b>Or click these buttons to test some well-known servers</b><br> + <TABLE BORDER=0> + <TR> + <TD> + Export servers: + <TD> + <input type=button value='F-Tech' onclick=dohost(this.form,'strongbox.ftech.net')> + </TR> + <TR> + <TD> + Domestic servers: + <TD> + <input type=button value='Wells Fargo' onclick=dohost(this.form,'banking.wellsfargo.com')> + </TR> + <TR> + <TD> + Step-Up Servers + <TD> + <input type=button value='Barclaycard' onclick=dohost(this.form,'enigma.barclaycard.co.uk')> + <input type=button value='BBVnet' onclick=dohost(this.form,'www.bbvnet.com')> + <input type=button value='BHIF' onclick=dohost(this.form,'empresas.bhif.cl')> + </TR> + </TABLE> +</TR> +</TABLE> +<br> +<hr> +<br> +<h2>Encryption policy</h2> +<input type=radio name=policy VALUE=export onclick=doexport(this.form)> +Export<br> +<input type=radio name=policy VALUE=domestic CHECKED onclick=dodomestic(this.form)> +Domestic<br> +<br> +<hr> +<br> +<h2>Cipher Selection</h2> +(use ctrl to multi-select)<br> +<table> +<tr> +<td>SSL 2 Ciphers +<td> +<SELECT NAME=ssl2ciphers SIZE=6 MULTIPLE align=bottom> +<OPTION SELECTED>SSL_EN_RC4_128_WITH_MD5 +<OPTION SELECTED>SSL_EN_RC2_128_CBC_WITH_MD5 +<OPTION SELECTED>SSL_EN_DES_192_EDE3_CBC_WITH_MD5 +<OPTION SELECTED>SSL_EN_DES_64_CBC_WITH_MD5 +<OPTION SELECTED>SSL_EN_RC4_128_EXPORT40_WITH_MD5 +<OPTION SELECTED>SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 +</SELECT> +<input type=button Value='Clear all' onclick = 'doclearssl2(this.form)'> +</tr> +<tr> +<td>SSL3 Ciphers +<td> +<SELECT NAME=ssl3ciphers SIZE=8 MULTIPLE> +<OPTION SELECTED>SSL_RSA_WITH_RC4_128_MD5 +<OPTION SELECTED>SSL_RSA_WITH_3DES_EDE_CBC_SHA +<OPTION SELECTED>SSL_RSA_WITH_DES_CBC_SHA +<OPTION SELECTED>SSL_RSA_EXPORT_WITH_RC4_40_MD5 +<OPTION SELECTED>SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 +<OPTION SELECTED>SSL_RSA_WITH_NULL_MD5 +<OPTION SELECTED>SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA +<OPTION SELECTED>SSL_RSA_FIPS_WITH_DES_CBC_SHA +</SELECT> +<input type=button value='Clear all' onclick = 'doclearssl3(this.form)'> + +<TD> +<input type=submit name=dotest value='Run SSLStrength'> +</tr> +</table> +<input type=hidden name=dotest> +<br> +<br> +</form> +\n"; + +} + + +exit(0); + + +__END__ + + id CipherName Domestic Export + a SSL_EN_RC4_128_WITH_MD5 (ssl2) Yes No + b SSL_EN_RC2_128_CBC_WITH_MD5 (ssl2) Yes No + c SSL_EN_DES_192_EDE3_CBC_WITH_MD5 (ssl2) Yes No + d SSL_EN_DES_64_CBC_WITH_MD5 (ssl2) Yes No + e SSL_EN_RC4_128_EXPORT40_WITH_MD5 (ssl2) Yes Yes + f SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 (ssl2) Yes Yes + i SSL_RSA_WITH_RC4_128_MD5 (ssl3) Yes Step-up only + j SSL_RSA_WITH_3DES_EDE_CBC_SHA (ssl3) Yes Step-up only + k SSL_RSA_WITH_DES_CBC_SHA (ssl3) Yes No + l SSL_RSA_EXPORT_WITH_RC4_40_MD5 (ssl3) Yes Yes + m SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (ssl3) Yes Yes + o SSL_RSA_WITH_NULL_MD5 (ssl3) Yes Yes + + + diff --git a/security/nss/cmd/sslstrength/sslstrength.c b/security/nss/cmd/sslstrength/sslstrength.c new file mode 100644 index 000000000..ee4c0a692 --- /dev/null +++ b/security/nss/cmd/sslstrength/sslstrength.c @@ -0,0 +1,625 @@ +/* ***** 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 ***** */ + +#ifdef SSLTELNET +#include <termios.h> +#endif + +/* Portable layer header files */ +#include "prinit.h" +#include "prprf.h" +#include "prsystem.h" +#include "prmem.h" +#include "plstr.h" +#include "prnetdb.h" +#include "prinrval.h" + +#include "secutil.h" + +/* Security library files */ +#include "cert.h" +#include "ssl.h" +#include "sslproto.h" +#include "secmod.h" +#include "nss.h" + +/* define this if you want telnet capability! */ + +/* #define SSLTELNET 1 */ + +PRInt32 debug; + +#ifdef DEBUG_stevep +#define dbmsg(x) if (verbose) PR_fprintf(PR_STDOUT,x); +#else +#define dbmsg(x) ; +#endif + + +/* Set SSL Policy to Domestic (strong=1) or Export (strong=0) */ + +#define ALLOW(x) SSL_CipherPolicySet(x,SSL_ALLOWED); SSL_CipherPrefSetDefault(x,1); +#define DISALLOW(x) SSL_CipherPolicySet(x,SSL_NOT_ALLOWED); SSL_CipherPrefSetDefault(x,0); +#define MAYBEALLOW(x) SSL_CipherPolicySet(x,SSL_RESTRICTED); SSL_CipherPrefSetDefault(x,1); + +struct CipherPolicy { + char number; + long id; + char *name; + PRInt32 pref; + PRInt32 domestic; + PRInt32 export; +}; + +struct CipherPolicy ciphers[] = { + { 'a',SSL_EN_RC4_128_WITH_MD5, "SSL_EN_RC4_128_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, + { 'b',SSL_EN_RC2_128_CBC_WITH_MD5, "SSL_EN_RC2_128_CBC_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, + { 'c',SSL_EN_DES_192_EDE3_CBC_WITH_MD5, "SSL_EN_DES_192_EDE3_CBC_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, + { 'd',SSL_EN_DES_64_CBC_WITH_MD5, "SSL_EN_DES_64_CBC_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, + { 'e',SSL_EN_RC4_128_EXPORT40_WITH_MD5, "SSL_EN_RC4_128_EXPORT40_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_ALLOWED }, + { 'f',SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5 (ssl2)",1, SSL_ALLOWED,SSL_ALLOWED }, +#ifdef FORTEZZA + { 'g',SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA",1,SSL_ALLOWED,SSL_NOT_ALLOWED }, + { 'h',SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, "SSL_FORTEZZA_DMS_WITH_RC4_128_SHA",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, +#endif + { 'i',SSL_RSA_WITH_RC4_128_MD5, "SSL_RSA_WITH_RC4_128_MD5 (ssl3)",1, SSL_ALLOWED,SSL_RESTRICTED }, + { 'j',SSL_RSA_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_WITH_3DES_EDE_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_RESTRICTED }, + { 'k',SSL_RSA_WITH_DES_CBC_SHA, "SSL_RSA_WITH_DES_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, + { 'l',SSL_RSA_EXPORT_WITH_RC4_40_MD5, "SSL_RSA_EXPORT_WITH_RC4_40_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED }, + { 'm',SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED }, +#ifdef FORTEZZA + { 'n',SSL_FORTEZZA_DMS_WITH_NULL_SHA, "SSL_FORTEZZA_DMS_WITH_NULL_SHA",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, +#endif + { 'o',SSL_RSA_WITH_NULL_MD5, "SSL_RSA_WITH_NULL_MD5 (ssl3)",1, SSL_ALLOWED,SSL_ALLOWED }, + { 'p',SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED }, + { 'q',SSL_RSA_FIPS_WITH_DES_CBC_SHA, "SSL_RSA_FIPS_WITH_DES_CBC_SHA (ssl3)",1, SSL_ALLOWED,SSL_NOT_ALLOWED } + +}; + +void PrintErrString(char *progName,char *msg) { + + PRErrorCode e = PORT_GetError(); + char *s=NULL; + + + if ((e >= PR_NSPR_ERROR_BASE) && (e < PR_MAX_ERROR)) { + + if (e == PR_DIRECTORY_LOOKUP_ERROR) + s = PL_strdup("Hostname Lookup Failed"); + else if (e == PR_NETWORK_UNREACHABLE_ERROR) + s = PL_strdup("Network Unreachable"); + else if (e == PR_CONNECT_TIMEOUT_ERROR) + s = PL_strdup("Connection Timed Out"); + else s = PR_smprintf("%d",e); + + if (!s) return; + } + else { + s = PL_strdup(SECU_ErrorString(e)); + } + + PR_fprintf(PR_STDOUT,"%s: ",progName); + if (s) { + if (*s) + PR_fprintf(PR_STDOUT, "%s\n", s); + else + PR_fprintf(PR_STDOUT, "\n"); + + PR_Free(s); + } + +} + +void PrintCiphers(int onlyenabled) { + int ciphercount,i; + + if (onlyenabled) { + PR_fprintf(PR_STDOUT,"Your Cipher preference:\n"); + } + + ciphercount = sizeof(ciphers)/sizeof(struct CipherPolicy); + PR_fprintf(PR_STDOUT, + " %s %-45s %-12s %-12s\n","id","CipherName","Domestic","Export"); + + for (i=0;i<ciphercount;i++) { + if ( (onlyenabled ==0) || ((onlyenabled==1)&&(ciphers[i].pref))) { + PR_fprintf(PR_STDOUT, + " %c %-45s %-12s %-12s\n",ciphers[i].number,ciphers[i].name, + (ciphers[i].domestic==SSL_ALLOWED)?"Yes": + ( (ciphers[i].domestic==SSL_NOT_ALLOWED)?"No":"Step-up only"), + (ciphers[i].export==SSL_ALLOWED)?"Yes": + ( (ciphers[i].export==SSL_NOT_ALLOWED)?"No":"Step-up only")); + } + } +} + + +void SetPolicy(char *c,int policy) { /* policy==1 : domestic, policy==0, export */ + int i,j,cpolicy; + /* first, enable all relevant ciphers according to policy */ + for (j=0;j<(sizeof(ciphers)/sizeof(struct CipherPolicy));j++) { + SSL_CipherPolicySet(ciphers[j].id,policy?ciphers[j].domestic:ciphers[j].export); + SSL_CipherPrefSetDefault(ciphers[j].id, PR_FALSE); + ciphers[j].pref =0; + } + + + for (i=0;i<(int)PL_strlen(c);i++) { + for (j=0;j<(sizeof(ciphers)/sizeof(struct CipherPolicy));j++) { + if (ciphers[j].number == c[i]) { + cpolicy = policy?ciphers[j].domestic:ciphers[j].export; + if (cpolicy == SSL_NOT_ALLOWED) { + PR_fprintf(PR_STDOUT, "You're trying to enable a cipher (%c:%s) outside of your policy. ignored\n", + c[i],ciphers[j].name); + } + else { + ciphers[j].pref=1; + SSL_CipherPrefSetDefault(ciphers[j].id, PR_TRUE); + } + } + } + } +} + + +int MyAuthCertificateHook(void *arg, PRFileDesc *fd, PRBool checksig, PRBool isserver) { + return SECSuccess; +} + + +void Usage() { +#ifdef SSLTELNET + PR_fprintf(PR_STDOUT,"SSLTelnet "); +#else + PR_fprintf(PR_STDOUT,"SSLStrength (No telnet functionality) "); +#endif + PR_fprintf(PR_STDOUT,"Version 1.5\n"); + + PR_fprintf(PR_STDOUT,"Usage:\n sslstrength hostname[:port] [ciphers=xyz] [certdir=x] [debug] [verbose] " +#ifdef SSLTELNET +"[telnet]|[servertype]|[querystring=<string>] " +#endif +"[policy=export|domestic]\n sslstrength ciphers\n"); +} + + +PRInt32 debug = 0; +PRInt32 verbose = 0; + +PRInt32 main(PRInt32 argc,char **argv, char **envp) +{ + + + /* defaults for command line arguments */ + char *hostnamearg=NULL; + char *portnumarg=NULL; + char *sslversionarg=NULL; + char *keylenarg=NULL; + char *certdir=NULL; + char *hostname; + char *nickname=NULL; + char *progname=NULL; + /* struct sockaddr_in addr; */ + PRNetAddr addr; + + int ss_on; + char *ss_cipher; + int ss_keysize; + int ss_secretsize; + char *ss_issuer; + char *ss_subject; + int policy=1; + char *set_ssl_policy=NULL; + int print_ciphers=0; + + char buf[10]; + char netdbbuf[PR_NETDB_BUF_SIZE]; + PRHostEnt hp; + PRStatus r; + PRNetAddr na; + SECStatus rv; + int portnum=443; /* default https: port */ + PRFileDesc *s,*fd; + + CERTCertDBHandle *handle; + CERTCertificate *c; + PRInt32 i; +#ifdef SSLTELNET + struct termios tmp_tc; + char cb; + int prev_lflag,prev_oflag,prev_iflag; + int t_fin,t_fout; + int servertype=0, telnet=0; + char *querystring=NULL; +#endif + + debug = 0; + + progname = (char *)PL_strrchr(argv[0], '/'); + progname = progname ? progname+1 : argv[0]; + + /* Read in command line args */ + if (argc == 1) { + Usage(); + return(0); + } + + if (! PL_strcmp("ciphers",argv[1])) { + PrintCiphers(0); + exit(0); + } + + hostname = argv[1]; + + if (!PL_strcmp(hostname , "usage") || !PL_strcmp(hostname, "-help") ) { + Usage(); + exit(0); + } + + if ((portnumarg = PL_strchr(hostname,':'))) { + *portnumarg = 0; + portnumarg = &portnumarg[1]; + } + + if (portnumarg) { + if (*portnumarg == 0) { + PR_fprintf(PR_STDOUT,"malformed port number supplied\n"); + return(1); + } + portnum = atoi(portnumarg); + } + + for (i = 2 ; i < argc; i++) + { + if (!PL_strncmp(argv[i] , "sslversion=",11) ) + sslversionarg=&(argv[i][11]); + else if (!PL_strncmp(argv[i], "certdir=",8) ) + certdir = &(argv[i][8]); + else if (!PL_strncmp(argv[i], "ciphers=",8) ) + { + set_ssl_policy=&(argv[i][8]); + } + else if (!PL_strncmp(argv[i], "policy=",7) ) { + if (!PL_strcmp(&(argv[i][7]),"domestic")) policy=1; + else if (!PL_strcmp(&(argv[i][7]),"export")) policy=0; + else { + PR_fprintf(PR_STDOUT,"sslstrength: invalid argument. policy must be one of (domestic,export)\n"); + } + } + else if (!PL_strcmp(argv[i] , "debug") ) + debug = 1; +#ifdef SSLTELNET + else if (!PL_strcmp(argv[i] , "telnet") ) + telnet = 1; + else if (!PL_strcmp(argv[i] , "servertype") ) + servertype = 1; + else if (!PL_strncmp(argv[i] , "querystring=",11) ) + querystring = &argv[i][12]; +#endif + else if (!PL_strcmp(argv[i] , "verbose") ) + verbose = 1; + } + +#ifdef SSLTELNET + if (telnet && (servertype || querystring)) { + PR_fprintf(PR_STDOUT,"You can't use telnet and (server or querystring) options at the same time\n"); + exit(1); + } +#endif + + PR_fprintf(PR_STDOUT,"Using %s policy\n",policy?"domestic":"export"); + + /* allow you to set env var SSLDIR to set the cert directory */ + if (! certdir) certdir = SECU_DefaultSSLDir(); + + /* if we don't have one still, initialize with no databases */ + if (!certdir) { + rv = NSS_NoDB_Init(NULL); + + (void) SECMOD_AddNewModule("Builtins", DLL_PREFIX"nssckbi."DLL_SUFFIX,0,0); + } else { + rv = NSS_Init(certdir); + SECU_ConfigDirectory(certdir); + } + + /* Lookup host */ + r = PR_GetHostByName(hostname,netdbbuf,PR_NETDB_BUF_SIZE,&hp); + + if (r) { + PrintErrString(progname,"Host Name lookup failed"); + return(1); + } + + /* should the third field really be 0? */ + + PR_EnumerateHostEnt(0,&hp,0,&na); + PR_InitializeNetAddr(PR_IpAddrNull,portnum,&na); + + PR_fprintf(PR_STDOUT,"Connecting to %s:%d\n",hostname, portnum); + + /* Create socket */ + + fd = PR_NewTCPSocket(); + if (fd == NULL) { + PrintErrString(progname, "error creating socket"); + return -1; + } + + s = SSL_ImportFD(NULL,fd); + if (s == NULL) { + PrintErrString(progname, "error creating socket"); + return -1; + } + + dbmsg("10: About to enable security\n"); + + rv = SSL_OptionSet(s, SSL_SECURITY, PR_TRUE); + if (rv < 0) { + PrintErrString(progname, "error enabling socket"); + return -1; + } + + if (set_ssl_policy) { + SetPolicy(set_ssl_policy,policy); + } + else { + PR_fprintf(PR_STDOUT,"Using all ciphersuites usually found in client\n"); + if (policy) { + SetPolicy("abcdefghijklmnopqrst",policy); + } + else { + SetPolicy("efghijlmo",policy); + } + } + + PrintCiphers(1); + + rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); + if (rv < 0) { + PrintErrString(progname, "error enabling client handshake"); + return -1; + } + + dbmsg("30: About to set AuthCertificateHook\n"); + + + SSL_AuthCertificateHook(s, MyAuthCertificateHook, (void *)handle); + /* SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle); */ + /* SSL_GetClientAuthDataHook(s, GetClientAuthDataHook, (void *)nickname);*/ + + + dbmsg("40: About to SSLConnect\n"); + + /* Try to connect to the server */ + /* now SSL_Connect takes new arguments. */ + + + r = PR_Connect(s, &na, PR_TicksPerSecond()*5); + if (r < 0) { + PrintErrString(progname, "unable to connect"); + return -1; + } + + rv = SSL_ForceHandshake(s); + + if (rv) { + PrintErrString(progname,"SSL Handshake failed. "); + exit(1); + } + + rv = SSL_SecurityStatus(s, &ss_on, &ss_cipher, + &ss_keysize, &ss_secretsize, + &ss_issuer, &ss_subject); + + + dbmsg("60: done with security status, about to print\n"); + + c = SSL_PeerCertificate(s); + if (!c) PR_fprintf(PR_STDOUT,"Couldn't retrieve peers Certificate\n"); + PR_fprintf(PR_STDOUT,"SSL Connection Status\n",rv); + + PR_fprintf(PR_STDOUT," Cipher: %s\n",ss_cipher); + PR_fprintf(PR_STDOUT," Key Size: %d\n",ss_keysize); + PR_fprintf(PR_STDOUT," Secret Key Size: %d\n",ss_secretsize); + PR_fprintf(PR_STDOUT," Issuer: %s\n",ss_issuer); + PR_fprintf(PR_STDOUT," Subject: %s\n",ss_subject); + + PR_fprintf(PR_STDOUT," Valid: from %s to %s\n", + c==NULL?"???":DER_TimeChoiceDayToAscii(&c->validity.notBefore), + c==NULL?"???":DER_TimeChoiceDayToAscii(&c->validity.notAfter)); + +#ifdef SSLTELNET + + + + + if (servertype || querystring) { + char buffer[1024]; + char ch; + char qs[] = "HEAD / HTTP/1.0"; + + + + + if (!querystring) querystring = qs; + PR_fprintf(PR_STDOUT,"\nServer query mode\n>>Sending:\n%s\n",querystring); + + PR_fprintf(PR_STDOUT,"\n*** Server said:\n"); + ch = querystring[PL_strlen(querystring)-1]; + if (ch == '"' || ch == '\'') { + PR_fprintf(PR_STDOUT,"Warning: I'm not smart enough to cope with quotes mid-string like that\n"); + } + + rv = PR_Write(s,querystring,PL_strlen(querystring)); + if ((rv < 1) ) { + PR_fprintf(PR_STDOUT,"Oh dear - couldn't send servertype query\n"); + goto closedown; + } + + rv = PR_Write(s,"\r\n\r\n",4); + rv = PR_Read(s,buffer,1024); + if ((rv < 1) ) { + PR_fprintf(PR_STDOUT,"Oh dear - couldn't read server repsonse\n"); + goto closedown; + } + PR_Write(PR_STDOUT,buffer,rv); + } + + + if (telnet) { + + PR_fprintf(PR_STDOUT,"---------------------------\n" + "telnet mode. CTRL-C to exit\n" + "---------------------------\n"); + + + + /* fudge terminal attributes */ + t_fin = PR_FileDesc2NativeHandle(PR_STDIN); + t_fout = PR_FileDesc2NativeHandle(PR_STDOUT); + + tcgetattr(t_fin,&tmp_tc); + prev_lflag = tmp_tc.c_lflag; + prev_oflag = tmp_tc.c_oflag; + prev_iflag = tmp_tc.c_iflag; + tmp_tc.c_lflag &= ~ECHO; + /* tmp_tc.c_oflag &= ~ONLCR; */ + tmp_tc.c_lflag &= ~ICANON; + tmp_tc.c_iflag &= ~ICRNL; + tmp_tc.c_cflag |= CS8; + tmp_tc.c_cc[VMIN] = 1; + tmp_tc.c_cc[VTIME] = 0; + + tcsetattr(t_fin, TCSANOW, &tmp_tc); + /* ioctl(tin, FIONBIO, (char *)&onoff); + ioctl(tout, FIONBIO, (char *)&onoff);*/ + + + { + PRPollDesc pds[2]; + char buffer[1024]; + int amt,amtwritten; + char *x; + + /* STDIN */ + pds[0].fd = PR_STDIN; + pds[0].in_flags = PR_POLL_READ; + pds[1].fd = s; + pds[1].in_flags = PR_POLL_READ | PR_POLL_EXCEPT; + + while (1) { + int nfds; + + nfds = PR_Poll(pds,2,PR_SecondsToInterval(2)); + if (nfds == 0) continue; + + /** read input from keyboard*/ + /* note: this is very inefficient if reading from a file */ + + if (pds[0].out_flags & PR_POLL_READ) { + amt = PR_Read(PR_STDIN,&buffer,1); + /* PR_fprintf(PR_STDOUT,"fd[0]:%d=%d\r\n",amt,buffer[0]); */ + if (amt == 0) { + PR_fprintf(PR_STDOUT,"\n"); + goto loser; + } + + if (buffer[0] == '\r') { + buffer[0] = '\r'; + buffer[1] = '\n'; + amt = 2; + } + rv = PR_Write(PR_STDOUT,buffer,amt); + + + rv = PR_Write(s,buffer,amt); + if (rv == -1) { + PR_fprintf(PR_STDOUT,"Error writing to socket: %d\n",PR_GetError()); + } + } + + /***/ + + + /***/ + if (pds[1].out_flags & PR_POLL_EXCEPT) { + PR_fprintf(PR_STDOUT,"\r\nServer closed connection\r\n"); + goto loser; + } + if (pds[1].out_flags & PR_POLL_READ) { + amt = PR_Read(s,&buffer,1024); + + if (amt == 0) { + PR_fprintf(PR_STDOUT,"\r\nServer closed connection\r\n"); + goto loser; + } + rv = PR_Write(PR_STDOUT,buffer,amt); + } + /***/ + + } + } + loser: + + /* set terminal back to normal */ + tcgetattr(t_fin,&tmp_tc); + + tmp_tc.c_lflag = prev_lflag; + tmp_tc.c_oflag = prev_oflag; + tmp_tc.c_iflag = prev_iflag; + tcsetattr(t_fin, TCSANOW, &tmp_tc); + + /* ioctl(tin, FIONBIO, (char *)&onoff); + ioctl(tout, FIONBIO, (char *)&onoff); */ + } + +#endif + /* SSLTELNET */ + + closedown: + + PR_Close(s); + + if (NSS_Shutdown() != SECSuccess) { + exit(1); + } + + return(0); + +} /* main */ + +/*EOF*/ + diff --git a/security/nss/cmd/sslstrength/sslwrap b/security/nss/cmd/sslstrength/sslwrap new file mode 100755 index 000000000..892fd349e --- /dev/null +++ b/security/nss/cmd/sslstrength/sslwrap @@ -0,0 +1,185 @@ +#!/usr/bin/perl +# +# ***** 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 ***** + + +@profiles = ( +# "host:port" "policy" "ciphers" "exp-cipher" "expkeysize" + + [ "cfu:443", "export", "efijlmo", "RC4-40", "40" ], + [ "hbombsgi:448", "export", "efijlmo", "RC4-40", "40" ], + [ "hbombsgi:448", "domestic", "abcdefijklmo", "RC4", "128" ], + [ "gandalf:5666", "domestic", "abcdefijklmo", "RC4", "128" ], + [ "gandalf:5666", "export", "efijlmo", "RC4", "128" ], + [ "gandalf:5666", "domestic", "j", "3DES-EDE-CBC", "168" ], + [ "gandalf:5666", "domestic", "k", "DES-CBC", "56" ], + [ "gandalf:5666", "export", "l", "RC4-40", "40" ], + [ "gandalf:5666", "export", "efijlmo", "RC4", "128" ], + [ "hbombcfu:443", "export", "efijlmo", "RC4", "128" ], + + ); + +$file = &filename; + +open(HTML, ">$file.htm") || die"Cannot open html output file\n"; + +$mutversion = ""; +$platform = $ARGV[0]; + + +print HTML +"<HTML><HEAD> +<TITLE>ssl/sslstrength: Version: $mutversion Platform: $platform Run date mm/dd/yy</TITLE></HEAD><BODY>\n"; + +print HTML +"<TABLE BORDER=1><TR> +<TD><B>Test Case Number</B></TD> +<TD><B>Program</B></TD> +<TD><B>Description of Test Case</B></TD> +<TD><B>Start date/time<B></TD> +<TD><B>End date/time<B></TD> +<TD><B>PASS/FAIL</B></TD> +</TR>\n"; + +$countpass =0; +$countfail =0; + + +$testnum =0; +for $profile (@profiles) { + $testnum ++; + ($host, $policy, $ciphers, $expcipher, $expkeysize) = @$profile; + + $cmd = "./sslstrength $host policy=$policy ciphers=$ciphers"; + + $starttime = &datestring." ".×tring; + print STDERR "$cmd\n"; + open(PIPE, "$cmd|") || die "Cannot start sslstrength\n"; + + $cipher = ""; + $keysize = ""; + while (<PIPE>) { + chop; + if (/^ Cipher: *(.*)/) { + $cipher = $1; + } + if (/^ Secret Key Size: (.*)/) { + $keysize = $1; + } + } + close(PIPE); + $endtime = &datestring." ".×tring; + + if (( $? != 0) || ($cipher ne $expcipher) || ($keysize ne $expkeysize)) { + $countfail ++; + $passed =0; + } + else { + $countpass ++; + $passed =1; + } + +print HTML +"<TR> +<TD><B>$testnum</B></TD> +<TD></TD> +<TD>$cmd</TD> +<TD>$starttime</TD> +<TD>$endtime</TD> +<TD><B>".($passed ? "PASS" : "<FONT COLOR=red>FAIL: return code = +c=$cipher, ec=$expcipher, s=$keysize, es=$expkeysize.</FONT>")." +</B></TD> +</TR>\n"; + +} + +print HTML "</table>\n"; + +close(HTML); + +open (SUM, ">$file.sum") ||die "couldn't open summary file for writing\n"; + +print SUM <<EOM; +[Status] +mut=SSL +mutversion=1.0 +platform=$platform +pass=$countpass +fail=$countfail +knownFail=0 +malformed=0 +EOM + + close(SUM); + + + +sub timestring +{ + + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); + my $string; + + $string = sprintf "%2d:%02d:%02d",$hour, $min, $sec; + return $string; +} + +sub datestring +{ + + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); + my $string; + + $string = sprintf "%d/%d/%2d",$mon+1, $mday+1, $year; + return $string; +} + +sub filename +{ + + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); + my $string; + + $string = sprintf "%04d%02d%02d",$year+1900, $mon+1, $mday; + return $string; +} + + + + + + diff --git a/security/nss/cmd/swfort/Makefile b/security/nss/cmd/swfort/Makefile new file mode 100644 index 000000000..ec86309c0 --- /dev/null +++ b/security/nss/cmd/swfort/Makefile @@ -0,0 +1,113 @@ +#! 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 ***** + +CORE_DEPTH = ../../.. + +include manifest.mn +include $(CORE_DEPTH)/coreconf/config.mk + +# $(NULL) + + +INCLUDES += \ + -I$(DIST)/../public/security \ + -I$(DIST)/../private/security \ + -I$(DEPTH)/security/lib/cert \ + -I$(DEPTH)/security/lib/key \ + -I$(DEPTH)/security/lib/util \ + -I./include \ + $(NULL) + + +# For the time being, sec stuff is export only +# US_FLAGS = -DEXPORT_VERSION -DUS_VERSION + +US_FLAGS = -DEXPORT_VERSION +EXPORT_FLAGS = -DEXPORT_VERSION + +BASE_LIBS = \ + $(DIST)/lib/libdbm.$(LIB_SUFFIX) \ + $(DIST)/lib/libxp.$(LIB_SUFFIX) \ + $(DIST)/lib/libnspr.$(LIB_SUFFIX) \ + $(NULL) + +# $(DIST)/lib/libpurenspr.$(LIB_SUFFIX) \ + +#There are a circular dependancies in security/lib, and we deal with it by +# double linking some libraries +SEC_LIBS = \ + $(DIST)/lib/libsecnav.$(LIB_SUFFIX) \ + $(DIST)/lib/libssl.$(LIB_SUFFIX) \ + $(DIST)/lib/libpkcs7.$(LIB_SUFFIX) \ + $(DIST)/lib/libcert.$(LIB_SUFFIX) \ + $(DIST)/lib/libkey.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecmod.$(LIB_SUFFIX) \ + $(DIST)/lib/libcrypto.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \ + $(DIST)/lib/libssl.$(LIB_SUFFIX) \ + $(DIST)/lib/libpkcs7.$(LIB_SUFFIX) \ + $(DIST)/lib/libcert.$(LIB_SUFFIX) \ + $(DIST)/lib/libkey.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecmod.$(LIB_SUFFIX) \ + $(DIST)/lib/libcrypto.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \ + $(DIST)/lib/libhash.$(LIB_SUFFIX) \ + $(NULL) + +MYLIB = lib/$(OBJDIR)/libsectool.$(LIB_SUFFIX) + +US_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS) +EX_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS) + +REQUIRES = libxp nspr security + +CSRCS = $(EXEC_SRCS) $(BI_SRCS) + +OBJS = $(CSRCS:.c=.o) $(BI_SRCS:.c=-us.o) $(BI_SRCS:.c=-ex.o) + +PROGS = $(addprefix $(OBJDIR)/, $(EXEC_SRCS:.c=$(BIN_SUFFIX))) +US_PROGS = $(addprefix $(OBJDIR)/, $(BI_SRCS:.c=-us$(BIN_SUFFIX))) +EX_PROGS = $(addprefix $(OBJDIR)/, $(BI_SRCS:.c=-ex$(BIN_SUFFIX))) + + +NON_DIRS = $(PROGS) $(US_PROGS) $(EX_PROGS) +TARGETS = $(NON_DIRS) + +include $(CORE_DEPTH)/coreconf/rules.mk + +symbols:: + @echo "TARGETS = $(TARGETS)" diff --git a/security/nss/cmd/swfort/instinit/Makefile b/security/nss/cmd/swfort/instinit/Makefile new file mode 100644 index 000000000..a2e75fc7b --- /dev/null +++ b/security/nss/cmd/swfort/instinit/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/swfort/instinit/instinit.c b/security/nss/cmd/swfort/instinit/instinit.c new file mode 100644 index 000000000..2e65b1aac --- /dev/null +++ b/security/nss/cmd/swfort/instinit/instinit.c @@ -0,0 +1,424 @@ +/* ***** 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 ***** */ +#include <stdio.h> + +#include "prio.h" +#include "seccomon.h" +#include "swforti.h" +#include "cert.h" +#include "pk11func.h" +#include "nss.h" +#include "secutil.h" + +#define CERTDB_VALID_CA (1<<3) +#define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */ + +void secmod_GetInternalModule(SECMODModule *module); +void sec_SetCheckKRLState(int i); + +#define STEP 16 +void +printItem(SECItem *key) { + int i; + unsigned char *block; + int len; + for (block=key->data,len=key->len; len > 0; len -= STEP,block += STEP) { + for(i=0; i < STEP && i < len; i++) printf(" %02x ",block[i]); + printf("\n"); + } + printf("\n"); +} + +void +dump(unsigned char *block, int len) { + int i; + for (; len > 0; len -= STEP,block += STEP) { + for(i=0; i < STEP && i < len; i++) printf(" %02x ",block[i]); + printf("\n"); + } + printf("\n"); +} + + +/* + * We need to move this to security/cmd .. so we can use the password + * prompting infrastructure. + */ +char *GetUserInput(char * prompt) +{ + char phrase[200]; + + fprintf(stderr, "%s", prompt); + fflush (stderr); + + fgets ((char*) phrase, sizeof(phrase), stdin); + + /* stomp on newline */ + phrase[PORT_Strlen((char*)phrase)-1] = 0; + + /* Validate password */ + return (char*) PORT_Strdup((char*)phrase); +} + +void ClearPass(char *pass) { + PORT_Memset(pass,0,strlen(pass)); + PORT_Free(pass); +} + +char * +formatDERIssuer(FORTSWFile *file,SECItem *derIssuer) +{ + CERTName name; + SECStatus rv; + + PORT_Memset(&name,0,sizeof(name));; + rv = SEC_ASN1DecodeItem(file->arena,&name,CERT_NameTemplate,derIssuer); + if (rv != SECSuccess) { + return NULL; + } + return CERT_NameToAscii(&name); +} + +#define NETSCAPE_INIT_FILE "nsswft.swf" + +char *getDefaultTarget(void) +{ + char *fname = NULL; + char *home = NULL; + static char unix_home[512]; + + /* first try to get it from the environment */ + fname = getenv("SW_FORTEZZA_FILE"); + if (fname != NULL) { + return PORT_Strdup(fname); + } + +#ifdef XP_UNIX + home = getenv("HOME"); + if (home) { + strncpy(unix_home,home, sizeof(unix_home)-sizeof("/.netscape/"NETSCAPE_INIT_FILE)); + strcat(unix_home,"/.netscape/"NETSCAPE_INIT_FILE); + return unix_home; + } +#endif +#ifdef XP_WIN + home = getenv("windir"); + if (home) { + strncpy(unix_home,home, sizeof(unix_home)-sizeof("\\"NETSCAPE_INIT_FILE)); + strcat(unix_home,"\\"NETSCAPE_INIT_FILE); + return unix_home; + } +#endif + return (NETSCAPE_INIT_FILE); +} + +void +usage(char *prog) { + fprintf(stderr,"usage: %s [-v][-f][-t transport_pass][-u user_pass][-o output_file] source_file\n",prog); + exit(1); +} + +int main(int argc, char ** argv) +{ + + FORTSignedSWFile * swfile; + int size; + SECItem file; + char *progname = *argv++; + char *filename = NULL; + char *outname = NULL; + char *cp; + int verbose = 0; + int force = 0; + CERTCertDBHandle *certhandle = NULL; + CERTCertificate *cert; + CERTCertTrust *trust; + char * pass; + SECStatus rv; + int i; + int64 now; /* XXXX */ + char *issuer; + char *transport_pass = NULL; + char *user_pass = NULL; + SECItem *outItem = NULL; + PRFileDesc *fd; + PRFileInfo info; + PRStatus prv; + + + + + /* put better argument parsing here */ + while ((cp = *argv++) != NULL) { + if (*cp == '-') { + while (*++cp) { + switch (*cp) { + /* verbose mode */ + case 'v': + verbose++; + break; + /* explicitly set the target */ + case 'o': + outname = *argv++; + break; + case 'f': + /* skip errors in signatures without prompts */ + force++; + break; + case 't': + /* provide password on command line */ + transport_pass = *argv++; + break; + case 'u': + /* provide user password on command line */ + user_pass = *argv++; + break; + default: + usage(progname); + break; + } + } + } else if (filename) { + usage(progname); + } else { + filename = cp; + } + } + + if (filename == NULL) usage(progname); + if (outname == NULL) outname = getDefaultTarget(); + + + now = PR_Now(); + /* read the file in */ + fd = PR_Open(filename,PR_RDONLY,0); + if (fd == NULL) { + fprintf(stderr,"%s: couldn't open file \"%s\".\n",progname,filename); + exit(1); + } + + prv = PR_GetOpenFileInfo(fd,&info); + if (prv != PR_SUCCESS) { + fprintf(stderr,"%s: couldn't get info on file \"%s\".\n", + progname,filename); + exit(1); + } + + size = info.size; + + file.data = malloc(size); + file.len = size; + + file.len = PR_Read(fd,file.data,file.len); + if (file.len < 0) { + fprintf(stderr,"%s: couldn't read file \"%s\".\n",progname, filename); + exit(1); + } + + PR_Close(fd); + + /* Parse the file */ + swfile = FORT_GetSWFile(&file); + if (swfile == NULL) { + fprintf(stderr, + "%s: File \"%s\" not a valid FORTEZZA initialization file.\n", + progname,filename); + exit(1); + } + + issuer = formatDERIssuer(&swfile->file,&swfile->file.derIssuer); + if (issuer == NULL) { + issuer = "<Invalid Issuer DER>"; + } + + if (verbose) { + printf("Processing file %s ....\n",filename); + printf(" Version %ld\n",DER_GetInteger(&swfile->file.version)); + printf(" Issuer: %s\n",issuer); + printf(" Serial Number: "); + for (i=0; i < (int)swfile->file.serialID.len; i++) { + printf(" %02x",swfile->file.serialID.data[i]); + } + printf("\n"); + } + + + /* Check the Initalization phrase and save Kinit */ + if (!transport_pass) { + pass = SECU_GetPasswordString(NULL,"Enter the Initialization Memphrase:"); + transport_pass = pass; + } + rv = FORT_CheckInitPhrase(swfile,transport_pass); + if (rv != SECSuccess) { + fprintf(stderr, + "%s: Invalid Initialization Memphrase for file \"%s\".\n", + progname,filename); + exit(1); + } + + /* Check the user or init phrase and save Ks, use Kinit to unwrap the + * remaining data. */ + if (!user_pass) { + pass = SECU_GetPasswordString(NULL,"Enter the User Memphrase or the User PIN:"); + user_pass = pass; + } + rv = FORT_CheckUserPhrase(swfile,user_pass); + if (rv != SECSuccess) { + fprintf(stderr,"%s: Invalid User Memphrase or PIN for file \"%s\".\n", + progname,filename); + exit(1); + } + + NSS_NoDB_Init(NULL); + sec_SetCheckKRLState(1); + certhandle = CERT_GetDefaultCertDB(); + + /* now dump the certs into the temparary data base */ + for (i=0; swfile->file.slotEntries[i]; i++) { + int trusted = 0; + SECItem *derCert = FORT_GetDERCert(swfile, + swfile->file.slotEntries[i]->certIndex); + + if (derCert == NULL) { + if (verbose) { + printf(" Cert %02d: %s \"%s\" \n", + swfile->file.slotEntries[i]->certIndex, + "untrusted", "Couldn't decrypt Cert"); + } + continue; + } + cert = CERT_NewTempCertificate(certhandle, derCert, NULL, + PR_FALSE, PR_TRUE); + if (cert == NULL) { + if (verbose) { + printf(" Cert %02d: %s \"%s\" \n", + swfile->file.slotEntries[i]->certIndex, + "untrusted", "Couldn't decode Cert"); + } + continue; + } + if (swfile->file.slotEntries[i]->trusted.data[0]) { + /* Add TRUST */ + trust = PORT_ArenaAlloc(cert->arena,sizeof(CERTCertTrust)); + if (trust != NULL) { + trust->sslFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA; + trust->emailFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA; + trust->objectSigningFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA; + cert->trust = trust; + trusted++; + } + } + if (verbose) { + printf(" Cert %02d: %s \"%s\" \n", + swfile->file.slotEntries[i]->certIndex, + trusted?" trusted ":"untrusted", + CERT_NameToAscii(&cert->subject)); + } + } + + fflush(stdout); + + + cert = CERT_FindCertByName(certhandle,&swfile->file.derIssuer); + if (cert == NULL) { + fprintf(stderr,"%s: Couldn't find signer certificate \"%s\".\n", + progname,issuer); + rv = SECFailure; + goto noverify; + } + rv = CERT_VerifySignedData(&swfile->signatureWrap,cert, now, NULL); + if (rv != SECSuccess) { + fprintf(stderr, + "%s: Couldn't verify the signature on file \"%s\" with certificate \"%s\".\n", + progname,filename,issuer); + goto noverify; + } + rv = CERT_VerifyCert(certhandle, cert, PR_TRUE, certUsageSSLServer, + now ,NULL,NULL); + /* not an normal cert, see if it's a CA? */ + if (rv != SECSuccess) { + rv = CERT_VerifyCert(certhandle, cert, PR_TRUE, certUsageAnyCA, + now ,NULL,NULL); + } + if (rv != SECSuccess) { + fprintf(stderr,"%s: Couldn't verify the signer certificate \"%s\".\n", + progname,issuer); + goto noverify; + } + +noverify: + if (rv != SECSuccess) { + if (!force) { + pass = GetUserInput( + "Signature verify failed, continue without verification? "); + if (!(pass && ((*pass == 'Y') || (*pass == 'y')))) { + exit(1); + } + } + } + + + /* now write out the modified init file for future use */ + outItem = FORT_PutSWFile(swfile); + if (outItem == NULL) { + fprintf(stderr,"%s: Couldn't format target init file.\n", + progname); + goto noverify; + } + + if (verbose) { + printf("writing modified file out to \"%s\".\n",outname); + } + + /* now write it out */ + fd = PR_Open(outname,PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,0700); + if (fd == NULL) { + fprintf(stderr,"%s: couldn't open file \"%s\".\n",progname,outname); + exit(1); + } + + file.len = PR_Write(fd,outItem->data,outItem->len); + if (file.len < 0) { + fprintf(stderr,"%s: couldn't read file \"%s\".\n",progname, filename); + exit(1); + } + + PR_Close(fd); + + exit(0); + return (0); +} + diff --git a/security/nss/cmd/swfort/instinit/manifest.mn b/security/nss/cmd/swfort/instinit/manifest.mn new file mode 100644 index 000000000..8fbfd4d9e --- /dev/null +++ b/security/nss/cmd/swfort/instinit/manifest.mn @@ -0,0 +1,50 @@ +# +# ***** 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 ***** +CORE_DEPTH = ../../../.. + +DEFINES += -DNSPR20 + +MODULE = nss + +CSRCS = instinit.c + +REQUIRES = nspr dbm seccmd + +PROGRAM = instinit +# PROGRAM = ./$(OBJDIR)/selfserv.exe + +USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/swfort/manifest.mn b/security/nss/cmd/swfort/manifest.mn new file mode 100644 index 000000000..92bc6ea2f --- /dev/null +++ b/security/nss/cmd/swfort/manifest.mn @@ -0,0 +1,42 @@ +# +# ***** 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 ***** +CORE_DEPTH = ../../.. + +REQUIRES = nss seccmd dbm + + +DIRS = instinit newuser diff --git a/security/nss/cmd/swfort/newuser/Makefile b/security/nss/cmd/swfort/newuser/Makefile new file mode 100644 index 000000000..cb295c50f --- /dev/null +++ b/security/nss/cmd/swfort/newuser/Makefile @@ -0,0 +1,87 @@ +#! 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). # +####################################################################### + +ctmp := $(shell $(MAKE) -C ../../../lib/fortcrypt --no-print-directory cilib_name) +ifeq ($(ctmp), $(patsubst /%,/,$(ctmp))) + CILIB := ../../../lib/fortcrypt/$(ctmp) +else + CILIB := $(ctmp) +endif + +EXTRA_LIBS += $(CILIB) + +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/swfort/newuser/manifest.mn b/security/nss/cmd/swfort/newuser/manifest.mn new file mode 100644 index 000000000..6b8b4d5ba --- /dev/null +++ b/security/nss/cmd/swfort/newuser/manifest.mn @@ -0,0 +1,49 @@ +# +# ***** 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 ***** +CORE_DEPTH = ../../../.. + +DEFINES += -DNSPR20 + +MODULE = nss + +CSRCS = newuser.c mktst.c + +REQUIRES = nspr dbm seccmd + +PROGRAM = newuser + +USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/swfort/newuser/mktst.c b/security/nss/cmd/swfort/newuser/mktst.c new file mode 100644 index 000000000..cca8704d1 --- /dev/null +++ b/security/nss/cmd/swfort/newuser/mktst.c @@ -0,0 +1,257 @@ +/* ***** 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 ***** */ +#include <stdio.h> + +#include "prio.h" +#include "swforti.h" +#include "maci.h" +#include "secder.h" +#include "blapi.h" + +void +printkey(char *s, unsigned char *block) { + int i; + printf("%s \n 0x",s); + for(i=0; i < 10; i++) printf("%02x",block[i]); + printf("\n"); +} + +void +printblock(char *s, unsigned char *block) { + int i; + printf("%s \n 0x",s); + for(i=0; i < 8; i++) printf("%02x",block[i]); + printf("\n 0x"); + for(i=8; i < 16; i++) printf("%02x",block[i]); + printf("\n"); +} + + +static char *leafbits="THIS IS NOT LEAF"; + +static void +encryptCertEntry(fortProtectedData *pdata,FORTSkipjackKeyPtr Ks, + unsigned char *data,int len) +{ + unsigned char *dataout; + int enc_len; + /* XXX Make length */ + pdata->dataIV.data = PORT_ZAlloc(24); + pdata->dataIV.len = 24; + PORT_Memcpy(pdata->dataIV.data,leafbits,SKIPJACK_LEAF_SIZE); + fort_GenerateRandom(&pdata->dataIV.data[SKIPJACK_LEAF_SIZE], + SKIPJACK_BLOCK_SIZE); + enc_len = (len + (SKIPJACK_BLOCK_SIZE-1)) & ~(SKIPJACK_BLOCK_SIZE-1); + dataout = pdata->dataEncryptedWithKs.data = PORT_ZAlloc(enc_len); + pdata->dataEncryptedWithKs.len = enc_len; + fort_skipjackEncrypt(Ks,&pdata->dataIV.data[SKIPJACK_LEAF_SIZE], + enc_len, data,dataout); + if (len > 255) { + pdata->length.data = PORT_ZAlloc(2); + pdata->length.data[0] = (len >> 8) & 0xff; + pdata->length.data[1] = len & 0xff; + pdata->length.len = 2; + } else { + pdata->length.data = PORT_ZAlloc(1); + pdata->length.data[0] = len & 0xff; + pdata->length.len = 1; + } + +} + +unsigned char issuer[30] = { 0 }; + +void +makeCertSlot(fortSlotEntry *entry,int index,char *label,SECItem *cert, + FORTSkipjackKeyPtr Ks, unsigned char *xKEA, unsigned char *xDSA, + unsigned char *pubKey, int pubKeyLen, unsigned char *p, unsigned char *q, + unsigned char *g) +{ + unsigned char *key; /* private key */ + + entry->trusted.data = PORT_Alloc(1); + *entry->trusted.data = index == 0 ? 1 : 0; + entry->trusted.len = 1; + entry->certificateIndex.data = PORT_Alloc(1); + *entry->certificateIndex.data = index; + entry->certificateIndex.len = 1; + entry->certIndex = index; + encryptCertEntry(&entry->certificateLabel,Ks, + (unsigned char *)label, strlen(label)); + encryptCertEntry(&entry->certificateData,Ks, cert->data, cert->len); + if (xKEA) { + entry->exchangeKeyInformation = PORT_ZNew(fortKeyInformation); + entry->exchangeKeyInformation->keyFlags.data = PORT_ZAlloc(1); + entry->exchangeKeyInformation->keyFlags.data[0] = 1; + entry->exchangeKeyInformation->keyFlags.len = 1; + key = PORT_Alloc(24); + fort_skipjackWrap(Ks,24,xKEA,key); + entry->exchangeKeyInformation->privateKeyWrappedWithKs.data = key; + entry->exchangeKeyInformation->privateKeyWrappedWithKs.len = 24; + entry->exchangeKeyInformation->derPublicKey.data = pubKey; + entry->exchangeKeyInformation->derPublicKey.len = pubKeyLen; + entry->exchangeKeyInformation->p.data = p; + entry->exchangeKeyInformation->p.len = 128; + entry->exchangeKeyInformation->q.data = q; + entry->exchangeKeyInformation->q.len = 20; + entry->exchangeKeyInformation->g.data = g; + entry->exchangeKeyInformation->g.len = 128; + + entry->signatureKeyInformation = PORT_ZNew(fortKeyInformation); + entry->signatureKeyInformation->keyFlags.data = PORT_ZAlloc(1); + entry->signatureKeyInformation->keyFlags.data[0] = 1; + entry->signatureKeyInformation->keyFlags.len = 1; + key = PORT_Alloc(24); + fort_skipjackWrap(Ks,24,xDSA,key); + entry->signatureKeyInformation->privateKeyWrappedWithKs.data = key; + entry->signatureKeyInformation->privateKeyWrappedWithKs.len = 24; + entry->signatureKeyInformation->derPublicKey.data = pubKey; + entry->signatureKeyInformation->derPublicKey.len = pubKeyLen; + entry->signatureKeyInformation->p.data = p; + entry->signatureKeyInformation->p.len = 128; + entry->signatureKeyInformation->q.data = q; + entry->signatureKeyInformation->q.len = 20; + entry->signatureKeyInformation->g.data = g; + entry->signatureKeyInformation->g.len = 128; + } else { + entry->exchangeKeyInformation = NULL; + entry->signatureKeyInformation = NULL; + } + + return; +} + + +void +makeProtectedPhrase(FORTSWFile *file, fortProtectedPhrase *prot_phrase, + FORTSkipjackKeyPtr Ks, FORTSkipjackKeyPtr Kinit, char *phrase) +{ + SHA1Context *sha; + unsigned char hashout[SHA1_LENGTH]; + FORTSkipjackKey Kfek; + unsigned int len; + unsigned char cw[4]; + unsigned char enc_version[2]; + unsigned char *data = NULL; + int keySize; + int i,version; + char tmp_data[13]; + + if (strlen(phrase) < 12) { + PORT_Memset(tmp_data, ' ', sizeof(tmp_data)); + PORT_Memcpy(tmp_data,phrase,strlen(phrase)); + tmp_data[12] = 0; + phrase = tmp_data; + } + + /* now calculate the PBE key for fortezza */ + sha = SHA1_NewContext(); + SHA1_Begin(sha); + version = DER_GetUInteger(&file->version); + enc_version[0] = (version >> 8) & 0xff; + enc_version[1] = version & 0xff; + SHA1_Update(sha,enc_version,sizeof(enc_version)); + SHA1_Update(sha,file->derIssuer.data, file->derIssuer.len); + SHA1_Update(sha,file->serialID.data, file->serialID.len); + SHA1_Update(sha,(unsigned char *)phrase,strlen(phrase)); + SHA1_End(sha,hashout,&len,SHA1_LENGTH); + PORT_Memcpy(Kfek,hashout,sizeof(FORTSkipjackKey)); + + keySize = sizeof(CI_KEY); + if (Kinit) keySize = SKIPJACK_BLOCK_SIZE*2; + data = PORT_ZAlloc(keySize); + prot_phrase->wrappedKValue.data = data; + prot_phrase->wrappedKValue.len = keySize; + fort_skipjackWrap(Kfek,sizeof(CI_KEY),Ks,data); + + /* first, decrypt the hashed/Encrypted Memphrase */ + data = (unsigned char *) PORT_ZAlloc(SHA1_LENGTH+sizeof(cw)); + + /* now build the hash for comparisons */ + SHA1_Begin(sha); + SHA1_Update(sha,(unsigned char *)phrase,strlen(phrase)); + SHA1_End(sha,hashout,&len,SHA1_LENGTH); + SHA1_DestroyContext(sha,PR_TRUE); + + + /* now calcuate the checkword and compare it */ + cw[0] = cw[1] = cw[2] = cw[3] = 0; + for (i=0; i <5 ; i++) { + cw[0] = cw[0] ^ hashout[i*4]; + cw[1] = cw[1] ^ hashout[i*4+1]; + cw[2] = cw[2] ^ hashout[i*4+2]; + cw[3] = cw[3] ^ hashout[i*4+3]; + } + + PORT_Memcpy(data,hashout,len); + PORT_Memcpy(data+len,cw,sizeof(cw)); + + prot_phrase->memPhraseIV.data = PORT_ZAlloc(24); + prot_phrase->memPhraseIV.len = 24; + PORT_Memcpy(prot_phrase->memPhraseIV.data,leafbits,SKIPJACK_LEAF_SIZE); + fort_GenerateRandom(&prot_phrase->memPhraseIV.data[SKIPJACK_LEAF_SIZE], + SKIPJACK_BLOCK_SIZE); + prot_phrase->kValueIV.data = PORT_ZAlloc(24); + prot_phrase->kValueIV.len = 24; + PORT_Memcpy(prot_phrase->kValueIV.data,leafbits,SKIPJACK_LEAF_SIZE); + fort_GenerateRandom(&prot_phrase->kValueIV.data[SKIPJACK_LEAF_SIZE], + SKIPJACK_BLOCK_SIZE); + fort_skipjackEncrypt(Ks,&prot_phrase->memPhraseIV.data[SKIPJACK_LEAF_SIZE], + len+sizeof(cw), data,data); + + prot_phrase->hashedEncryptedMemPhrase.data = data; + prot_phrase->hashedEncryptedMemPhrase.len = len+sizeof(cw); + + if (Kinit) { + fort_skipjackEncrypt(Kinit, + &prot_phrase->kValueIV.data[SKIPJACK_LEAF_SIZE], + prot_phrase->wrappedKValue.len, + prot_phrase->wrappedKValue.data, + prot_phrase->wrappedKValue.data ); + } + + return; +} + + +void +fill_in(SECItem *item,unsigned char *data, int len) +{ + item->data = PORT_Alloc(len); + PORT_Memcpy(item->data,data,len); + item->len = len; +} + diff --git a/security/nss/cmd/swfort/newuser/newuser.c b/security/nss/cmd/swfort/newuser/newuser.c new file mode 100644 index 000000000..e0db69509 --- /dev/null +++ b/security/nss/cmd/swfort/newuser/newuser.c @@ -0,0 +1,1134 @@ +/* ***** 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 ***** */ +#include <stdio.h> +#include <fcntl.h> +#include <sys/types.h> +#ifdef XP_UNIX +#include <unistd.h> +#endif +#include "cryptint.h" +#include "blapi.h" /* program calls low level functions directly!*/ +#include "pk11func.h" +#include "secmod.h" +/*#include "secmodi.h"*/ +#include "cert.h" +#include "key.h" +#include "nss.h" +#include "swforti.h" +#include "secutil.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define MAX_PERSONALITIES 50 +typedef struct { + int index; + CI_CERT_STR label; + CERTCertificate *cert; +} certlist; + +typedef struct { + int card; + int index; + CI_CERT_STR label; + certlist valid[MAX_PERSONALITIES]; + int count; +} Cert; + + +#define EMAIL_OID_LEN 9 +#define EMAIL_OID 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 +unsigned char emailAVA[127] = { + 0x31, 6+EMAIL_OID_LEN, /* Set */ + 0x30, 4+EMAIL_OID_LEN, /* Sequence */ + 0x06, EMAIL_OID_LEN, EMAIL_OID, + 0x13, 0, /* printable String */ +}; +#define EMAIL_DATA_START 8+EMAIL_OID_LEN + +int emailOffset[] = { 1, 3, EMAIL_DATA_START-1 }; +int offsetCount = sizeof(emailOffset)/sizeof(emailOffset[0]); + +unsigned char hash[20] = { 'H', 'a', 's', 'h', ' ', 'F', 'a', 'i', 'l', 'e', + 'd', ' ', '*', '*', '*', '*', '*', '*', '*', '*' }; +unsigned char sig[40] = { 'H', 'a', 's', 'h', ' ', 'F', 'a', 'i', 'l', 'e', + 'd', ' ', '*', '*', '*', '*', '*', '*', '*', '*', + '>', '>', '>', ' ', 'N', 'o', 't', ' ', 'S', 'i', + 'g', 'n', 'd', ' ', '<', '<', '<', ' ', ' ', ' ' }; + + +/*void *malloc(int); */ + +unsigned char *data_start(unsigned char *buf, int length, int *data_length) +{ + unsigned char tag; + int used_length= 0; + + tag = buf[used_length++]; + + /* blow out when we come to the end */ + if (tag == 0) { + return NULL; + } + + *data_length = buf[used_length++]; + + if (*data_length&0x80) { + int len_count = *data_length & 0x7f; + + *data_length = 0; + + while (len_count-- > 0) { + *data_length = (*data_length << 8) | buf[used_length++]; + } + } + + if (*data_length > (length-used_length) ) { + *data_length = length-used_length; + return NULL; + } + + return (buf + used_length); +} + +unsigned char * +GetAbove(unsigned char *cert,int cert_length,int *above_len) +{ + unsigned char *buf = cert; + int buf_length = cert_length; + unsigned char *tmp; + int len; + + *above_len = 0; + + /* optional serial number */ + if ((buf[0] & 0xa0) == 0xa0) { + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + } + /* serial number */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the OID */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* issuer */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the date */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + + *above_len = buf - cert; + return cert; +} + +unsigned char * +GetSubject(unsigned char *cert,int cert_length,int *subj_len) { + unsigned char *buf = cert; + int buf_length = cert_length; + unsigned char *tmp; + int len; + + *subj_len = 0; + + /* optional serial number */ + if ((buf[0] & 0xa0) == 0xa0) { + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + } + /* serial number */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the OID */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* issuer */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the date */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + + return data_start(buf,buf_length,subj_len); +} + +unsigned char * +GetBelow(unsigned char *cert,int cert_length,int *below_len) { + unsigned char *subj; + int subj_len; + unsigned char *below; + + *below_len = 0; + + subj = GetSubject(cert,cert_length,&subj_len); + + below = subj + subj_len; + *below_len = cert_length - (below - cert); + return below; +} + +unsigned char * +GetSignature(unsigned char *sig,int sig_length,int *subj_len) { + unsigned char *buf = sig; + int buf_length = sig_length; + unsigned char *tmp; + int len; + + *subj_len = 0; + + /* signature oid */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* signature data */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + + *subj_len = len -1; + return tmp+1; +} + +int DER_Sequence(unsigned char *buf, int length) { + int next = 0; + + buf[next++] = 0x30; + if (length < 0x80) { + buf[next++] = length; + } else { + buf[next++] = 0x82; + buf[next++] = (length >> 8) & 0xff; + buf[next++] = length & 0xff; + } + return next; +} + +static +int Cert_length(unsigned char *buf, int length) { + unsigned char tag; + int used_length= 0; + int data_length; + + tag = buf[used_length++]; + + /* blow out when we come to the end */ + if (tag == 0) { + return 0; + } + + data_length = buf[used_length++]; + + if (data_length&0x80) { + int len_count = data_length & 0x7f; + + data_length = 0; + + while (len_count-- > 0) { + data_length = (data_length << 8) | buf[used_length++]; + } + } + + if (data_length > (length-used_length) ) { + return length; + } + + return (data_length + used_length); +} + +int +InitCard(int card, char *inpass) { + int cirv; + char buf[50]; + char *pass; + + cirv = CI_Open( 0 /* flags */, card); + if (cirv != CI_OK) return cirv; + + if (inpass == NULL) { + sprintf(buf,"Enter PIN for card in socket %d: ",card); + pass = SECU_GetPasswordString(NULL, buf); + + if (pass == NULL) { + CI_Close(CI_POWER_DOWN_FLAG,card); + return CI_FAIL; + } + } else pass=inpass; + + cirv = CI_CheckPIN(CI_USER_PIN,(unsigned char *)pass); + if (cirv != CI_OK) { + CI_Close(CI_POWER_DOWN_FLAG,card); + } + return cirv; +} + +int +isUser(CI_PERSON *person) { + return 1; +} + +int +isCA(CI_PERSON *person) { + return 0; +} + +int FoundCert(int card, char *name, Cert *cert) { + CI_PERSON personalities[MAX_PERSONALITIES]; + CI_PERSON *person; + int cirv; + int i; + int user_len = strlen(name); + + PORT_Memset(personalities, 0, sizeof(CI_PERSON)*MAX_PERSONALITIES); + + cirv = CI_GetPersonalityList(MAX_PERSONALITIES,personalities); + if (cirv != CI_OK) return 0; + + + cert->count = 1; + cert->valid[0].index = 0; + memcpy(cert->valid[0].label,"RRXX0000Root PAA Certificate ", + sizeof(cert->valid[0].label)); + cert->valid[0].cert = NULL; + for (i=0; i < MAX_PERSONALITIES; i++) { + person = &personalities[i]; + if ( (PORT_Memcmp(person->CertLabel,"RRXX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"RTXX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"LAXX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"INKS",4) == 0) || + (PORT_Memcmp(person->CertLabel,"INKX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"ONKS",4) == 0) || + (PORT_Memcmp(person->CertLabel,"ONKX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"KEAK",4) == 0) || + (PORT_Memcmp(person->CertLabel,"3IKX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"DSA1",4) == 0) || + (PORT_Memcmp(person->CertLabel,"DSAI",4) == 0) || + (PORT_Memcmp(person->CertLabel,"DSAO",4) == 0) || + (PORT_Memcmp(person->CertLabel,"3IXS",4) == 0) || + (PORT_Memcmp(person->CertLabel,"3OXS",4) == 0) ){ + int index; + + cert->valid[cert->count].cert = NULL; + memcpy(cert->valid[cert->count].label, + person->CertLabel,sizeof(person->CertLabel)); + for (index = sizeof(person->CertLabel)-1; + cert->valid[cert->count].label[index] == ' '; index--) { + cert->valid[cert->count].label[index] = 0; + } + cert->valid[cert->count++].index = person->CertificateIndex; + } + } + for (i=0; i < MAX_PERSONALITIES; i++) { + person = &personalities[i]; + if (strncmp((char *)&person->CertLabel[8],name,user_len) == 0) { + cert->card = card; + cert->index = person->CertificateIndex; + memcpy(&cert->label,person->CertLabel,sizeof(person->CertLabel)); + return 1; + } + } + return 0; +} + +void +Terminate(char *mess, int cirv, int card1, int card2) +{ + fprintf(stderr,"FAIL: %s error %d\n",mess,cirv); + if (card1 != -1) CI_Close(CI_POWER_DOWN_FLAG,card1); + if (card2 != -1) CI_Close(CI_POWER_DOWN_FLAG,card2); + CI_Terminate(); + exit(1); +} + +void +usage(char *prog) +{ + fprintf(stderr,"usage: %s [-e email][-t transport][-u userpin][-U userpass][-s ssopin][-S ssopass][-o outfile] common_name ca_label\n",prog); + exit(1); +} + +#define CERT_SIZE 2048 + + +/* version and oid */ +unsigned char header[] = { + /* Cert OID */ + 0x02, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x30, 0x0b, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13 }; + +#define KEY_START 21 +#define KMID_OFFSET 4 +#define KEA_OFFSET 15 +#define DSA_OFFSET 148 +unsigned char key[] = { + /* Sequence(Constructed): 293 bytes (0x125) */ + 0x30, 0x82, 0x01, 0x25, + /*Sequence(Constructed): 11 bytes (0xb) */ + 0x30, 0x0b, + /* ObjectId(Universal): 9 bytes (0x9) */ + 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x14, + /* BitString(Universal): 276 bytes (0x114) */ + 0x03, 0x82, 0x01, 0x14, + 0x00, 0x00, 0x01, 0xef, 0x04, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x69, 0x60, 0x70, 0x00, 0x80, 0x02, + 0x2e, 0x46, 0xb9, 0xcb, 0x22, 0x72, 0x0b, 0x1c, + 0xe6, 0x25, 0x20, 0x16, 0x86, 0x05, 0x8e, 0x2b, + 0x98, 0xd1, 0x46, 0x3d, 0x00, 0xb8, 0x69, 0xe1, + 0x1a, 0x42, 0x7d, 0x7d, 0xb5, 0xbf, 0x9f, 0x26, + 0xd3, 0x2c, 0xb1, 0x73, 0x01, 0xb6, 0xb2, 0x6f, + 0x7b, 0xa5, 0x54, 0x85, 0x60, 0x77, 0x81, 0x8a, + 0x87, 0x86, 0xe0, 0x2d, 0xbf, 0xdb, 0x28, 0xe8, + 0xfa, 0x20, 0x35, 0xb4, 0xc0, 0x94, 0x10, 0x8e, + 0x1c, 0x58, 0xaa, 0x02, 0x60, 0x97, 0xf5, 0xb3, + 0x2f, 0xf8, 0x99, 0x29, 0x28, 0x73, 0x47, 0x36, + 0xdd, 0x1d, 0x78, 0x95, 0xeb, 0xb8, 0xec, 0x45, + 0x96, 0x69, 0x6f, 0x54, 0xc8, 0x1f, 0x2d, 0x3a, + 0xd9, 0x0e, 0x8e, 0xaa, 0x59, 0x11, 0x8c, 0x3b, + 0x8d, 0xa4, 0xed, 0xf2, 0x7d, 0xdc, 0x42, 0xaa, + 0xa4, 0xd2, 0x1c, 0xb9, 0x87, 0xd0, 0xd9, 0x3d, + 0x8e, 0x89, 0xbb, 0x06, 0x54, 0xcf, 0x32, 0x00, + 0x02, 0x00, 0x00, 0x80, 0x0b, 0x80, 0x6c, 0x0f, + 0x71, 0xd1, 0xa1, 0xa9, 0x26, 0xb4, 0xf1, 0xcd, + 0x6a, 0x7a, 0x09, 0xaa, 0x58, 0x28, 0xd7, 0x35, + 0x74, 0x8e, 0x7c, 0x83, 0xcb, 0xfe, 0x00, 0x3b, + 0x62, 0x00, 0xfb, 0x90, 0x37, 0xcd, 0x93, 0xcf, + 0xf3, 0xe4, 0x6d, 0x8d, 0xdd, 0xb8, 0x53, 0xe0, + 0x5c, 0xda, 0x1a, 0x7e, 0x56, 0x03, 0x95, 0x03, + 0x2f, 0x74, 0x86, 0xb1, 0xa0, 0xbb, 0x05, 0x91, + 0xe4, 0x76, 0x83, 0xe6, 0x62, 0xf9, 0x12, 0x64, + 0x5a, 0x62, 0xd8, 0x94, 0x04, 0x1f, 0x83, 0x02, + 0x2e, 0xc5, 0xa7, 0x17, 0x46, 0x46, 0x21, 0x96, + 0xc3, 0xa9, 0x8e, 0x92, 0x18, 0xd1, 0x52, 0x08, + 0x1d, 0xff, 0x8e, 0x24, 0xdb, 0x6c, 0xd8, 0xfe, + 0x80, 0x93, 0xe1, 0xa5, 0x4a, 0x0a, 0x37, 0x24, + 0x18, 0x07, 0xbe, 0x0f, 0xaf, 0x73, 0xea, 0x50, + 0x64, 0xa1, 0xb3, 0x77, 0xe5, 0x41, 0x02, 0x82, + 0x39, 0xb9, 0xe3, 0x94 +}; + +unsigned char valitity[] = { + 0x30, 0x1e, + 0x17, 0x0d, + '2','0','0','0','0','1','0','1','0','0','0','0','Z', + 0x17, 0x0d, + '2','0','0','5','1','2','0','1','0','0','0','0','Z' +}; + + +unsigned char cnam_oid[] = { 0x06, 0x03, 0x55, 0x04, 0x03 }; + +unsigned char signature[] = { + /* the OID */ + 0x30, 0x0b, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13, + /* signature wrap */ + 0x03, 0x29, 0x00, + /* 40 byte dsa signature */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +unsigned char fortezza_oid [] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13 +}; + +unsigned char software_ou[] = { + 0x31, 26, 0x30, 24, + 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 17, + 'S','o','f','t','w', + 'a','r','e',' ','F', + 'O','R','T','E','Z','Z','A' +}; + + +char letterarray[] = { + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v','w','x','y','z' }; + +char constarray[] = { + 'b','c','d','f','g','h','j','k','l','m','n', + 'p','q','r','s','t','v','w','x','y','z' }; + +char vowelarray[] = { + 'a','e','i','o','u','y' }; + +char digitarray[] = { + '0','1','2','3','4','5','6','7','8','9' }; + +unsigned long +getRandom(unsigned long max) { + unsigned short data; + unsigned long result; + + fort_GenerateRandom((unsigned char *)&data,sizeof(data)); + + result = (unsigned long)data * max; + result = result >> 16; + return result; +} + + +char getLetter(void) +{ + return letterarray[getRandom(sizeof(letterarray))]; +} +char getVowel(void) +{ + return vowelarray[getRandom(sizeof(vowelarray))]; +} +char getDigit(void) +{ + return digitarray[getRandom(sizeof(digitarray))]; +} + +char getConst(void) +{ + return constarray[getRandom(sizeof(constarray))]; +} + +char *getPinPhrase(void) +{ + char * pass = PORT_ZAlloc(5); + + pass[0] = getDigit(); + pass[1] = getDigit(); + pass[2] = getDigit(); + pass[3] = getDigit(); + + return pass; +} + +char *getPassPhrase(void) +{ + char * pass = PORT_ZAlloc(13); + + pass[0] = getConst()+'A'-'a'; + pass[1] = getVowel(); + pass[2] = getConst(); + pass[3] = getVowel(); + pass[4] = getConst(); + pass[5] = getVowel(); + pass[6] = getConst(); + pass[7] = getDigit(); + pass[8] = getDigit(); + pass[9] = getDigit(); + pass[10] = getDigit(); + pass[11] = getLetter()+'A'-'a'; + + return pass; +} + +extern void +makeCertSlot(fortSlotEntry * entry, + int index, + char * label, + SECItem * cert, + FORTSkipjackKeyPtr Ks, + unsigned char *xKEA, + unsigned char *xDSA, + unsigned char *pubKey, + int pubKeyLen, + unsigned char *p, + unsigned char *q, + unsigned char *g); + +extern void +makeProtectedPhrase(FORTSWFile * file, + fortProtectedPhrase *prot_phrase, + FORTSkipjackKeyPtr Ks, + FORTSkipjackKeyPtr Kinit, + char * phrase); + +extern void +fill_in(SECItem *item, unsigned char *data, int len); + +char *userLabel = "INKS0002 "; +int main(int argc, char **argv) +{ + char *progname = *argv++; + char *commonName = NULL; + char *caname = NULL; + char *email = NULL; + char *outname = NULL; + char *cp; + int arg_count = 0; + Cert caCert; + SECItem userCert; + int cirv,i; + int cards, start; + unsigned char *subject; + int subject_len; + int signature_len = sizeof(signature); + int newSubject_len, newCertBody_len, len; + int cname1_len, cname_len, pstring_len; + int valitity_len = sizeof(valitity); + unsigned char origCert[CERT_SIZE]; + unsigned char newSubject[CERT_SIZE]; + unsigned char newCertBody[CERT_SIZE]; + unsigned char newCert[CERT_SIZE]; + unsigned char pstring[CERT_SIZE]; + unsigned char cname1[CERT_SIZE]; + unsigned char cname[CERT_SIZE]; + CERTCertificate *myCACert = NULL; + CERTCertificate *cert; + CERTCertDBHandle *certhandle; + SECStatus rv; + unsigned char serial[16]; + SECKEYPublicKey *pubKey; + DSAPrivateKey *keaPrivKey; + DSAPrivateKey *dsaPrivKey; + CI_RANDOM randomVal; + PQGParams *params; + int pca_index = -1; + unsigned char *p,*q,*g; + FORTSkipjackKey Ks; + FORTSkipjackKey Kinit; + FORTSWFile *file; + FORTSignedSWFile *signed_file; + FORTSignedSWFile *signed_file2; + unsigned char random[20]; + unsigned char vers; + unsigned char *data; + char *transportPin=NULL; + char *ssoMemPhrase=NULL; + char *userMemPhrase=NULL; + char *ssoPin=NULL; + char *userPin=NULL; + char *pass=NULL; + SECItem *outItem; + int email_len = 0; + int emailAVA_len = 0; + + + /* put better argument parsing here */ + while ((cp = *argv++) != NULL) { + if (*cp == '-') { + while (*++cp) { + switch (*cp) { + /* verbose mode */ + case 'e': + email = *argv++; + break; + /* explicitly set the target */ + case 'o': + outname = *argv++; + break; + case 't': + /* provide password on command line */ + transportPin = *argv++; + break; + case 'u': + /* provide user password on command line */ + userPin = *argv++; + break; + case 'U': + /* provide user password on command line */ + userMemPhrase = *argv++; + break; + case 's': + /* provide user password on command line */ + ssoPin = *argv++; + break; + case 'S': + /* provide user password on command line */ + ssoMemPhrase = *argv++; + break; + case 'p': + /* provide card password on command line */ + pass = *argv++; + break; + case 'd': + transportPin="test1234567890"; + ssoMemPhrase="sso1234567890"; + userMemPhrase="user1234567890"; + ssoPin="9999"; + userPin="0000"; + break; + default: + usage(progname); + break; + } + } + } else switch (arg_count++) { + case 0: + commonName = cp; + break; + case 1: + caname = cp; + break; + default: + usage(progname); + } + } + + if (outname == NULL) outname = "swfort.sfi"; + if (caname == NULL) usage(progname); + + + + caCert.card = -1; + memset(newCert,0,CERT_SIZE); + + if (commonName == NULL) usage(progname); + + + cirv = CI_Initialize(&cards); + + start = 0; + for (i=0; i < cards; i++) { + cirv = InitCard(i+1,pass); + if (cirv == CI_OK) { + if (FoundCert(i+1,caname,&caCert)) { + break; + } + } + } + + if (caCert.card == -1) { + fprintf(stderr, + "WARNING: Couldn't find Signing CA...new cert will not be signed\n"); + } + + + /* + * initialize enough security to deal with certificates. + */ + NSS_NoDB_Init(NULL); + certhandle = CERT_GetDefaultCertDB(); + if (certhandle == NULL) { + Terminate("Couldn't build temparary Cert Database", + 1, -1, caCert.card); + exit(1); + } + + CI_GenerateRandom(random); + RNG_RandomUpdate(random,sizeof(random)); + CI_GenerateRandom(random); + RNG_RandomUpdate(random,sizeof(random)); + + + if (transportPin == NULL) transportPin = getPassPhrase(); + if (ssoMemPhrase == NULL) ssoMemPhrase = getPassPhrase(); + if (userMemPhrase == NULL) userMemPhrase = getPassPhrase(); + if (ssoPin == NULL) ssoPin = getPinPhrase(); + if (userPin == NULL) userPin = getPinPhrase(); + + + + /* now dump the certs into the temparary data base */ + for (i=0; i < caCert.count; i++) { + SECItem derCert; + + cirv = CI_Select(caCert.card); + if (cirv != CI_OK) { + Terminate("Couldn't select on CA card",cirv, + -1, caCert.card); + } + cirv = CI_GetCertificate(caCert.valid[i].index,origCert); + if (cirv != CI_OK) { + continue; + } + derCert.data = origCert; + derCert.len = Cert_length(origCert, sizeof(origCert)); + cert = + (CERTCertificate *)CERT_NewTempCertificate(certhandle,&derCert, NULL, + PR_FALSE, PR_TRUE); + caCert.valid[i].cert = cert; + if (cert == NULL) continue; + if (caCert.valid[i].index == caCert.index) myCACert=cert; + if (caCert.valid[i].index == atoi((char *)&caCert.label[4])) + pca_index = i; + } + + if (myCACert == NULL) { + Terminate("Couldn't find CA's Certificate", 1, -1, caCert.card); + exit(1); + } + + + /* + * OK now build the user cert. + */ + /* first get the serial number and KMID */ + cirv = CI_GenerateRandom(randomVal); + memcpy(&header[2],randomVal,sizeof(serial)); + memcpy(serial,randomVal,sizeof(serial)); + memcpy(&key[KEY_START+KMID_OFFSET],randomVal+sizeof(serial),7); + /* KMID */ + + /* now generate the keys */ + pubKey = CERT_ExtractPublicKey(myCACert); + if (pubKey == NULL) { + Terminate("Couldn't extract CA's public key", + 1, -1, caCert.card); + exit(1); + } + + + switch (pubKey->keyType) { + case fortezzaKey: + params = (PQGParams *)&pubKey->u.fortezza.params; + break; + case dsaKey: + params = (PQGParams *)&pubKey->u.dsa.params; + break; + default: + Terminate("Certificate is not a fortezza or DSA Cert", + 1, -1, caCert.card); + exit(1); + } + + rv = DSA_NewKey(params,&keaPrivKey); + if (rv != SECSuccess) { + Terminate("Couldn't Generate KEA key", + PORT_GetError(), -1, caCert.card); + exit(1); + } + rv = DSA_NewKey(params,&dsaPrivKey); + if (rv != SECSuccess) { + Terminate("Couldn't Generate DSA key", + PORT_GetError(), -1, caCert.card); + exit(1); + } + + if (keaPrivKey->publicValue.len == 129) + keaPrivKey->publicValue.data++; + if (dsaPrivKey->publicValue.len == 129) + dsaPrivKey->publicValue.data++; + if (keaPrivKey->privateValue.len == 21) + keaPrivKey->privateValue.data++; + if (dsaPrivKey->privateValue.len == 21) + dsaPrivKey->privateValue.data++; + + /* save the parameters */ + p = params->prime.data; + if (params->prime.len == 129) p++; + q = params->subPrime.data; + if (params->subPrime.len == 21) q++; + g = params->base.data; + if (params->base.len == 129) g++; + + memcpy(&key[KEY_START+KEA_OFFSET], + keaPrivKey->publicValue.data, + keaPrivKey->publicValue.len); + memcpy(&key[KEY_START+DSA_OFFSET], + dsaPrivKey->publicValue.data, + dsaPrivKey->publicValue.len); + + /* build the der subject */ + subject = data_start(myCACert->derSubject.data,myCACert->derSubject.len, + &subject_len); + + /* build the new Common name AVA */ + len = DER_Sequence(pstring,strlen(commonName)); + memcpy(pstring+len,commonName,strlen(commonName)); + len += strlen(commonName); + pstring_len = len; + pstring[0] = 0x13; + + len = DER_Sequence(cname1,sizeof(cnam_oid)+pstring_len); + memcpy(cname1+len,cnam_oid,sizeof(cnam_oid)); len += sizeof(cnam_oid); + memcpy(cname1+len,pstring,pstring_len); len += pstring_len; + cname1_len = len; + + len = DER_Sequence(cname, cname1_len); + memcpy(cname+len,cname1,cname1_len); len += cname1_len; + cname_len = len; + cname[0] = 0x31; /* make it a set rather than a sequence */ + + if (email) { + email_len = strlen(email); + emailAVA_len = EMAIL_DATA_START + email_len; + } + + /* now assemble it */ + len = DER_Sequence(newSubject,subject_len + sizeof(software_ou) + + cname_len + emailAVA_len); + memcpy(newSubject+len,subject,subject_len); + + for (i=0; i < subject_len; i++) { + if (memcmp(newSubject+len+i,cnam_oid,sizeof(cnam_oid)) == 0) { + newSubject[i+len+4] = 0x0b; /* change CN to OU */ + break; + } + } + len += subject_len; + memcpy(newSubject+len,software_ou,sizeof(software_ou)); + len += sizeof(software_ou); + memcpy(newSubject+len,cname,cname_len); len += cname_len; + newSubject_len = len; + + /* + * build the email AVA + */ + if (email) { + memcpy(&emailAVA[EMAIL_DATA_START],email,email_len); + for (i=0; i < offsetCount; i++) { + emailAVA[emailOffset[i]] += email_len; + } + memcpy(newSubject+len,emailAVA,emailAVA_len); + newSubject_len += emailAVA_len; + } + + + /* + * Assemble the Cert + */ + + len = DER_Sequence(newCertBody,sizeof(header)+newSubject_len+ + valitity_len+myCACert->derSubject.len+sizeof(key)); + memcpy(newCertBody+len,header,sizeof(header));len += sizeof(header); + memcpy(newCertBody+len,myCACert->derSubject.data, + myCACert->derSubject.len);len += myCACert->derSubject.len; + memcpy(newCertBody+len,valitity,valitity_len);len += valitity_len; + memcpy(newCertBody+len,newSubject,newSubject_len); + len += newSubject_len; + memcpy(newCertBody+len,key,sizeof(key));len += sizeof(key); + newCertBody_len = len; + + + /* + * generate the hash + */ + cirv = CI_InitializeHash(); + if (cirv == CI_OK) { + int hash_left = newCertBody_len & 63; + int hash_len = newCertBody_len - hash_left; + cirv = CI_Hash(hash_len,newCertBody); + if (cirv == CI_OK) { + cirv = CI_GetHash(hash_left,newCertBody+hash_len,hash); + } + } + + /* + * now sign the hash + */ + if ((cirv == CI_OK) && (caCert.card != -1)) { + cirv = CI_Select(caCert.card); + if (cirv == CI_OK) { + cirv = CI_SetPersonality(caCert.index); + if (cirv == CI_OK) { + cirv = CI_Sign(hash,sig); + } + } + } else cirv = -1; + + if (cirv != CI_OK) { + memcpy(sig,hash,sizeof(hash)); + } + + /* + * load in new signature + */ + { + int sig_len; + unsigned char *sig_start = + GetSignature(signature,signature_len,&sig_len); + memcpy(sig_start,sig,sizeof(sig)); + } + + /* + * now do the final wrap + */ + len = DER_Sequence(newCert,newCertBody_len+signature_len); + memcpy(newCert+len,newCertBody,newCertBody_len); len += newCertBody_len; + memcpy(newCert+len, signature, signature_len); len +=signature_len; + userCert.data = newCert; + userCert.len = len; + + + /* OK, we now have our cert, let's go build our software file */ + signed_file = PORT_ZNew(FORTSignedSWFile); + file = &signed_file->file; + + signed_file->signatureWrap.signature.data = PORT_ZAlloc(40); + signed_file->signatureWrap.signature.len = 40; + signed_file->signatureWrap.signatureAlgorithm.algorithm.data = + fortezza_oid; + signed_file->signatureWrap.signatureAlgorithm.algorithm.len = + sizeof(fortezza_oid); + + vers = 1; + fill_in(&file->version,&vers,1); + file->derIssuer.data = myCACert->derSubject.data; + file->derIssuer.len = myCACert->derSubject.len; + file->serialID.data = serial; + file->serialID.len =sizeof(serial); + /* generate out Ks value */ + fort_GenerateRandom(Ks,sizeof(Ks)); + makeProtectedPhrase(file,&file->initMemPhrase,Kinit,NULL,transportPin); + makeProtectedPhrase(file,&file->ssoMemPhrase,Ks,Kinit,ssoMemPhrase); + makeProtectedPhrase(file,&file->ssoPinPhrase,Ks,Kinit,ssoPin); + makeProtectedPhrase(file,&file->userMemPhrase,Ks,Kinit,userMemPhrase); + makeProtectedPhrase(file,&file->userPinPhrase,Ks,Kinit,userPin); + file->wrappedRandomSeed.data = PORT_ZAlloc(12); + file->wrappedRandomSeed.len = 12; + cirv = fort_GenerateRandom(file->wrappedRandomSeed.data,10); + if (cirv != CI_OK) { + Terminate("Couldn't get Random Seed", + cirv, -1, caCert.card); + } + fort_skipjackWrap(Ks,12,file->wrappedRandomSeed.data, + file->wrappedRandomSeed.data); + file->slotEntries = PORT_ZAlloc(sizeof(fortSlotEntry *)*5); + /* paa */ + file->slotEntries[0] = PORT_ZNew(fortSlotEntry); + makeCertSlot(file->slotEntries[0],0, + (char *)caCert.valid[0].label, + &caCert.valid[0].cert->derCert, + Ks,NULL,NULL,NULL,0,p,q,g); + /* pca */ + file->slotEntries[1] = PORT_ZNew(fortSlotEntry); + makeCertSlot(file->slotEntries[1],1, + (char *)caCert.valid[pca_index].label, + &caCert.valid[pca_index].cert->derCert, + Ks,NULL,NULL,NULL,0,p,q,g); + /* ca */ + file->slotEntries[2] = PORT_ZNew(fortSlotEntry); + /* make sure the caCert lable points to our new pca slot location */ + caCert.label[4] = '0'; + caCert.label[5] = '0'; + caCert.label[6] = '0'; + caCert.label[7] = '1'; + makeCertSlot(file->slotEntries[2],2,(char *)caCert.label, + &myCACert->derCert,Ks,NULL,NULL,NULL,0,p,q,g); + /* user */ + file->slotEntries[3] = PORT_ZNew(fortSlotEntry); + strncpy(&userLabel[8],commonName,sizeof(CI_PERSON)-8); + makeCertSlot(file->slotEntries[3],3,userLabel,&userCert,Ks, + keaPrivKey->privateValue.data, + dsaPrivKey->privateValue.data, + key, sizeof(key), p, q, g); + file->slotEntries[4] = 0; + + /* encode the file so we can sign it */ + outItem = FORT_PutSWFile(signed_file); + + /* get the der encoded data to sign */ + signed_file2 = FORT_GetSWFile(outItem); + + /* now sign it */ + len = signed_file2->signatureWrap.data.len; + data = signed_file2->signatureWrap.data.data; + /* + * generate the hash + */ + cirv = CI_InitializeHash(); + if (cirv == CI_OK) { + int hash_left = len & 63; + int hash_len = len - hash_left; + cirv = CI_Hash(hash_len,data); + if (cirv == CI_OK) { + cirv = CI_GetHash(hash_left,data+hash_len,hash); + } + } + + /* + * now sign the hash + */ + if ((cirv == CI_OK) && (caCert.card != -1)) { + cirv = CI_Select(caCert.card); + if (cirv == CI_OK) { + cirv = CI_SetPersonality(caCert.index); + if (cirv == CI_OK) { + cirv = CI_Sign(hash,sig); + } + } + } else cirv = -1; + + if (cirv != CI_OK) { + memcpy(sig,hash,sizeof(hash)); + } + memcpy( signed_file->signatureWrap.signature.data,sig,sizeof(sig)); + signed_file->signatureWrap.signature.len = sizeof(sig)*8; + + + /* encode it for the last time */ + outItem = FORT_PutSWFile(signed_file); + + + /* + * write it out to the .sfi file + */ + { + int fd = open(outname,O_WRONLY|O_CREAT|O_BINARY,0777); + + write(fd,outItem->data,outItem->len); + close(fd); + } + CI_Close(CI_POWER_DOWN_FLAG,caCert.card); + CI_Terminate(); + + printf("Wrote %s to file %s.\n",commonName,outname); + printf("Initialization Memphrase: %s\n",transportPin); + printf("SSO Memphrase: %s\n",ssoMemPhrase); + printf("User Memphrase: %s\n",userMemPhrase); + printf("SSO pin: %s\n",ssoPin); + printf("User pin: %s\n",userPin); + + return 0; +} + diff --git a/security/nss/cmd/ttformat/Makefile b/security/nss/cmd/ttformat/Makefile new file mode 100644 index 000000000..4de295a9c --- /dev/null +++ b/security/nss/cmd/ttformat/Makefile @@ -0,0 +1,78 @@ +#! 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/ttformat/manifest.mn b/security/nss/cmd/ttformat/manifest.mn new file mode 100644 index 000000000..39667ee88 --- /dev/null +++ b/security/nss/cmd/ttformat/manifest.mn @@ -0,0 +1,52 @@ +# +# ***** 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 ***** + +CORE_DEPTH = ../../.. + +DEFINES += -DNSPR20 + +# MODULE public and private header directories are implicitly REQUIRED. +MODULE = nss + +CSRCS = ttformat.c + +# The MODULE is always implicitly required. +# Listing it here in REQUIRES makes it appear twice in the cc command line. +REQUIRES = seccmd dbm + +PROGRAM = ttformat + diff --git a/security/nss/cmd/ttformat/nClient b/security/nss/cmd/ttformat/nClient new file mode 100755 index 000000000..aab8402bd --- /dev/null +++ b/security/nss/cmd/ttformat/nClient @@ -0,0 +1,49 @@ +# /bin/ksh +# +# nClient -- run the nss test strsclnt for performance testing +# +# syntax: nClient [options] +# +# where: options are: +# any valid command line option for strsclnt +# Note that some options are set by this script! +# +# Description: +# nClient runs the nss test program "strsclnt" for purposes of +# gathering performance data. +# +# some shell variables are set at the top of the script +# you may have to change these, depending on the host you +# are running on and other "stuff". caveat emptor. +# +# You will have to tinker with this script to get it to +# run for you. +# +# See also: nServ +# +# --- begin nClient ------------------------------------------------------- +baseDir=/home/lorenzo/nss-raw/mozilla +# +# shell variables for running strsclnt +# +export HOST=`hostname -s` +export DOMSUF=red.iplanet.com +serverHost=dbldog +nssDB=${baseDir}/tests_results/security/${HOST}.1/client +nssHost=${HOST}.red.iplanet.com +pushd ${baseDir}/security/nss/tests/common +objDir=`gmake objdir_name` +popd +# +# +nssOptions="-p 12944 ${serverHost}.red.iplanet.com" +export LD_LIBRARY_PATH=${baseDir}/dist/${objDir}/lib +clientProg=${baseDir}/security/nss/cmd/strsclnt/${objDir}/strsclnt +# +# do the test +# +nssCommand="${clientProg} -d ${nssDB} ${nssOptions}" +echo $nssCommand $* +${nssCommand} $* & +# +# --- end nClient -------------------------------------------------------- diff --git a/security/nss/cmd/ttformat/nServ b/security/nss/cmd/ttformat/nServ new file mode 100755 index 000000000..ddf51b0e8 --- /dev/null +++ b/security/nss/cmd/ttformat/nServ @@ -0,0 +1,49 @@ +# /bin/ksh +# +# nServ -- run the nss test selfserv for performance testing +# +# syntax: nServ [options] +# +# where: options are: +# Valid arguments to the selfserv program +# Note that this script sets some options +# +# Description: +# nServ runs the nss test program "selfserv" for purposes of +# gathering performance data. +# +# some shell variables are set at the top of the script +# you may have to change these, depending on the host you +# are running on and other "stuff". caveat emptor. +# +# See also: nClinet +# +# --- begin nServ ------------------------------------------------------- +# +baseDir=/home/lorenzo/nss-server/mozilla +# +# shell variables for running selfserv +# +export HOST=`hostname -s` +export DOMSUF=red.iplanet.com +nssDB=${baseDir}/tests_results/security/${HOST}.1/server +nssHost=${HOST}.red.iplanet.com +nssOptions="-p 12944 -w nss" +pushd ${baseDir}/security/nss/tests/common +objDir=`gmake objdir_name` +popd +export LD_LIBRARY_PATH=${baseDir}/dist/${objDir}/lib +# +# shell variables for capturing instrumentation data +# +export NSPR_LOG_MODULES=TestCase:6 +export NSPR_LOG_FILE=xxxLogfile +# +# do the test +# +nssCommand="${baseDir}/dist/${objDir}/bin/selfserv -d ${nssDB} -n ${nssHost} ${nssOptions}" +echo $nssCommand +${nssCommand} $* & +# xxgdb ${baseDir}/dist/${objDir}/bin/selfserv +# +# --- end nServ ------------------------------------------------------- diff --git a/security/nss/cmd/ttformat/redux.pl b/security/nss/cmd/ttformat/redux.pl new file mode 100755 index 000000000..ccc13c24a --- /dev/null +++ b/security/nss/cmd/ttformat/redux.pl @@ -0,0 +1,77 @@ +# +# redux.pl -- general nss trace data extraction +# +# syntax: redux.pl +# +# redux.pl reads a file of formatted trace table records from stdin +# The trace records are formatted by nssilock.c +# redux.pl parses the lines and accumulates data in a hash +# When finished with stdin, redux.pl traverses the hash and emits +# the accumulated data. +# +# Operation: +# read stdin, accumulate in a hash by file, line, type. +# traverse the hash, reporting data. +# +# raw data format: +# thredid op ltype callTime heldTime lock line file +# +# Notes: +# After running redux.pl, sort the report on column 4 in decending sequence +# to see where the lock contention is. +# +# +# ----------------------------------------------------------------------- +use Getopt::Std; + +getopts("h") || die "redux.pl: unrecognized command option"; + + +# ----------------------------------------------------------------------- +# read stdin to exhaustion +while ( <STDIN> ) { + $recordCount++; +# next if ($recordCount < 36000 ); # skip initialization records + chomp; + ($thredid, $op, $ltype, $callTime, $heldTime, $lock, $line, $file) = split; + +# select out un-interesting lines +# next if (( $callTime < $opt_c ) && ( $heldTime < $opt_h )); +# print $_, "\n"; + +# count general stats + $interesting++; + +# format the key + $hashKey = $file ." ". $line ." ". $ltype; + +# Update the data in the hash entry + $theData = $theHash{$hashKey}; # read it if it already exists + ( $hCount, $hcallTime, $hheldTime, $hcallMax, $hheldMax ) = split(/\s+/, $theData ); + $hCount++; + $hcallTime += $callTime; + $hheldTime += $heldTime; + $hcallMax = ( $hcallMax > $callTime )? $hcallMax : $callTime; + $hheldMax = ( $hheldMax > $heldTime )? $hheldMax : $heldTime; + +# Write theData back to the hash + $theData = $hCount." ".$hcallTime." ".$hheldTime." ".$hcallMax." ".$hheldMax; + $theHash{$hashKey} = $theData; +} # end while() + +# ----------------------------------------------------------------------- +# traverse theHash + printf("%-16s %6s %-16s %8s %8s %8s %8s %8s\n", + "File","line","ltype","hits","calltim","heldtim","callmax","heldmax" ); +while (($hashKey,$theData) = each(%theHash)) { + $hashElements++; + ($file, $line, $ltype) = split(/\s+/, $hashKey ); + ( $hCount, $hcallTime, $hheldTime, $hcallMax, $hheldMax ) = split(/\s+/, $theData ); + printf("%-16s %6d %-16s %8d %8d %8d %8d %8d\n", + $file, $line, $ltype, $hCount, $hcallTime, $hheldTime, $hcallMax, $hheldMax ); +} # end while() + +# ----------------------------------------------------------------------- +# dump global statistics +printf ("Record count: %d\n", $recordCount ); +printf("Interesting: %d, HashElements: %d\n", $interesting, $hashElements); diff --git a/security/nss/cmd/ttformat/reduxhwm.pl b/security/nss/cmd/ttformat/reduxhwm.pl new file mode 100644 index 000000000..f442ff4e4 --- /dev/null +++ b/security/nss/cmd/ttformat/reduxhwm.pl @@ -0,0 +1,33 @@ +# +# reduxhwm.pl -- analyze highwatermark data in xxxLogfile +# +# example interesting line in xxxLogfile +# 1026[8154da0]: selfserv: Launched thread in slot 37, highWaterMark: 63 +# +# +# +while ( <STDIN> ) { + chomp; + ($proc, $who, $launched, $thread, $in, $slotx, $slot, $hwm, $highwatermark) = split; + if ( $launched == "Launched" ) { + next if ( $slot == 0 ); + $notInteresting++; + if ( $hwmMax < $highwatermark ){ + $hwmMax = $highwatermark; + } + $hwmArray[$slot] += 1; + $interesting++; + } +} # end while() + +printf ("Interesteing: %d\n", $interesting ); +printf ("Not Interesting: %d\n", $notInteresting - $interesting ); + +foreach $element (@hwmArray) { + $percent = 100*($element / $interesting); + $percentTotal += $percent; + printf("Slot %2d: %d hits, %2.2f percent, %2.2f total percent\n", $i, $element, $percent, $percentTotal ); + $i++; +} +printf("Sum of percentages: %3.2f\n", $percentTotal ); +# --- end --- diff --git a/security/nss/cmd/ttformat/ttformat.c b/security/nss/cmd/ttformat/ttformat.c new file mode 100644 index 000000000..26c9bbbce --- /dev/null +++ b/security/nss/cmd/ttformat/ttformat.c @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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 Portable Runtime (NSPR). + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-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 ***** */ + +/* +** File: ttformat.c +** Description: ttformat.c reads the file "xxxTTLog". xxxTTLog +** contains fixed length binary data written by nssilock. +** ttformat formats the data to a human readable form (printf) +** usable for visual scanning and for processing via a perl script. +** Output is written to stdout +** +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <nssilock.h> + +/* +** struct maps enum nssILockType to character representation +*/ +struct { + nssILockType ltype; + char *name; +} ltypeNameT[] = { + { nssILockArena, "Arena" }, + { nssILockSession, "Session" }, + { nssILockObject, "Object" }, + { nssILockRefLock, "RefLock" }, + { nssILockCert, "Cert", }, + { nssILockCertDB, "CertDB" }, + { nssILockDBM, "DBM" }, + { nssILockCache, "Cache" }, + { nssILockSSL, "SSL" }, + { nssILockList, "List" }, + { nssILockSlot, "Slot" }, + { nssILockFreelist, "Freelist" }, + { nssILockOID, "OID" }, + { nssILockAttribute, "Attribute" }, + { nssILockPK11cxt, "PK11Context" }, + { nssILockRWLock, "RWLock" }, + { nssILockOther, "Other" }, + { nssILockSelfServ, "SelfServ" } +}; /* end ltypeNameT */ + +/* +** struct maps enum nssILockOp to character representation +*/ +struct { + nssILockOp op; + char *name; +} opNameT[] = { + { FlushTT, "FlushTT" }, + { NewLock, "NewLock" }, + { Lock, "Lock" }, + { Unlock, "Unlock" }, + { DestroyLock, "DestroyLock" }, + { NewCondVar, "NewCondVar" }, + { WaitCondVar, "WaitCondVar" }, + { NotifyCondVar, "NotifyCondVar" }, + { NotifyAllCondVar, "NotifyAllCondVar" }, + { DestroyCondVar, "DestroyCondVar" }, + { NewMonitor, "NewMonitor" }, + { EnterMonitor, "EnterMonitor" }, + { ExitMonitor, "ExitMonitor" }, + { Notify, "Notify" }, + { NotifyAll, "NotifyAll" }, + { Wait, "Wait" }, + { DestroyMonitor, "DestroyMonitor" } +}; /* end opNameT */ + + +int main(int argc, char *argv[]) +{ + FILE *filea; + struct pzTrace_s inBuf; + char *opName; + char *ltypeName; + int rCount = 0; + int oCount = 0; + + filea = fopen( "xxxTTLog", "r" ); + if ( NULL == filea ) { + fprintf( stderr, "ttformat: Oh drat! Can't open 'xxxTTLog'\n" ); + exit(1); + } + + while(1 == (fread( &inBuf, sizeof(inBuf), 1 , filea ))) { + ++rCount; + if ( inBuf.op > DestroyMonitor ) continue; + if ( inBuf.op < FlushTT ) continue; + + opName = opNameT[inBuf.op].name; + ltypeName = ltypeNameT[inBuf.ltype].name; + + ++oCount; + printf("%8d %18s %18s %6d %6d %12p %6d %20s\n", + inBuf.threadID, opName, ltypeName, inBuf.callTime, inBuf.heldTime, + inBuf.lock, inBuf.line, inBuf.file ); + } /* end while() */ + + fprintf( stderr, "Read: %d, Wrote: %d\n", rCount, oCount ); + return 0; +} /* main() */ +/* end ttformat.c */ |