diff options
Diffstat (limited to 'security')
112 files changed, 25927 insertions, 2082 deletions
diff --git a/security/coreconf/FreeBSD.mk b/security/coreconf/FreeBSD.mk index a18739962..e0ac591dc 100644 --- a/security/coreconf/FreeBSD.mk +++ b/security/coreconf/FreeBSD.mk @@ -75,10 +75,10 @@ endif MKSHLIB = $(CC) $(DSO_LDOPTS) ifdef MAPFILE -# Add LD options to restrict exported symbols to those in the map file + MKSHLIB += -Wl,--version-script,$(MAPFILE) endif -# Change PROCESS to put the mapfile in the correct format for this platform -PROCESS_MAP_FILE = cp $< $@ +PROCESS_MAP_FILE = grep -v ';-' $< | \ + sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ G++INCLUDES = -I/usr/include/g++ diff --git a/security/coreconf/Linux.mk b/security/coreconf/Linux.mk index 3a7b25fe8..d87c4ce82 100644 --- a/security/coreconf/Linux.mk +++ b/security/coreconf/Linux.mk @@ -165,7 +165,7 @@ endif ARCH = linux DSO_CFLAGS = -fPIC -DSO_LDOPTS = -shared $(ARCHFLAG) -z defs +DSO_LDOPTS = -shared $(ARCHFLAG) DSO_LDFLAGS = LDFLAGS += $(ARCHFLAG) diff --git a/security/coreconf/Linux2.6.mk b/security/coreconf/Linux2.6.mk index 86bffef75..d51f5a952 100644 --- a/security/coreconf/Linux2.6.mk +++ b/security/coreconf/Linux2.6.mk @@ -37,6 +37,8 @@ include $(CORE_DEPTH)/coreconf/Linux.mk +DSO_LDOPTS += -Wl,-z,defs + OS_REL_CFLAGS += -DLINUX2_1 MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) diff --git a/security/dbm/config/config.mk b/security/dbm/config/config.mk deleted file mode 100644 index 753364931..000000000 --- a/security/dbm/config/config.mk +++ /dev/null @@ -1,67 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -# -# These macros are defined by mozilla's configure script. -# We define them manually here. -# - -DEFINES += -DSTDC_HEADERS -DHAVE_STRERROR - -# -# Most platforms have snprintf, so it's simpler to list the exceptions. -# -HAVE_SNPRINTF = 1 -# -# OSF1 V4.0D doesn't have snprintf but V5.0A does. -# -ifeq ($(OS_TARGET)$(OS_RELEASE),OSF1V4.0D) -HAVE_SNPRINTF = -endif -ifdef HAVE_SNPRINTF -DEFINES += -DHAVE_SNPRINTF -endif - -ifeq (,$(filter-out IRIX Linux,$(OS_TARGET))) -DEFINES += -DHAVE_SYS_CDEFS_H -endif - -ifeq (,$(filter-out DGUX NCR ReliantUNIX SCO_SV SCOOS UNIXWARE,$(OS_TARGET))) -DEFINES += -DHAVE_SYS_BYTEORDER_H -endif - -# -# None of the platforms that we are interested in need to -# define HAVE_MEMORY_H. -# diff --git a/security/dbm/include/manifest.mn b/security/dbm/include/manifest.mn deleted file mode 100644 index 886fedd98..000000000 --- a/security/dbm/include/manifest.mn +++ /dev/null @@ -1,57 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -CORE_DEPTH = ../.. - -VPATH = $(CORE_DEPTH)/../dbm/include - -MODULE = dbm - -EXPORTS = nsres.h \ - cdefs.h \ - mcom_db.h \ - ncompat.h \ - winfile.h \ - $(NULL) - -PRIVATE_EXPORTS = hsearch.h \ - page.h \ - extern.h \ - ndbm.h \ - queue.h \ - hash.h \ - mpool.h \ - search.h \ - $(NULL) - diff --git a/security/dbm/manifest.mn b/security/dbm/manifest.mn deleted file mode 100644 index d4065f761..000000000 --- a/security/dbm/manifest.mn +++ /dev/null @@ -1,45 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -CORE_DEPTH = .. - -MODULE = dbm - -IMPORTS = nspr20/v4.4.1 - -RELEASE = dbm - -DIRS = include \ - src \ - $(NULL) diff --git a/security/dbm/src/config.mk b/security/dbm/src/config.mk deleted file mode 100644 index 370fd75d6..000000000 --- a/security/dbm/src/config.mk +++ /dev/null @@ -1,63 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -DEFINES += -DMEMMOVE -D__DBINTERFACE_PRIVATE $(SECURITY_FLAG) - -INCLUDES += -I$(CORE_DEPTH)/../dbm/include - -# -# Currently, override TARGETS variable so that only static libraries -# are specifed as dependencies within rules.mk. -# - -TARGETS = $(LIBRARY) -SHARED_LIBRARY = -IMPORT_LIBRARY = -PURE_LIBRARY = -PROGRAM = - -ifdef SHARED_LIBRARY - ifeq (,$(filter-out WINNT WIN95 WINCE,$(OS_TARGET))) # list omits WIN16 - DLLBASE=/BASE:0x30000000 - RES=$(OBJDIR)/dbm.res - RESNAME=../include/dbm.rc - endif - ifeq ($(DLL_SUFFIX),dll) - DEFINES += -D_DLL - endif -endif - -ifeq ($(OS_TARGET),AIX) - OS_LIBS += -lc_r -endif diff --git a/security/dbm/src/dirent.c b/security/dbm/src/dirent.c deleted file mode 100644 index 001a48c5c..000000000 --- a/security/dbm/src/dirent.c +++ /dev/null @@ -1,348 +0,0 @@ -#ifdef OS2 - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include <dirent.h> -#include <errno.h> - -/*#ifndef __EMX__ -#include <libx.h> -#endif */ - -#define INCL_DOSFILEMGR -#define INCL_DOSERRORS -#include <os2.h> - -#if OS2 >= 2 -# define FFBUF FILEFINDBUF3 -# define Word ULONG - /* - * LS20 recommends a request count of 100, but according to the - * APAR text it does not lead to missing files, just to funny - * numbers of returned entries. - * - * LS30 HPFS386 requires a count greater than 2, or some files - * are missing (those starting with a character less that '.'). - * - * Novell looses entries which overflow the buffer. In previous - * versions of dirent2, this could have lead to missing files - * when the average length of 100 directory entries was 40 bytes - * or more (quite unlikely for files on a Novell server). - * - * Conclusion: Make sure that the entries all fit into the buffer - * and that the buffer is large enough for more than 2 entries - * (each entry is at most 300 bytes long). And ignore the LS20 - * effect. - */ -# define Count 25 -# define BufSz (25 * (sizeof(FILEFINDBUF3)+1)) -#else -# define FFBUF FILEFINDBUF -# define Word USHORT -# define BufSz 1024 -# define Count 3 -#endif - -#if defined(__IBMC__) || defined(__IBMCPP__) - #define error(rc) _doserrno = rc, errno = EOS2ERR -#elif defined(MICROSOFT) - #define error(rc) _doserrno = rc, errno = 255 -#else - #define error(rc) errno = 255 -#endif - -struct _dirdescr { - HDIR handle; /* DosFindFirst handle */ - char fstype; /* filesystem type */ - Word count; /* valid entries in <ffbuf> */ - long number; /* absolute number of next entry */ - int index; /* relative number of next entry */ - FFBUF * next; /* pointer to next entry */ - char name[MAXPATHLEN+3]; /* directory name */ - unsigned attrmask; /* attribute mask for seekdir */ - struct dirent entry; /* buffer for directory entry */ - BYTE ffbuf[BufSz]; -}; - -/* - * Return first char of filesystem type, or 0 if unknown. - */ -static char -getFSType(const char *path) -{ - static char cache[1+26]; - char drive[3], info[512]; - Word unit, infolen; - char r; - - if (isalpha(path[0]) && path[1] == ':') { - unit = toupper(path[0]) - '@'; - path += 2; - } else { - ULONG driveMap; -#if OS2 >= 2 - if (DosQueryCurrentDisk(&unit, &driveMap)) -#else - if (DosQCurDisk(&unit, &driveMap)) -#endif - return 0; - } - - if ((path[0] == '\\' || path[0] == '/') - && (path[1] == '\\' || path[1] == '/')) - return 0; - - if (cache [unit]) - return cache [unit]; - - drive[0] = '@' + unit; - drive[1] = ':'; - drive[2] = '\0'; - infolen = sizeof info; -#if OS2 >= 2 - if (DosQueryFSAttach(drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen)) - return 0; - if (infolen >= sizeof(FSQBUFFER2)) { - FSQBUFFER2 *p = (FSQBUFFER2 *)info; - r = p->szFSDName[p->cbName]; - } else -#else - if (DosQFSAttach((PSZ)drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen, 0)) - return 0; - if (infolen >= 9) { - char *p = info + sizeof(USHORT); - p += sizeof(USHORT) + *(USHORT *)p + 1 + sizeof(USHORT); - r = *p; - } else -#endif - r = 0; - return cache [unit] = r; -} - -char * -abs_path(const char *name, char *buffer, int len) -{ - char buf[4]; - if (isalpha(name[0]) && name[1] == ':' && name[2] == '\0') { - buf[0] = name[0]; - buf[1] = name[1]; - buf[2] = '.'; - buf[3] = '\0'; - name = buf; - } -#if OS2 >= 2 - if (DosQueryPathInfo((PSZ)name, FIL_QUERYFULLNAME, buffer, len)) -#else - if (DosQPathInfo((PSZ)name, FIL_QUERYFULLNAME, (PBYTE)buffer, len, 0L)) -#endif - return NULL; - return buffer; -} - -DIR * -openxdir(const char *path, unsigned att_mask) -{ - DIR *dir; - char name[MAXPATHLEN+3]; - Word rc; - - dir = malloc(sizeof(DIR)); - if (dir == NULL) { - errno = ENOMEM; - return NULL; - } - - strncpy(name, path, MAXPATHLEN); - name[MAXPATHLEN] = '\0'; - switch (name[strlen(name)-1]) { - default: - strcat(name, "\\"); - case '\\': - case '/': - case ':': - ; - } - strcat(name, "."); - if (!abs_path(name, dir->name, MAXPATHLEN+1)) - strcpy(dir->name, name); - if (dir->name[strlen(dir->name)-1] == '\\') - strcat(dir->name, "*"); - else - strcat(dir->name, "\\*"); - - dir->fstype = getFSType(dir->name); - dir->attrmask = att_mask | A_DIR; - - dir->handle = HDIR_CREATE; - dir->count = 100; -#if OS2 >= 2 - rc = DosFindFirst(dir->name, &dir->handle, dir->attrmask, - dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD); -#else - rc = DosFindFirst((PSZ)dir->name, &dir->handle, dir->attrmask, - (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0); -#endif - switch (rc) { - default: - free(dir); - error(rc); - return NULL; - case NO_ERROR: - case ERROR_NO_MORE_FILES: - ; - } - - dir->number = 0; - dir->index = 0; - dir->next = (FFBUF *)dir->ffbuf; - - return (DIR *)dir; -} - -DIR * -opendir(const char *pathname) -{ - return openxdir(pathname, 0); -} - -struct dirent * -readdir(DIR *dir) -{ - static int dummy_ino = 2; - - if (dir->index == dir->count) { - Word rc; - dir->count = 100; -#if OS2 >= 2 - rc = DosFindNext(dir->handle, dir->ffbuf, - sizeof dir->ffbuf, &dir->count); -#else - rc = DosFindNext(dir->handle, (PFILEFINDBUF)dir->ffbuf, - sizeof dir->ffbuf, &dir->count); -#endif - if (rc) { - error(rc); - return NULL; - } - - dir->index = 0; - dir->next = (FFBUF *)dir->ffbuf; - } - - if (dir->index == dir->count) - return NULL; - - memcpy(dir->entry.d_name, dir->next->achName, dir->next->cchName); - dir->entry.d_name[dir->next->cchName] = '\0'; - dir->entry.d_ino = dummy_ino++; - dir->entry.d_reclen = dir->next->cchName; - dir->entry.d_namlen = dir->next->cchName; - dir->entry.d_size = dir->next->cbFile; - dir->entry.d_attribute = dir->next->attrFile; - dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite; - dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite; - - switch (dir->fstype) { - case 'F': /* FAT */ - case 'C': /* CDFS */ - if (dir->next->attrFile & FILE_DIRECTORY) - strupr(dir->entry.d_name); - else - strlwr(dir->entry.d_name); - } - -#if OS2 >= 2 - dir->next = (FFBUF *)((BYTE *)dir->next + dir->next->oNextEntryOffset); -#else - dir->next = (FFBUF *)((BYTE *)dir->next->achName + dir->next->cchName + 1); -#endif - ++dir->number; - ++dir->index; - - return &dir->entry; -} - -long -telldir(DIR *dir) -{ - return dir->number; -} - -void -seekdir(DIR *dir, long off) -{ - if (dir->number > off) { - char name[MAXPATHLEN+2]; - Word rc; - - DosFindClose(dir->handle); - - strcpy(name, dir->name); - strcat(name, "*"); - - dir->handle = HDIR_CREATE; - dir->count = 32767; -#if OS2 >= 2 - rc = DosFindFirst(name, &dir->handle, dir->attrmask, - dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD); -#else - rc = DosFindFirst((PSZ)name, &dir->handle, dir->attrmask, - (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0); -#endif - switch (rc) { - default: - error(rc); - return; - case NO_ERROR: - case ERROR_NO_MORE_FILES: - ; - } - - dir->number = 0; - dir->index = 0; - dir->next = (FFBUF *)dir->ffbuf; - } - - while (dir->number < off && readdir(dir)) - ; -} - -void -closedir(DIR *dir) -{ - DosFindClose(dir->handle); - free(dir); -} - -/*****************************************************************************/ - -#ifdef TEST - -main(int argc, char **argv) -{ - int i; - DIR *dir; - struct dirent *ep; - - for (i = 1; i < argc; ++i) { - dir = opendir(argv[i]); - if (!dir) - continue; - while (ep = readdir(dir)) - if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1])) - printf("%s%s\n", argv[i], ep->d_name); - else - printf("%s/%s\n", argv[i], ep->d_name); - closedir(dir); - } - - return 0; -} - -#endif - -#endif /* OS2 */ - diff --git a/security/dbm/src/dirent.h b/security/dbm/src/dirent.h deleted file mode 100644 index 07a6c0ac8..000000000 --- a/security/dbm/src/dirent.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef __DIRENT_H__ -#define __DIRENT_H__ -/* - * @(#)msd_dir.h 1.4 87/11/06 Public Domain. - * - * A public domain implementation of BSD directory routines for - * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), - * August 1897 - * - * Extended by Peter Lim (lim@mullian.oz) to overcome some MS DOS quirks - * and returns 2 more pieces of information - file size & attribute. - * Plus a little reshuffling of some #define's positions December 1987 - * - * Some modifications by Martin Junius 02-14-89 - * - * AK900712 - * AK910410 abs_path - make absolute path - * - */ - -#ifdef __EMX__ -#include <sys/param.h> -#else -#if defined(__IBMC__) || defined(__IBMCPP__) || defined(XP_W32_MSVC) -#include <stdio.h> -#ifdef MAXPATHLEN - #undef MAXPATHLEN -#endif -#define MAXPATHLEN (FILENAME_MAX*4) -#define MAXNAMLEN FILENAME_MAX - -#else -#include <param.h> -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* attribute stuff */ -#ifndef A_RONLY -# define A_RONLY 0x01 -# define A_HIDDEN 0x02 -# define A_SYSTEM 0x04 -# define A_LABEL 0x08 -# define A_DIR 0x10 -# define A_ARCHIVE 0x20 -#endif - -struct dirent { -#if defined(OS2) || defined(WIN32) /* use the layout of EMX to avoid trouble */ - int d_ino; /* Dummy */ - int d_reclen; /* Dummy, same as d_namlen */ - int d_namlen; /* length of name */ - char d_name[MAXNAMLEN + 1]; - unsigned long d_size; - unsigned short d_attribute; /* attributes (see above) */ - unsigned short d_time; /* modification time */ - unsigned short d_date; /* modification date */ -#else - char d_name[MAXNAMLEN + 1]; /* garentee null termination */ - char d_attribute; /* .. extension .. */ - unsigned long d_size; /* .. extension .. */ -#endif -}; - -typedef struct _dirdescr DIR; -/* the structs do not have to be defined here */ - -extern DIR *opendir(const char *); -extern DIR *openxdir(const char *, unsigned); -extern struct dirent *readdir(DIR *); -extern void seekdir(DIR *, long); -extern long telldir(DIR *); -extern void closedir(DIR *); -#define rewinddir(dirp) seekdir(dirp, 0L) - -extern char * abs_path(const char *name, char *buffer, int len); - -#ifndef S_IFMT -#define S_IFMT ( S_IFDIR | S_IFREG ) -#endif - -#ifndef S_ISDIR -#define S_ISDIR( m ) (((m) & S_IFMT) == S_IFDIR) -#endif - -#ifndef S_ISREG -#define S_ISREG( m ) (((m) & S_IFMT) == S_IFREG) -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/security/dbm/src/manifest.mn b/security/dbm/src/manifest.mn deleted file mode 100644 index 80f2abfd0..000000000 --- a/security/dbm/src/manifest.mn +++ /dev/null @@ -1,61 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -CORE_DEPTH = ../.. - -VPATH = $(CORE_DEPTH)/../dbm/src - -MODULE = dbm - -# -# memmove.c, snprintf.c, and strerror.c are not in CSRCS because -# the Standard C Library has memmove and strerror and DBM is not -# using snprintf. -# - -CSRCS = db.c \ - h_bigkey.c \ - h_func.c \ - h_log2.c \ - h_page.c \ - hash.c \ - hash_buf.c \ - hsearch.c \ - mktemp.c \ - ndbm.c \ - nsres.c \ - dirent.c \ - $(NULL) - -LIBRARY_NAME = dbm diff --git a/security/dbm/tests/Makefile b/security/dbm/tests/Makefile deleted file mode 100644 index fe132e19c..000000000 --- a/security/dbm/tests/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# -DEPTH = ../.. -CORE_DEPTH = ../.. - -VPATH = $(CORE_DEPTH)/../dbm/tests - -MODULE = dbm - -CSRCS = lots.c - -PROGRAM = lots - -include $(DEPTH)/coreconf/config.mk - -include $(DEPTH)/dbm/config/config.mk - -ifeq (,$(filter-out WIN%,$(OS_TARGET))) -LIBDBM = ../src/$(PLATFORM)/dbm$(STATIC_LIB_SUFFIX) -else -LIBDBM = ../src/$(PLATFORM)/libdbm$(STATIC_LIB_SUFFIX) -endif - -INCLUDES += -I$(CORE_DEPTH)/../dbm/include - -LDFLAGS = $(LDOPTS) $(LIBDBM) - -include $(DEPTH)/coreconf/rules.mk - -lots.pure: lots - purify $(CC) -o lots.pure $(CFLAGS) $(OBJS) $(MYLIBS) - -crash: crash.o $(MYLIBS) - $(CC) -o crash $(CFLAGS) $^ - -crash.pure: crash.o $(MYLIBS) - purify $(CC) -o crash.pure $(CFLAGS) $^ - diff --git a/security/dbm/src/Makefile b/security/nss/cmd/cmdlib/Makefile index 8fce98394..c4f18fb5d 100644 --- a/security/dbm/src/Makefile +++ b/security/nss/cmd/cmdlib/Makefile @@ -1,36 +1,40 @@ #! gmake # -# 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. -# +# ***** 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 Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# +# +# 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 the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. # +# 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). # @@ -48,7 +52,7 @@ include $(CORE_DEPTH)/coreconf/config.mk # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### -include $(CORE_DEPTH)/dbm/config/config.mk + ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # @@ -73,4 +77,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### - 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/fipstest/Makefile b/security/nss/cmd/fipstest/Makefile index 60f791f6c..3b8ea808a 100755 --- a/security/nss/cmd/fipstest/Makefile +++ b/security/nss/cmd/fipstest/Makefile @@ -62,10 +62,9 @@ include $(CORE_DEPTH)/coreconf/config.mk include ../platlibs.mk -#EXTRA_SHARED_LIBS += \ -# -L/usr/lib \ -# -lposix4 \ -# $(NULL) +ifdef NSS_ENABLE_ECC +DEFINES += -DNSS_ENABLE_ECC +endif ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # diff --git a/security/nss/cmd/fipstest/ecdsa.sh b/security/nss/cmd/fipstest/ecdsa.sh new file mode 100644 index 000000000..306c8650f --- /dev/null +++ b/security/nss/cmd/fipstest/ecdsa.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# A Bourne shell script for running the NIST ECDSA Validation System +# +# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment +# variables appropriately so that the fipstest command and the NSPR and NSS +# shared libraries/DLLs are on the search path. Then run this script in the +# directory where the REQUEST (.req) files reside. The script generates the +# RESPONSE (.rsp) files in the same directory. + +request=KeyPair.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdsa keypair $request > $response + +request=PKV.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdsa pkv $request > $response + +request=SigGen.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdsa siggen $request > $response + +request=SigVer.req +response=`echo $request | sed -e "s/req/rsp/"` +echo $request $response +fipstest ecdsa sigver $request > $response diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c index bea7f2e72..c602cbc2d 100644 --- a/security/nss/cmd/fipstest/fipstest.c +++ b/security/nss/cmd/fipstest/fipstest.c @@ -41,298 +41,25 @@ #include "secitem.h" #include "blapi.h" #include "nss.h" +#include "secerr.h" +#include "secoidt.h" +#include "keythi.h" +#include "ec.h" #if 0 #include "../../lib/freebl/mpi/mpi.h" #endif -static const unsigned char -table3[32][8] = { - { 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31 }, - { 0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 }, - { 0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20 }, - { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 }, - { 0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01 }, - { 0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01 }, - { 0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01 }, - { 0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01 }, - { 0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01 }, - { 0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01 }, - { 0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40 }, - { 0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40 }, - { 0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01 }, - { 0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01 }, - { 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01 }, - { 0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20 }, - { 0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01 }, - { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01 }, - { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01 }, - { 0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01 }, - { 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01 }, - { 0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01 }, - { 0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01 }, - { 0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01 }, - { 0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b }, - { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01 }, - { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02 }, - { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08 }, - { 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04 }, - { 0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04 }, - { 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01 }, - { 0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01 } -}; - -static const unsigned char -table4_key[19][8] = { - { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 }, - { 0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e }, - { 0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86 }, - { 0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e }, - { 0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6 }, - { 0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce }, - { 0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6 }, - { 0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe }, - { 0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16 }, - { 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f }, - { 0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46 }, - { 0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e }, - { 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76 }, - { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07 }, - { 0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f }, - { 0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7 }, - { 0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf }, - { 0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6 }, - { 0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef } -}; - -static const unsigned char -table4_inp[19][8] = { - { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 }, - { 0x5c, 0xd5, 0x4c, 0xa8, 0x3d, 0xef, 0x57, 0xda }, - { 0x02, 0x48, 0xd4, 0x38, 0x06, 0xf6, 0x71, 0x72 }, - { 0x51, 0x45, 0x4b, 0x58, 0x2d, 0xdf, 0x44, 0x0a }, - { 0x42, 0xfd, 0x44, 0x30, 0x59, 0x57, 0x7f, 0xa2 }, - { 0x05, 0x9b, 0x5e, 0x08, 0x51, 0xcf, 0x14, 0x3a }, - { 0x07, 0x56, 0xd8, 0xe0, 0x77, 0x47, 0x61, 0xd2 }, - { 0x76, 0x25, 0x14, 0xb8, 0x29, 0xbf, 0x48, 0x6a }, - { 0x3b, 0xdd, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02 }, - { 0x26, 0x95, 0x5f, 0x68, 0x35, 0xaf, 0x60, 0x9a }, - { 0x16, 0x4d, 0x5e, 0x40, 0x4f, 0x27, 0x52, 0x32 }, - { 0x6b, 0x05, 0x6e, 0x18, 0x75, 0x9f, 0x5c, 0xca }, - { 0x00, 0x4b, 0xd6, 0xef, 0x09, 0x17, 0x60, 0x62 }, - { 0x48, 0x0d, 0x39, 0x00, 0x6e, 0xe7, 0x62, 0xf2 }, - { 0x43, 0x75, 0x40, 0xc8, 0x69, 0x8f, 0x3c, 0xfa }, - { 0x07, 0x2d, 0x43, 0xa0, 0x77, 0x07, 0x52, 0x92 }, - { 0x02, 0xfe, 0x55, 0x77, 0x81, 0x17, 0xf1, 0x2a }, - { 0x1d, 0x9d, 0x5c, 0x50, 0x18, 0xf7, 0x28, 0xc2 }, - { 0x30, 0x55, 0x32, 0x28, 0x6d, 0x6f, 0x29, 0x5a } -}; +#ifdef NSS_ENABLE_ECC +extern SECStatus +EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); +#endif -static const unsigned char -des_ecb_enc_sample_key[8] = { 0x97, 0xae, 0x43, 0x08, 0xb6, 0xa8, 0x7a, 0x08 }; -static const unsigned char -des_ecb_enc_sample_inp[8] = { 0xcf, 0xcd, 0x91, 0xf1, 0xb3, 0x40, 0xc9, 0x91 }; - -static const unsigned char -des_ecb_dec_sample_key[8] = { 0x0b, 0x8c, 0x38, 0xef, 0x52, 0x01, 0xda, 0x13 }; -static const unsigned char -des_ecb_dec_sample_inp[8] = { 0x58, 0x0b, 0x39, 0x57, 0x3d, 0x9b, 0x8d, 0xdf }; - -static const unsigned char -des_cbc_enc_sample_key[8] = { 0x58, 0x62, 0xd3, 0xf8, 0x04, 0xe9, 0xb3, 0x98 }; -static const unsigned char -des_cbc_enc_sample_iv[8] = { 0xac, 0xcf, 0x45, 0x4c, 0x1a, 0x28, 0x68, 0xcf }; -static const unsigned char -des_cbc_enc_sample_inp[8] = { 0xf1, 0x55, 0x47, 0x63, 0x76, 0x0e, 0x43, 0xa9 }; - -static const unsigned char -des_cbc_dec_sample_key[8] = { 0x64, 0x6d, 0x02, 0x75, 0xe9, 0x34, 0xe6, 0x7a }; -static const unsigned char -des_cbc_dec_sample_iv[8] = { 0xb4, 0x32, 0xa3, 0x8c, 0xd5, 0xe3, 0x20, 0x1a }; -static const unsigned char -des_cbc_dec_sample_inp[8] = { 0x5a, 0xfe, 0xe8, 0xf2, 0xf6, 0x63, 0x4f, 0xb6 }; - -static const unsigned char -tdea_ecb_enc_sample_key[24] = { - 0x0b, 0x62, 0x7f, 0x67, 0xea, 0xda, 0x0b, 0x34, - 0x08, 0x07, 0x3b, 0xc8, 0x8c, 0x23, 0x1a, 0xb6, - 0x75, 0x0b, 0x9e, 0x57, 0x83, 0xf4, 0xe6, 0xa4 }; -static const unsigned char -tdea_ecb_enc_sample_inp[8] = { 0x44, 0x15, 0x7a, 0xb0, 0x0a, 0x78, 0x6d, 0xbf }; - -static const unsigned char -tdea_ecb_dec_sample_key[24] = { - 0x91, 0xe5, 0x07, 0xba, 0x01, 0x01, 0xb6, 0xdc, - 0x0e, 0x51, 0xf1, 0xd0, 0x25, 0xc2, 0xc2, 0x1c, - 0x1f, 0x54, 0x2f, 0xa1, 0xf8, 0xce, 0xda, 0x89 }; -static const unsigned char -tdea_ecb_dec_sample_inp[8] = { 0x66, 0xe8, 0x72, 0x0d, 0x42, 0x85, 0x4b, 0xba }; - -static const unsigned char -tdea_cbc_enc_sample_key[24] = { - 0xd5, 0xe5, 0x61, 0x61, 0xb0, 0xc4, 0xa4, 0x25, - 0x45, 0x1a, 0x15, 0x67, 0xa4, 0x89, 0x6b, 0xc4, - 0x3b, 0x54, 0x1a, 0x4c, 0x1a, 0xb5, 0x49, 0x0d }; -static const unsigned char -tdea_cbc_enc_sample_iv[8] = { 0x5a, 0xb2, 0xa7, 0x3e, 0xc4, 0x3c, 0xe7, 0x1e }; -static const unsigned char -tdea_cbc_enc_sample_inp[8] = { 0x9e, 0x76, 0x87, 0x7c, 0x54, 0x14, 0xab, 0x50 }; - -static const unsigned char -tdea_cbc_dec_sample_key[24] = { - 0xf8, 0x25, 0xcd, 0x02, 0xc7, 0x76, 0xe6, 0xce, - 0x9e, 0x16, 0xe6, 0x40, 0x7f, 0xcd, 0x01, 0x80, - 0x5b, 0x38, 0xc4, 0xe0, 0xb5, 0x6e, 0x94, 0x61 }; -static const unsigned char -tdea_cbc_dec_sample_iv[8] = { 0x74, 0x3e, 0xdc, 0xc2, 0xc6, 0xc4, 0x18, 0xe3 }; -static const unsigned char -tdea_cbc_dec_sample_inp[8] = { 0xbe, 0x47, 0xd1, 0x77, 0xa5, 0xe8, 0x29, 0xfb }; - - -static const unsigned char -des_ecb_enc_key[8] = { 0x49, 0x45, 0xd9, 0x3d, 0x83, 0xcd, 0x61, 0x9b }; -static const unsigned char -des_ecb_enc_inp[8] = { 0x81, 0xf2, 0x12, 0x0d, 0x99, 0x04, 0x5d, 0x16 }; - -static const unsigned char -des_ecb_dec_key[8] = { 0x7a, 0x6b, 0x61, 0x76, 0xc8, 0x85, 0x43, 0x31 }; -static const unsigned char -des_ecb_dec_inp[8] = { 0xef, 0xe4, 0x6e, 0x4f, 0x4f, 0xc3, 0x28, 0xcc }; - -static const unsigned char -des_cbc_enc_key[8] = { 0xc8, 0x5e, 0xfd, 0xa7, 0xa7, 0xc2, 0xc4, 0x0d }; -static const unsigned char -des_cbc_enc_iv[8] = { 0x4c, 0xb9, 0xcf, 0x46, 0xff, 0x7a, 0x3d, 0xff }; -static const unsigned char -des_cbc_enc_inp[8] = { 0x80, 0x1b, 0x24, 0x9b, 0x24, 0x0e, 0xa5, 0x96 }; - -static const unsigned char -des_cbc_dec_key[8] = { 0x2c, 0x3d, 0xa1, 0x67, 0x4c, 0xfb, 0x85, 0x23 }; -static const unsigned char -des_cbc_dec_iv[8] = { 0x7a, 0x0a, 0xc2, 0x15, 0x1d, 0x22, 0x98, 0x3a }; -static const unsigned char -des_cbc_dec_inp[8] = { 0x2d, 0x5d, 0x02, 0x04, 0x98, 0x5d, 0x5e, 0x28 }; - -static const unsigned char -tdea1_ecb_enc_key[24] = { - 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4, - 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4, - 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4 }; - -static const unsigned char -tdea1_ecb_enc_inp[8] = { 0xe5, 0x8c, 0x48, 0xf0, 0x91, 0x4e, 0xeb, 0x87 }; - -static const unsigned char -tdea1_ecb_dec_key[24] = { - 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37, - 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37, - 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37 }; - -static const unsigned char -tdea1_ecb_dec_inp[8] = { 0x35, 0x7a, 0x6c, 0x05, 0xe0, 0x8c, 0x3d, 0xb7 }; - -static const unsigned char -tdea1_cbc_enc_key[24] = { - 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94, - 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94, - 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94 }; - - -static const unsigned char -tdea1_cbc_enc_iv[8] = { 0xf7, 0x3e, 0x14, 0x05, 0x88, 0xeb, 0x2e, 0x96 }; -static const unsigned char -tdea1_cbc_enc_inp[8] = { 0x18, 0x1b, 0xdf, 0x18, 0x10, 0xb2, 0xe0, 0x05 }; - -static const unsigned char -tdea1_cbc_dec_key[24] = { - 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c, - 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c, - 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c }; - - -static const unsigned char -tdea1_cbc_dec_iv[8] = { 0xb9, 0x65, 0x4a, 0x94, 0xba, 0x6a, 0x66, 0xf9 }; -static const unsigned char -tdea1_cbc_dec_inp[8] = { 0xce, 0xb8, 0x30, 0x95, 0xac, 0x82, 0xdf, 0x9b }; - -static const unsigned char -tdea2_ecb_enc_key[24] = { - 0x79, 0x98, 0x4a, 0xe9, 0x23, 0xad, 0x10, 0xda, - 0x16, 0x3e, 0xb5, 0xfe, 0xcd, 0x52, 0x20, 0x01, - 0x79, 0x98, 0x4a, 0xe9, 0x23, 0xad, 0x10, 0xda }; -static const unsigned char -tdea2_ecb_enc_inp[8] = { 0x99, 0xd2, 0xca, 0xe8, 0xa7, 0x90, 0x13, 0xc2 }; - -static const unsigned char -tdea2_ecb_dec_key[24] = { - 0x98, 0xcd, 0x29, 0x52, 0x85, 0x91, 0x75, 0xe3, - 0xab, 0x29, 0xe3, 0x10, 0xa2, 0x10, 0x04, 0x58, - 0x98, 0xcd, 0x29, 0x52, 0x85, 0x91, 0x75, 0xe3 }; - -static const unsigned char -tdea2_ecb_dec_inp[8] = { 0xc0, 0x35, 0x24, 0x1f, 0xc9, 0x29, 0x5c, 0x7a }; - -static const unsigned char -tdea2_cbc_enc_key[24] = { - 0xba, 0x5d, 0x70, 0xf8, 0x08, 0x13, 0xb0, 0x4c, - 0xf8, 0x46, 0xa8, 0xce, 0xe6, 0xb3, 0x08, 0x02, - 0xba, 0x5d, 0x70, 0xf8, 0x08, 0x13, 0xb0, 0x4c }; - - -static const unsigned char -tdea2_cbc_enc_iv[8] = { 0xe8, 0x39, 0xd7, 0x3a, 0x8d, 0x8c, 0x59, 0x8a }; -static const unsigned char -tdea2_cbc_enc_inp[8] = { 0x6e, 0x85, 0x0a, 0x4c, 0x86, 0x86, 0x70, 0x23 }; - -static const unsigned char -tdea2_cbc_dec_key[24] = { - 0x25, 0xf8, 0x9e, 0x7a, 0xef, 0x26, 0xb5, 0x9e, - 0x46, 0x32, 0x19, 0x9b, 0xea, 0x1c, 0x19, 0xad, - 0x25, 0xf8, 0x9e, 0x7a, 0xef, 0x26, 0xb5, 0x9e }; - - -static const unsigned char -tdea2_cbc_dec_iv[8] = { 0x48, 0x07, 0x6f, 0xf9, 0x05, 0x14, 0xc1, 0xdc }; -static const unsigned char -tdea2_cbc_dec_inp[8] = { 0x9e, 0xf4, 0x10, 0x55, 0xe8, 0x7e, 0x7e, 0x25 }; - -static const unsigned char -tdea3_ecb_enc_key[24] = { - 0x6d, 0x37, 0x16, 0x31, 0x6e, 0x02, 0x83, 0xb6, - 0xf7, 0x16, 0xa2, 0x64, 0x57, 0x8c, 0xae, 0x34, - 0xd0, 0xce, 0x38, 0xb6, 0x31, 0x5e, 0xae, 0x1a }; -static const unsigned char -tdea3_ecb_enc_inp[8] = { 0x28, 0x8a, 0x45, 0x22, 0x53, 0x95, 0xba, 0x3c }; - -static const unsigned char -tdea3_ecb_dec_key[24] = { - 0xb0, 0x75, 0x92, 0x2c, 0xfd, 0x67, 0x8a, 0x26, - 0xc8, 0xba, 0xad, 0x68, 0xb6, 0xba, 0x92, 0x49, - 0xe3, 0x2c, 0xec, 0x83, 0x34, 0xe6, 0xda, 0x98 }; -static const unsigned char -tdea3_ecb_dec_inp[8] = { 0x03, 0xcc, 0xe6, 0x65, 0xf6, 0xc5, 0xc3, 0xba }; - -static const unsigned char -tdea3_cbc_enc_key[24] = { - 0x01, 0x32, 0x73, 0xe9, 0xcb, 0x8a, 0x89, 0x80, - 0x02, 0x7a, 0xc1, 0x5d, 0xf4, 0xd5, 0x6b, 0x76, - 0x2f, 0xef, 0xfd, 0x58, 0x57, 0x1a, 0xce, 0x29 }; -static const unsigned char -tdea3_cbc_enc_iv[8] = { 0x93, 0x98, 0x7c, 0x66, 0x98, 0x21, 0x5b, 0x9e }; -static const unsigned char -tdea3_cbc_enc_inp[8] = { 0x16, 0x54, 0x09, 0xd2, 0x2c, 0xad, 0x6d, 0x99 }; - -static const unsigned char -tdea3_cbc_dec_key[24] = { - 0x57, 0x70, 0x3b, 0x4f, 0xae, 0xe6, 0x9d, 0x0e, - 0x4c, 0x3b, 0x23, 0xcd, 0x54, 0x20, 0xbc, 0x58, - 0x3b, 0x8a, 0x4a, 0xf1, 0x73, 0xf8, 0xf8, 0x38 }; -static const unsigned char -tdea3_cbc_dec_iv[8] = { 0x5f, 0x62, 0xe4, 0xea, 0xa7, 0xb2, 0xb5, 0x70 }; -static const unsigned char -tdea3_cbc_dec_inp[8] = { 0x44, 0xb3, 0xe6, 0x3b, 0x1f, 0xbb, 0x43, 0x02 }; +#define ENCRYPT 1 +#define DECRYPT 0 +#define BYTE unsigned char SECStatus -hex_from_2char(unsigned char *c2, unsigned char *byteval) +hex_from_2char(const unsigned char *c2, unsigned char *byteval) { int i; unsigned char offset; @@ -381,463 +108,778 @@ to_hex_str(char *str, const unsigned char *buf, unsigned int len) } void -to_hex_str_cap(char *str, unsigned char *buf, unsigned int len) +to_hex_str_cap(char *str, const unsigned char *buf, unsigned int len) { unsigned int i; for (i=0; i<len; i++) { char2_from_hex(buf[i], &str[2*i], 'A'); } + str[2*len] = '\0'; } -void -des_var_pt_kat(int mode, PRBool encrypt, unsigned int len, - unsigned char *key, unsigned char *iv, - unsigned char *inp) +/* + * Convert a string of hex digits (str) to an array (buf) of len bytes. + * Return PR_TRUE if the hex string can fit in the byte array. Return + * PR_FALSE if the hex string is empty or is too long. + */ +PRBool +from_hex_str(unsigned char *buf, unsigned int len, const char *str) { - int i; - unsigned int olen, mbnum = 0; - unsigned char mod_byte = 0x80; - unsigned char in[8]; - unsigned char out[8]; - char keystr[17], ivstr[17], instr[17], outstr[17]; - char *ptty = (len == 8) ? "PT" : "PLAINTEXT"; - char *ctty = (len == 8) ? "CT" : "CIPHERTEXT"; - char tchar = (len == 8) ? '\t' : '\n'; - DESContext *cx1 = NULL, *cx2 = NULL; - memset(in, 0, sizeof in); - memset(keystr, 0, sizeof keystr); - memset(ivstr, 0, sizeof ivstr); - memset(instr, 0, sizeof instr); - memset(outstr, 0, sizeof outstr); - in[mbnum] = mod_byte; - for (i=1; i<=64; i++) { - cx1 = DES_CreateContext(key, iv, mode, PR_TRUE); - if (!encrypt) { - cx2 = DES_CreateContext(key, iv, mode, PR_FALSE); - } - if (len > 8) { - printf("COUNT = %d\n", i); - to_hex_str(keystr, key, 8); - printf("KEY1=%s\n", keystr); - to_hex_str(keystr, key+8, 8); - printf("KEY2=%s\n", keystr); - to_hex_str(keystr, key+16, 8); - printf("KEY3=%s\n", keystr); - } else { - to_hex_str(keystr, key, 8); - printf("%ld\tKEY=%s\t", i, keystr); - } - if (iv) { - to_hex_str(ivstr, iv, 8); - printf("IV=%s%c", ivstr, tchar); - } - DES_Encrypt(cx1, out, &olen, 8, in, 8); - if (encrypt) { - to_hex_str(instr, in, 8); - to_hex_str(outstr, out, 8); - printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr); - } else { - unsigned char inv[8]; - DES_Decrypt(cx2, inv, &olen, 8, out, 8); - to_hex_str(instr, out, 8); - to_hex_str(outstr, inv, 8); - printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr); + unsigned int nxdigit; /* number of hex digits in str */ + unsigned int i; /* index into buf */ + unsigned int j; /* index into str */ + + /* count the hex digits */ + nxdigit = 0; + for (nxdigit = 0; isxdigit(str[nxdigit]); nxdigit++) { + /* empty body */ + } + if (nxdigit == 0) { + return PR_FALSE; + } + if (nxdigit > 2*len) { + /* + * The input hex string is too long, but we allow it if the + * extra digits are leading 0's. + */ + for (j = 0; j < nxdigit-2*len; j++) { + if (str[j] != '0') { + return PR_FALSE; + } } - if (mod_byte > 0x01) { - mod_byte >>= 1; + /* skip leading 0's */ + str += nxdigit-2*len; + nxdigit = 2*len; + } + for (i=0, j=0; i< len; i++) { + if (2*i < 2*len-nxdigit) { + /* Handle a short input as if we padded it with leading 0's. */ + if (2*i+1 < 2*len-nxdigit) { + buf[i] = 0; + } else { + char tmp[2]; + tmp[0] = '0'; + tmp[1] = str[j]; + hex_from_2char(tmp, &buf[i]); + j++; + } } else { - in[mbnum] = 0x00; - mod_byte = 0x80; - mbnum++; - } - in[mbnum] = mod_byte; - DES_DestroyContext(cx1, PR_TRUE); - if (cx2) { - DES_DestroyContext(cx2, PR_TRUE); + hex_from_2char(&str[j], &buf[i]); + j += 2; } } + return PR_TRUE; } -void -des_inv_perm_kat(int mode, PRBool encrypt, unsigned int len, - unsigned char *key, unsigned char *iv, - unsigned char *inp) +SECStatus +tdea_encrypt_buf( + int mode, + const unsigned char *key, + const unsigned char *iv, + unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen, + const unsigned char *input, unsigned int inputlen) { - int i; - unsigned int olen, mbnum = 0; - unsigned char mod_byte = 0x80; - unsigned char in[8]; - unsigned char out[8]; - char keystr[17], ivstr[17], instr[17], outstr[17]; - char *ptty = (len == 8) ? "PT" : "PLAINTEXT"; - char *ctty = (len == 8) ? "CT" : "CIPHERTEXT"; - char tchar = (len == 8) ? '\t' : '\n'; - DESContext *cx1 = NULL, *cx2 = NULL; - memset(in, 0, sizeof in); - memset(keystr, 0, sizeof keystr); - memset(ivstr, 0, sizeof ivstr); - memset(instr, 0, sizeof instr); - memset(outstr, 0, sizeof outstr); - in[mbnum] = mod_byte; - for (i=1; i<=64; i++) { - if (encrypt) { - cx1 = DES_CreateContext(key, iv, mode, PR_TRUE); - cx2 = DES_CreateContext(key, iv, mode, PR_TRUE); - } else { - cx1 = DES_CreateContext(key, iv, mode, PR_FALSE); - } - if (len > 8) { - printf("COUNT = %d\n", i); - to_hex_str(keystr, key, 8); - printf("KEY1=%s\n", keystr); - to_hex_str(keystr, key+8, 8); - printf("KEY2=%s\n", keystr); - to_hex_str(keystr, key+16, 8); - printf("KEY3=%s\n", keystr); - } else { - to_hex_str(keystr, key, 8); - printf("%ld\tKEY=%s\t", i, keystr); - } - if (iv) { - to_hex_str(ivstr, iv, 8); - printf("IV=%s%c", ivstr, tchar); - } - if (encrypt) { - unsigned char inv[8]; - DES_Encrypt(cx1, out, &olen, 8, in, 8); - DES_Encrypt(cx2, inv, &olen, 8, out, 8); - to_hex_str(instr, out, 8); - to_hex_str(outstr, inv, 8); - printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr); - } else { - DES_Decrypt(cx1, out, &olen, 8, in, 8); - to_hex_str(instr, in, 8); - to_hex_str(outstr, out, 8); - printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr); - } - if (mod_byte > 0x01) { - mod_byte >>= 1; - } else { - in[mbnum] = 0x00; - mod_byte = 0x80; - mbnum++; - } - in[mbnum] = mod_byte; - DES_DestroyContext(cx1, PR_TRUE); - if (cx2) { - DES_DestroyContext(cx2, PR_TRUE); - } + SECStatus rv = SECFailure; + DESContext *cx; + unsigned char doublecheck[8*20]; /* 1 to 20 blocks */ + unsigned int doublechecklen = 0; + + cx = DES_CreateContext(key, iv, mode, PR_TRUE); + if (cx == NULL) { + goto loser; + } + rv = DES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen); + if (rv != SECSuccess) { + goto loser; + } + if (*outputlen != inputlen) { + goto loser; + } + DES_DestroyContext(cx, PR_TRUE); + cx = NULL; + + /* + * Doublecheck our result by decrypting the ciphertext and + * compare the output with the input plaintext. + */ + cx = DES_CreateContext(key, iv, mode, PR_FALSE); + if (cx == NULL) { + goto loser; + } + rv = DES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck, + output, *outputlen); + if (rv != SECSuccess) { + goto loser; + } + if (doublechecklen != *outputlen) { + goto loser; + } + DES_DestroyContext(cx, PR_TRUE); + cx = NULL; + if (memcmp(doublecheck, input, inputlen) != 0) { + goto loser; + } + rv = SECSuccess; + +loser: + if (cx != NULL) { + DES_DestroyContext(cx, PR_TRUE); } + return rv; } -void -des_var_key_kat(int mode, PRBool encrypt, unsigned int len, - unsigned char *key, unsigned char *iv, - unsigned char *inp) +SECStatus +tdea_decrypt_buf( + int mode, + const unsigned char *key, + const unsigned char *iv, + unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen, + const unsigned char *input, unsigned int inputlen) { - int i; - unsigned int olen, mbnum = 0; - unsigned char mod_byte = 0x80; - unsigned char keyin[24]; - unsigned char out[8]; - char keystr[17], ivstr[17], instr[17], outstr[17]; - char *ptty = (len == 8) ? "PT" : "PLAINTEXT"; - char *ctty = (len == 8) ? "CT" : "CIPHERTEXT"; - char tchar = (len == 8) ? '\t' : '\n'; - DESContext *cx1 = NULL, *cx2 = NULL; - memset(keyin, 1, sizeof keyin); - memset(keystr, 0, sizeof keystr); - memset(ivstr, 0, sizeof ivstr); - memset(instr, 0, sizeof instr); - memset(outstr, 0, sizeof outstr); - keyin[mbnum] = mod_byte; - keyin[mbnum+8] = mod_byte; - keyin[mbnum+16] = mod_byte; - for (i=1; i<=56; i++) { - cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE); - if (!encrypt) { - cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE); - } - if (len > 8) { - printf("COUNT = %d\n", i); - to_hex_str(keystr, keyin, 8); - printf("KEY1=%s\n", keystr); - to_hex_str(keystr, keyin+8, 8); - printf("KEY2=%s\n", keystr); - to_hex_str(keystr, keyin+16, 8); - printf("KEY3=%s\n", keystr); - } else { - to_hex_str(keystr, keyin, 8); - printf("%ld\tKEY=%s\t", i, keystr); - } - if (iv) { - to_hex_str(ivstr, iv, 8); - printf("IV=%s%c", ivstr, tchar); - } - DES_Encrypt(cx1, out, &olen, 8, inp, 8); - if (encrypt) { - to_hex_str(instr, inp, 8); - to_hex_str(outstr, out, 8); - printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr); - } else { - unsigned char inv[8]; - DES_Decrypt(cx2, inv, &olen, 8, out, 8); - to_hex_str(instr, out, 8); - to_hex_str(outstr, inv, 8); - printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr); - } - if (mod_byte > 0x02) { - mod_byte >>= 1; - } else { - keyin[mbnum] = 0x01; - keyin[mbnum+8] = 0x01; - keyin[mbnum+16] = 0x01; - mod_byte = 0x80; - mbnum++; - } - keyin[mbnum] = mod_byte; - keyin[mbnum+8] = mod_byte; - keyin[mbnum+16] = mod_byte; - DES_DestroyContext(cx1, PR_TRUE); - if (cx2) { - DES_DestroyContext(cx2, PR_TRUE); - } + SECStatus rv = SECFailure; + DESContext *cx; + unsigned char doublecheck[8*20]; /* 1 to 20 blocks */ + unsigned int doublechecklen = 0; + + cx = DES_CreateContext(key, iv, mode, PR_FALSE); + if (cx == NULL) { + goto loser; + } + rv = DES_Decrypt(cx, output, outputlen, maxoutputlen, + input, inputlen); + if (rv != SECSuccess) { + goto loser; + } + if (*outputlen != inputlen) { + goto loser; + } + DES_DestroyContext(cx, PR_TRUE); + cx = NULL; + + /* + * Doublecheck our result by encrypting the plaintext and + * compare the output with the input ciphertext. + */ + cx = DES_CreateContext(key, iv, mode, PR_TRUE); + if (cx == NULL) { + goto loser; } + rv = DES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck, + output, *outputlen); + if (rv != SECSuccess) { + goto loser; + } + if (doublechecklen != *outputlen) { + goto loser; + } + DES_DestroyContext(cx, PR_TRUE); + cx = NULL; + if (memcmp(doublecheck, input, inputlen) != 0) { + goto loser; + } + rv = SECSuccess; + +loser: + if (cx != NULL) { + DES_DestroyContext(cx, PR_TRUE); + } + return rv; } +/* + * Perform the TDEA Known Answer Test (KAT) or Multi-block Message + * Test (MMT) in ECB or CBC mode. The KAT (there are five types) + * and MMT have the same structure: given the key and IV (CBC mode + * only), encrypt the given plaintext or decrypt the given ciphertext. + * So we can handle them the same way. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ void -des_perm_op_kat(int mode, PRBool encrypt, unsigned int len, - unsigned char *key, unsigned char *iv, - unsigned char *inp) +tdea_kat_mmt(char *reqfn) { - int i; - unsigned int olen; - unsigned char keyin[24]; - unsigned char out[8]; - char keystr[17], ivstr[17], instr[17], outstr[17]; - char *ptty = (len == 8) ? "PT" : "PLAINTEXT"; - char *ctty = (len == 8) ? "CT" : "CIPHERTEXT"; - char tchar = (len == 8) ? '\t' : '\n'; - DESContext *cx1 = NULL, *cx2 = NULL; - memset(keyin, 0, sizeof keyin); - memset(keystr, 0, sizeof keystr); - memset(ivstr, 0, sizeof ivstr); - memset(instr, 0, sizeof instr); - memset(outstr, 0, sizeof outstr); - for (i=0; i<32; i++) { - memcpy(keyin, table3[i], 8); - memcpy(keyin+8, table3[i], 8); - memcpy(keyin+16, table3[i], 8); - cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE); - if (!encrypt) { - cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE); - } - if (len > 8) { - printf("COUNT = %d\n", i); - to_hex_str(keystr, keyin, 8); - printf("KEY1=%s\n", keystr); - to_hex_str(keystr, keyin+8, 8); - printf("KEY2=%s\n", keystr); - to_hex_str(keystr, keyin+16, 8); - printf("KEY3=%s\n", keystr); - } else { - to_hex_str(keystr, keyin, 8); - printf("%ld\tKEY=%s\t", i, keystr); - } - if (iv) { - to_hex_str(ivstr, iv, 8); - printf("IV=%s%c", ivstr, tchar); - } - DES_Encrypt(cx1, out, &olen, 8, inp, 8); - if (encrypt) { - to_hex_str(instr, inp, 8); - to_hex_str(outstr, out, 8); - printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr); - } else { - unsigned char inv[8]; - DES_Decrypt(cx2, inv, &olen, 8, out, 8); - to_hex_str(instr, out, 8); - to_hex_str(outstr, inv, 8); - printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr); - } - DES_DestroyContext(cx1, PR_TRUE); - if (cx2) { - DES_DestroyContext(cx2, PR_TRUE); - } + char buf[180]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "CIPHERTEXT = <180 hex digits>\n". + */ + FILE *req; /* input stream from the REQUEST file */ + FILE *resp; /* output stream to the RESPONSE file */ + int i, j; + int mode; /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */ + int crypt = DECRYPT; /* 1 means encrypt, 0 means decrypt */ + unsigned char key[24]; /* TDEA 3 key bundle */ + unsigned int numKeys = 0; + unsigned char iv[8]; /* for all modes except ECB */ + unsigned char plaintext[8*20]; /* 1 to 20 blocks */ + unsigned int plaintextlen; + unsigned char ciphertext[8*20]; /* 1 to 20 blocks */ + unsigned int ciphertextlen; + SECStatus rv; + + req = fopen(reqfn, "r"); + resp = stdout; + while (fgets(buf, sizeof buf, req) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, resp); + continue; + } + /* [ENCRYPT] or [DECRYPT] */ + if (buf[0] == '[') { + if (strncmp(&buf[1], "ENCRYPT", 7) == 0) { + crypt = ENCRYPT; + } else { + crypt = DECRYPT; + } + fputs(buf, resp); + continue; + } + /* NumKeys */ + if (strncmp(&buf[0], "NumKeys", 7) == 0) { + i = 7; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + numKeys = buf[i]; + fputs(buf, resp); + continue; + } + /* "COUNT = x" begins a new data set */ + if (strncmp(buf, "COUNT", 5) == 0) { + /* mode defaults to ECB, if dataset has IV mode will be set CBC */ + mode = NSS_DES_EDE3; + /* zeroize the variables for the test with this data set */ + memset(key, 0, sizeof key); + memset(iv, 0, sizeof iv); + memset(plaintext, 0, sizeof plaintext); + plaintextlen = 0; + memset(ciphertext, 0, sizeof ciphertext); + ciphertextlen = 0; + fputs(buf, resp); + continue; + } + if (numKeys == 0) { + if (strncmp(buf, "KEYs", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + key[j+8] = key[j]; + key[j+16] = key[j]; + } + fputs(buf, resp); + continue; + } + } else { + /* KEY1 = ... */ + if (strncmp(buf, "KEY1", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + } + fputs(buf, resp); + continue; + } + /* KEY2 = ... */ + if (strncmp(buf, "KEY2", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=8; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + } + fputs(buf, resp); + continue; + } + /* KEY3 = ... */ + if (strncmp(buf, "KEY3", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=16; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + } + fputs(buf, resp); + continue; + } + } + + /* IV = ... */ + if (strncmp(buf, "IV", 2) == 0) { + mode = NSS_DES_EDE3_CBC; + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; j<sizeof iv; i+=2,j++) { + hex_from_2char(&buf[i], &iv[j]); + } + fputs(buf, resp); + continue; + } + + /* PLAINTEXT = ... */ + if (strncmp(buf, "PLAINTEXT", 9) == 0) { + /* sanity check */ + if (crypt != ENCRYPT) { + goto loser; + } + i = 9; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &plaintext[j]); + } + plaintextlen = j; + rv = tdea_encrypt_buf(mode, key, + (mode == NSS_DES_EDE3) ? NULL : iv, + ciphertext, &ciphertextlen, sizeof ciphertext, + plaintext, plaintextlen); + if (rv != SECSuccess) { + goto loser; + } + + fputs(buf, resp); + fputs("CIPHERTEXT = ", resp); + to_hex_str(buf, ciphertext, ciphertextlen); + fputs(buf, resp); + fputc('\n', resp); + continue; + } + /* CIPHERTEXT = ... */ + if (strncmp(buf, "CIPHERTEXT", 10) == 0) { + /* sanity check */ + if (crypt != DECRYPT) { + goto loser; + } + + i = 10; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &ciphertext[j]); + } + ciphertextlen = j; + + rv = tdea_decrypt_buf(mode, key, + (mode == NSS_DES_EDE3) ? NULL : iv, + plaintext, &plaintextlen, sizeof plaintext, + ciphertext, ciphertextlen); + if (rv != SECSuccess) { + goto loser; + } + + fputs(buf, resp); + fputs("PLAINTEXT = ", resp); + to_hex_str(buf, plaintext, plaintextlen); + fputs(buf, resp); + fputc('\n', resp); + continue; + } } + +loser: + fclose(req); } -void -des_sub_tbl_kat(int mode, PRBool encrypt, unsigned int len, - unsigned char *key, unsigned char *iv, - unsigned char *inp) +/* +* Set the parity bit for the given byte +*/ +BYTE odd_parity( BYTE in) { - int i; - unsigned int olen; - unsigned char keyin[24]; - unsigned char out[8]; - char keystr[17], ivstr[17], instr[17], outstr[17]; - char *ptty = (len == 8) ? "PT" : "PLAINTEXT"; - char *ctty = (len == 8) ? "CT" : "CIPHERTEXT"; - char tchar = (len == 8) ? '\t' : '\n'; - DESContext *cx1 = NULL, *cx2 = NULL; - memset(keyin, 0, sizeof keyin); - memset(keystr, 0, sizeof keystr); - memset(ivstr, 0, sizeof ivstr); - memset(instr, 0, sizeof instr); - memset(outstr, 0, sizeof outstr); - for (i=0; i<19; i++) { - memcpy(keyin, table4_key[i], 8); - memcpy(keyin+8, table4_key[i], 8); - memcpy(keyin+16, table4_key[i], 8); - cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE); - if (!encrypt) { - cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE); - } - if (len > 8) { - printf("COUNT = %d\n", i); - to_hex_str(keystr, keyin, 8); - printf("KEY1=%s\n", keystr); - to_hex_str(keystr, keyin+8, 8); - printf("KEY2=%s\n", keystr); - to_hex_str(keystr, keyin+16, 8); - printf("KEY3=%s\n", keystr); - } else { - to_hex_str(keystr, keyin, 8); - printf("%ld\tKEY=%s\t", i, keystr); - } - if (iv) { - to_hex_str(ivstr, iv, 8); - printf("IV=%s%c", ivstr, tchar); - } - DES_Encrypt(cx1, out, &olen, 8, table4_inp[i], 8); - if (encrypt) { - to_hex_str(instr, table4_inp[i], 8); - to_hex_str(outstr, out, 8); - printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr); - } else { - unsigned char inv[8]; - DES_Decrypt(cx2, inv, &olen, 8, out, 8); - to_hex_str(instr, out, 8); - to_hex_str(outstr, inv, 8); - printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr); - } - DES_DestroyContext(cx1, PR_TRUE); - if (cx2) { - DES_DestroyContext(cx2, PR_TRUE); - } - } + BYTE out = in; + in ^= in >> 4; + in ^= in >> 2; + in ^= in >> 1; + return (BYTE)(out ^ !(in & 1)); } -unsigned char make_odd_parity(unsigned char b) +/* + * Generate Keys [i+1] from Key[i], PT/CT[j-2], PT/CT[j-1], and PT/CT[j] + * for TDEA Monte Carlo Test (MCT) in ECB and CBC modes. + */ +void +tdea_mct_next_keys(unsigned char *key, + const unsigned char *text_2, const unsigned char *text_1, + const unsigned char *text, unsigned int numKeys) { - int i; - int sum = 0; - for (i=1; i<8; i++) { - sum += (b & (1 << i)) ? 1 : 0; + int k; + + /* key1[i+1] = key1[i] xor PT/CT[j] */ + for (k=0; k<8; k++) { + key[k] ^= text[k]; + } + /* key2 */ + if (numKeys == 2 || numKeys == 3) { + /* key2 independent */ + for (k=8; k<16; k++) { + /* key2[i+1] = KEY2[i] xor PT/CT[j-1] */ + key[k] ^= text_1[k-8]; + } + } else { + /* key2 == key 1 */ + for (k=8; k<16; k++) { + /* key2[i+1] = KEY2[i] xor PT/CT[j] */ + key[k] = key[k-8]; + } } - if (sum & 0x01) { - return (b & 0xfe); + /* key3 */ + if (numKeys == 1 || numKeys == 2) { + /* key3 == key 1 */ + for (k=16; k<24; k++) { + /* key3[i+1] = KEY3[i] xor PT/CT[j] */ + key[k] = key[k-16]; + } } else { - return (b | 0x01); + /* key3 independent */ + for (k=16; k<24; k++) { + /* key3[i+1] = KEY3[i] xor PT/CT[j-2] */ + key[k] ^= text_2[k-16]; + } + } + /* set the parity bits */ + for (k=0; k<24; k++) { + key[k] = odd_parity(key[k]); + } +} + +/* + * Perform the Monte Carlo Test + * + * mode = NSS_DES_EDE3 or NSS_DES_EDE3_CBC + * crypt = ENCRYPT || DECRYPT + * inputtext = plaintext or Cyphertext depending on the value of crypt + * inputlength is expected to be size 8 bytes + * iv = needs to be set for NSS_DES_EDE3_CBC mode + * resp = is the output response file. + */ + void +tdea_mct_test(int mode, unsigned char* key, unsigned int numKeys, + unsigned int crypt, unsigned char* inputtext, + unsigned int inputlength, unsigned char* iv, FILE *resp) { + + int i, j; + unsigned char outputtext_1[8]; /* PT/CT[j-1] */ + unsigned char outputtext_2[8]; /* PT/CT[j-2] */ + char buf[80]; /* holds one line from the input REQUEST file. */ + unsigned int outputlen; + unsigned char outputtext[8]; + + + SECStatus rv; + + if (mode == NSS_DES_EDE3 && iv != NULL) { + printf("IV must be NULL for NSS_DES_EDE3 mode"); + goto loser; + } else if (mode == NSS_DES_EDE3_CBC && iv == NULL) { + printf("IV must not be NULL for NSS_DES_EDE3_CBC mode"); + goto loser; } + + /* loop 400 times */ + for (i=0; i<400; i++) { + /* if i == 0 CV[0] = IV not necessary */ + /* record the count and key values and plainText */ + sprintf(buf, "COUNT = %d\n", i); + fputs(buf, resp); + /* Output KEY1[i] */ + fputs("KEY1 = ", resp); + to_hex_str(buf, key, 8); + fputs(buf, resp); + fputc('\n', resp); + /* Output KEY2[i] */ + fputs("KEY2 = ", resp); + to_hex_str(buf, &key[8], 8); + fputs(buf, resp); + fputc('\n', resp); + /* Output KEY3[i] */ + fputs("KEY3 = ", resp); + to_hex_str(buf, &key[16], 8); + fputs(buf, resp); + fputc('\n', resp); + if (mode == NSS_DES_EDE3_CBC) { + /* Output CV[i] */ + fputs("IV = ", resp); + to_hex_str(buf, iv, 8); + fputs(buf, resp); + fputc('\n', resp); + } + if (crypt == ENCRYPT) { + /* Output PT[0] */ + fputs("PLAINTEXT = ", resp); + } else { + /* Output CT[0] */ + fputs("CIPHERTEXT = ", resp); + } + + to_hex_str(buf, inputtext, inputlength); + fputs(buf, resp); + fputc('\n', resp); + + /* loop 10,000 times */ + for (j=0; j<10000; j++) { + + outputlen = 0; + if (crypt == ENCRYPT) { + /* inputtext == ciphertext outputtext == plaintext*/ + rv = tdea_encrypt_buf(mode, key, + (mode == NSS_DES_EDE3) ? NULL : iv, + outputtext, &outputlen, 8, + inputtext, 8); + } else { + /* inputtext == plaintext outputtext == ciphertext */ + rv = tdea_decrypt_buf(mode, key, + (mode == NSS_DES_EDE3) ? NULL : iv, + outputtext, &outputlen, 8, + inputtext, 8); + } + + if (rv != SECSuccess) { + goto loser; + } + if (outputlen != inputlength) { + goto loser; + } + + if (mode == NSS_DES_EDE3_CBC) { + if (crypt == ENCRYPT) { + if (j == 0) { + /*P[j+1] = CV[0] */ + memcpy(inputtext, iv, 8); + } else { + /* p[j+1] = C[j-1] */ + memcpy(inputtext, outputtext_1, 8); + } + /* CV[j+1] = C[j] */ + memcpy(iv, outputtext, 8); + if (j != 9999) { + /* save C[j-1] */ + memcpy(outputtext_1, outputtext, 8); + } + } else { /* DECRYPT */ + /* CV[j+1] = C[j] */ + memcpy(iv, inputtext, 8); + /* C[j+1] = P[j] */ + memcpy(inputtext, outputtext, 8); + } + } else { + /* ECB mode PT/CT[j+1] = CT/PT[j] */ + memcpy(inputtext, outputtext, 8); + } + + /* Save PT/CT[j-2] and PT/CT[j-1] */ + if (j==9997) memcpy(outputtext_2, outputtext, 8); + if (j==9998) memcpy(outputtext_1, outputtext, 8); + /* done at the end of the for(j) loop */ + } + + + if (crypt == ENCRYPT) { + /* Output CT[j] */ + fputs("CIPHERTEXT = ", resp); + } else { + /* Output PT[j] */ + fputs("PLAINTEXT = ", resp); + } + to_hex_str(buf, outputtext, 8); + fputs(buf, resp); + fputc('\n', resp); + + /* Key[i+1] = Key[i] xor ... outputtext_2 == PT/CT[j-2] + * outputtext_1 == PT/CT[j-1] outputtext == PT/CT[j] + */ + tdea_mct_next_keys(key, outputtext_2, + outputtext_1, outputtext, numKeys); + + if (mode == NSS_DES_EDE3_CBC) { + /* taken care of in the j=9999 iteration */ + if (crypt == ENCRYPT) { + /* P[i] = C[j-1] */ + /* CV[i] = C[j] */ + } else { + /* taken care of in the j=9999 iteration */ + /* CV[i] = C[j] */ + /* C[i] = P[j] */ + } + } else { + /* ECB PT/CT[i] = PT/CT[j] */ + memcpy(inputtext, outputtext, 8); + } + /* done at the end of the for(i) loop */ + fputc('\n', resp); + } + +loser: + return; } +/* + * Perform the TDEA Monte Carlo Test (MCT) in ECB/CBC modes. + * by gathering the input from the request file, and then + * calling tdea_mct_test. + * + * reqfn is the pathname of the input REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ void -des_modes(int mode, PRBool encrypt, unsigned int len, - const unsigned char *key, const unsigned char *iv, - const unsigned char *inp, int keymode) +tdea_mct(int mode, char *reqfn) { int i, j; - unsigned int olen; - unsigned char keyin[24]; - unsigned char in[8]; - unsigned char cv[8]; - unsigned char cv0[8]; - unsigned char in0[8]; - unsigned char out[8]; - unsigned char cj9998[8], cj9997[8]; - char keystr[17], ivstr[17], instr[17], outstr[17]; - char *ptty = (len == 8) ? "PT" : "PLAINTEXT"; - char *ctty = (len == 8) ? "CT" : "CIPHERTEXT"; - char tchar = (len == 8) ? '\t' : '\n'; - DESContext *cx1 = NULL; - memset(keystr, 0, sizeof keystr); - memset(ivstr, 0, sizeof ivstr); - memset(instr, 0, sizeof instr); - memset(outstr, 0, sizeof outstr); - memcpy(in, inp, 8); - if (iv) memcpy(cv, iv, 8); - memcpy(keyin, key, len); - for (i=0; i<400; i++) { - if (iv) memcpy(cv0, cv, 8); - memcpy(in0, in, 8); - for (j=0; j<10000; j++) { - if (encrypt) { - cx1 = DES_CreateContext(keyin, cv, mode, PR_TRUE); - DES_Encrypt(cx1, out, &olen, 8, in, 8); - } else { - cx1 = DES_CreateContext(keyin, cv, mode, PR_FALSE); - DES_Decrypt(cx1, out, &olen, 8, in, 8); - } - if (j==9997) memcpy(cj9997, out, 8); - if (j==9998) memcpy(cj9998, out, 8); - if (iv) { - if (encrypt) { - memcpy(in, cv, 8); - memcpy(cv, out, 8); - } else { - memcpy(cv, in, 8); - memcpy(in, out, 8); - } - } else { - memcpy(in, out, 8); - } - DES_DestroyContext(cx1, PR_TRUE); - } - if (keymode > 0) { - printf("COUNT = %d\n", i); - to_hex_str(keystr, keyin, 8); - printf("KEY1=%s\n", keystr); - to_hex_str(keystr, keyin+8, 8); - printf("KEY2=%s\n", keystr); - to_hex_str(keystr, keyin+16, 8); - printf("KEY3=%s\n", keystr); - } else { - to_hex_str(keystr, keyin, 8); - printf("%ld\tKEY=%s\t", i, keystr); - } - if (iv) { - to_hex_str(ivstr, cv0, 8); - printf("CV=%s%c", ivstr, tchar); - } - to_hex_str(instr, in0, 8); - to_hex_str(outstr, out, 8); - if (encrypt) { - printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr); - } else { - printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr); - } - for (j=0; j<8; j++) { - keyin[j] ^= out[j]; - keyin[j] = make_odd_parity(keyin[j]); - if (keymode == 0) continue; - if (keymode > 1) { - keyin[j+8] ^= cj9998[j]; - keyin[j+8] = make_odd_parity(keyin[j+8]); - } else { - keyin[j+8] = keyin[j]; - } - if (keymode > 2) { - keyin[j+16] ^= cj9997[j]; - keyin[j+16] = make_odd_parity(keyin[j+16]); - } else { - keyin[j+16] = keyin[j]; - } - } + char buf[80]; /* holds one line from the input REQUEST file. */ + FILE *req; /* input stream from the REQUEST file */ + FILE *resp; /* output stream to the RESPONSE file */ + unsigned int crypt = 0; /* 1 means encrypt, 0 means decrypt */ + unsigned char key[24]; /* TDEA 3 key bundle */ + unsigned int numKeys = 0; + unsigned char plaintext[8]; /* PT[j] */ + unsigned char ciphertext[8]; /* CT[j] */ + unsigned char iv[8]; + + /* zeroize the variables for the test with this data set */ + memset(key, 0, sizeof key); + memset(plaintext, 0, sizeof plaintext); + memset(ciphertext, 0, sizeof ciphertext); + memset(iv, 0, sizeof iv); + + req = fopen(reqfn, "r"); + resp = stdout; + while (fgets(buf, sizeof buf, req) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, resp); + continue; + } + /* [ENCRYPT] or [DECRYPT] */ + if (buf[0] == '[') { + if (strncmp(&buf[1], "ENCRYPT", 7) == 0) { + crypt = ENCRYPT; + } else { + crypt = DECRYPT; + } + fputs(buf, resp); + continue; + } + /* NumKeys */ + if (strncmp(&buf[0], "NumKeys", 7) == 0) { + i = 7; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + numKeys = atoi(&buf[i]); + continue; + } + /* KEY1 = ... */ + if (strncmp(buf, "KEY1", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + } + continue; + } + /* KEY2 = ... */ + if (strncmp(buf, "KEY2", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=8; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + } + continue; + } + /* KEY3 = ... */ + if (strncmp(buf, "KEY3", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=16; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + } + continue; + } + + /* IV = ... */ + if (strncmp(buf, "IV", 2) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; j<sizeof iv; i+=2,j++) { + hex_from_2char(&buf[i], &iv[j]); + } + continue; + } + + /* PLAINTEXT = ... */ + if (strncmp(buf, "PLAINTEXT", 9) == 0) { + + /* sanity check */ + if (crypt != ENCRYPT) { + goto loser; + } + /* PT[0] = PT */ + i = 9; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; j<sizeof plaintext; i+=2,j++) { + hex_from_2char(&buf[i], &plaintext[j]); + } + + /* do the Monte Carlo test */ + if (mode==NSS_DES_EDE3) { + tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, plaintext, sizeof plaintext, NULL, resp); + } else { + tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, plaintext, sizeof plaintext, iv, resp); + } + continue; + } + /* CIPHERTEXT = ... */ + if (strncmp(buf, "CIPHERTEXT", 10) == 0) { + /* sanity check */ + if (crypt != DECRYPT) { + goto loser; + } + /* CT[0] = CT */ + i = 10; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &ciphertext[j]); + } + + /* do the Monte Carlo test */ + if (mode==NSS_DES_EDE3) { + tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, ciphertext, sizeof ciphertext, NULL, resp); + } else { + tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, ciphertext, sizeof ciphertext, iv, resp); + } + continue; + } } + +loser: + fclose(req); } + SECStatus aes_encrypt_buf( int mode, @@ -1797,152 +1839,6 @@ void write_compact_string(FILE *out, unsigned char *hash, unsigned int len) fseek(out, 0, SEEK_END); } -void do_shs_type3(FILE *out, unsigned char *M, unsigned int len) -{ - int i, j, a; - unsigned char zero[30]; - unsigned char iword[4]; - unsigned int l = len; - char hashstr[41]; - SHA1Context *cx; - memset(zero, 0, sizeof zero); - for (j=0; j<100; j++) { - cx = SHA1_NewContext(); - for (i=1; i<=50000; i++) { - SHA1_Begin(cx); - SHA1_Update(cx, M, l); - a = j/4 + 3; - SHA1_Update(cx, zero, a); - iword[3] = (char)i; - iword[2] = (char)(i >> 8); - iword[1] = (char)(i >> 16); - iword[0] = (char)(i >> 24); - SHA1_Update(cx, iword, 4); - SHA1_End(cx, M, &l, 20); - } - SHA1_DestroyContext(cx, PR_TRUE); - to_hex_str_cap(hashstr, M, l); - hashstr[40] = '\0'; - fprintf(out, "%s ^", hashstr); - if (j<99) fprintf(out, "\n"); - } -} - -void -shs_test(char *reqfn) -{ - char buf[80]; - FILE *shareq, *sharesp; - char readbuf[64]; - int i, nr; - int newline, skip, r_z, r_b, r_n, r, b, z, n, reading; - unsigned char hash[20]; - char hashstr[41]; - unsigned char input[13000]; - int next_bit = 0; - int shs_type = 0; - shareq = fopen(reqfn, "r"); - sharesp = stdout; - newline = 1; - reading = skip = r_z = r_b = r_n = z = r = n = 0; - while ((nr = fread(buf, 1, sizeof buf, shareq)) > 0) { - for (i=0; i<nr; i++) { - if (newline) { - if (buf[i] == '#' || buf[i] == 'D' || buf[i] == '<') { - skip = 1; - } else if (buf[i] == 'H') { - skip = 0; - shs_type++; - fprintf(sharesp, "H>SHS Type %d Hashes<H", shs_type); - } else if (isdigit(buf[i])) { - r_z = 1; - readbuf[r++] = buf[i]; - } - newline = (buf[i] == '\n') ? 1 : 0; - } else { - if (buf[i] == '\n' && !r_n) { - skip = r_z = r_n = 0; - newline = 1; - } else if (r_z) { - if (buf[i] == ' ') { - r_z = 0; - readbuf[r] = '\0'; - z = atoi(readbuf); - r_b = 1; - r = 0; - } else if (isdigit(buf[i])) { - readbuf[r++] = buf[i]; - } - } else if (r_b) { - if (buf[i] == ' ') { - r_b = 0; - readbuf[r] = '\0'; - b = atoi(readbuf); - r_n = 1; - r = 0; - } else if (isdigit(buf[i])) { - readbuf[r++] = buf[i]; - } - } else if (r_n) { - if (buf[i] == ' ') { - readbuf[r++] = '\0'; - n = atoi(readbuf); - if (b == 0) { - next_bit += n; - b = 1; - } else { - int next_byte = next_bit / 8; - int shift = next_bit % 8; - unsigned char m = 0xff; - if (n < 8 - shift) { - m <<= (8 - n); - m >>= shift; - input[next_byte] |= m; - next_bit += n; - } else { - m >>= shift; - input[next_byte++] |= m; - next_bit += 8 - shift; - n -= (8 - shift); - while (n > 8) { - m = 0xff; - input[next_byte++] |= m; - next_bit += 8; - n -= 8; - } - if (n > 0) { - m = 0xff << (8 - n); - input[next_byte] |= m; - next_bit += n; - } - } - b = 0; - } - r = 0; - } else if (buf[i] == '^') { - r_n = 0; - if (shs_type < 3) { - SHA1_HashBuf(hash, input, next_bit/8); - to_hex_str_cap(hashstr, hash, sizeof hash); - hashstr[40] = '\0'; - fprintf(sharesp, "%s ^", hashstr); - memset(input, 0, sizeof input); - next_bit = 0; - } else { - do_shs_type3(sharesp, input, next_bit/8); - } - } else if (isdigit(buf[i])) { - readbuf[r++] = buf[i]; - } - } - } - if (skip || newline) { - fprintf(sharesp, "%c", buf[i]); - } - } - } -} - int get_next_line(FILE *req, char *key, char *val, FILE *rsp) { int ignore = 0; @@ -2331,6 +2227,686 @@ do_sigver: fclose(rsp); } +#ifdef NSS_ENABLE_ECC +typedef struct curveNameTagPairStr { + char *curveName; + SECOidTag curveOidTag; +} CurveNameTagPair; + +#define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1 +/* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */ + +static CurveNameTagPair nameTagPair[] = +{ + { "sect163k1", SEC_OID_SECG_EC_SECT163K1}, + { "nistk163", SEC_OID_SECG_EC_SECT163K1}, + { "sect163r1", SEC_OID_SECG_EC_SECT163R1}, + { "sect163r2", SEC_OID_SECG_EC_SECT163R2}, + { "nistb163", SEC_OID_SECG_EC_SECT163R2}, + { "sect193r1", SEC_OID_SECG_EC_SECT193R1}, + { "sect193r2", SEC_OID_SECG_EC_SECT193R2}, + { "sect233k1", SEC_OID_SECG_EC_SECT233K1}, + { "nistk233", SEC_OID_SECG_EC_SECT233K1}, + { "sect233r1", SEC_OID_SECG_EC_SECT233R1}, + { "nistb233", SEC_OID_SECG_EC_SECT233R1}, + { "sect239k1", SEC_OID_SECG_EC_SECT239K1}, + { "sect283k1", SEC_OID_SECG_EC_SECT283K1}, + { "nistk283", SEC_OID_SECG_EC_SECT283K1}, + { "sect283r1", SEC_OID_SECG_EC_SECT283R1}, + { "nistb283", SEC_OID_SECG_EC_SECT283R1}, + { "sect409k1", SEC_OID_SECG_EC_SECT409K1}, + { "nistk409", SEC_OID_SECG_EC_SECT409K1}, + { "sect409r1", SEC_OID_SECG_EC_SECT409R1}, + { "nistb409", SEC_OID_SECG_EC_SECT409R1}, + { "sect571k1", SEC_OID_SECG_EC_SECT571K1}, + { "nistk571", SEC_OID_SECG_EC_SECT571K1}, + { "sect571r1", SEC_OID_SECG_EC_SECT571R1}, + { "nistb571", SEC_OID_SECG_EC_SECT571R1}, + { "secp160k1", SEC_OID_SECG_EC_SECP160K1}, + { "secp160r1", SEC_OID_SECG_EC_SECP160R1}, + { "secp160r2", SEC_OID_SECG_EC_SECP160R2}, + { "secp192k1", SEC_OID_SECG_EC_SECP192K1}, + { "secp192r1", SEC_OID_SECG_EC_SECP192R1}, + { "nistp192", SEC_OID_SECG_EC_SECP192R1}, + { "secp224k1", SEC_OID_SECG_EC_SECP224K1}, + { "secp224r1", SEC_OID_SECG_EC_SECP224R1}, + { "nistp224", SEC_OID_SECG_EC_SECP224R1}, + { "secp256k1", SEC_OID_SECG_EC_SECP256K1}, + { "secp256r1", SEC_OID_SECG_EC_SECP256R1}, + { "nistp256", SEC_OID_SECG_EC_SECP256R1}, + { "secp384r1", SEC_OID_SECG_EC_SECP384R1}, + { "nistp384", SEC_OID_SECG_EC_SECP384R1}, + { "secp521r1", SEC_OID_SECG_EC_SECP521R1}, + { "nistp521", SEC_OID_SECG_EC_SECP521R1}, + + { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 }, + { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 }, + { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 }, + { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 }, + { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 }, + { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 }, + + { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 }, + { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 }, + { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 }, + { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 }, + { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 }, + { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 }, + { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 }, + { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 }, + { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 }, + { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 }, + { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 }, + { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 }, + { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 }, + { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 }, + { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 }, + { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 }, + { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 }, + { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 }, + { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 }, + { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 }, + + { "secp112r1", SEC_OID_SECG_EC_SECP112R1}, + { "secp112r2", SEC_OID_SECG_EC_SECP112R2}, + { "secp128r1", SEC_OID_SECG_EC_SECP128R1}, + { "secp128r2", SEC_OID_SECG_EC_SECP128R2}, + + { "sect113r1", SEC_OID_SECG_EC_SECT113R1}, + { "sect113r2", SEC_OID_SECG_EC_SECT113R2}, + { "sect131r1", SEC_OID_SECG_EC_SECT131R1}, + { "sect131r2", SEC_OID_SECG_EC_SECT131R2}, +}; + +static SECKEYECParams * +getECParams(const char *curve) +{ + SECKEYECParams *ecparams; + SECOidData *oidData = NULL; + SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */ + int i, numCurves; + + if (curve != NULL) { + numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair); + for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN)); + i++) { + if (PL_strcmp(curve, nameTagPair[i].curveName) == 0) + curveOidTag = nameTagPair[i].curveOidTag; + } + } + + /* Return NULL if curve name is not recognized */ + if ((curveOidTag == SEC_OID_UNKNOWN) || + (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) { + fprintf(stderr, "Unrecognized elliptic curve %s\n", curve); + return NULL; + } + + ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len)); + + /* + * ecparams->data needs to contain the ASN encoding of an object ID (OID) + * representing the named curve. The actual OID is in + * oidData->oid.data so we simply prepend 0x06 and OID length + */ + ecparams->data[0] = SEC_ASN1_OBJECT_ID; + ecparams->data[1] = oidData->oid.len; + memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len); + + return ecparams; +} + +/* + * Perform the ECDSA Key Pair Generation Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void +ecdsa_keypair_test(char *reqfn) +{ + char buf[256]; /* holds one line from the input REQUEST file + * or to the output RESPONSE file. + * needs to be large enough to hold the longest + * line "Qx = <144 hex digits>\n". + */ + FILE *ecdsareq; /* input stream from the REQUEST file */ + FILE *ecdsaresp; /* output stream to the RESPONSE file */ + char curve[16]; /* "nistxddd" */ + ECParams *ecparams; + int N; + int i; + unsigned int len; + + ecdsareq = fopen(reqfn, "r"); + ecdsaresp = stdout; + strcpy(curve, "nist"); + while (fgets(buf, sizeof buf, ecdsareq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, ecdsaresp); + continue; + } + /* [X-ddd] */ + if (buf[0] == '[') { + const char *src; + char *dst; + SECKEYECParams *encodedparams; + + src = &buf[1]; + dst = &curve[4]; + *dst++ = tolower(*src); + src += 2; /* skip the hyphen */ + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst = '\0'; + encodedparams = getECParams(curve); + if (encodedparams == NULL) { + goto loser; + } + if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) { + goto loser; + } + SECITEM_FreeItem(encodedparams, PR_TRUE); + fputs(buf, ecdsaresp); + continue; + } + /* N = x */ + if (buf[0] == 'N') { + if (sscanf(buf, "N = %d", &N) != 1) { + goto loser; + } + for (i = 0; i < N; i++) { + ECPrivateKey *ecpriv; + + if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) { + goto loser; + } + fputs("d = ", ecdsaresp); + to_hex_str(buf, ecpriv->privateValue.data, + ecpriv->privateValue.len); + fputs(buf, ecdsaresp); + fputc('\n', ecdsaresp); + if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue) + != SECSuccess) { + goto loser; + } + len = ecpriv->publicValue.len; + if (len%2 == 0) { + goto loser; + } + len = (len-1)/2; + if (ecpriv->publicValue.data[0] + != EC_POINT_FORM_UNCOMPRESSED) { + goto loser; + } + fputs("Qx = ", ecdsaresp); + to_hex_str(buf, &ecpriv->publicValue.data[1], len); + fputs(buf, ecdsaresp); + fputc('\n', ecdsaresp); + fputs("Qy = ", ecdsaresp); + to_hex_str(buf, &ecpriv->publicValue.data[1+len], len); + fputs(buf, ecdsaresp); + fputc('\n', ecdsaresp); + fputc('\n', ecdsaresp); + PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE); + } + PORT_FreeArena(ecparams->arena, PR_TRUE); + continue; + } + } +loser: + fclose(ecdsareq); +} + +/* + * Perform the ECDSA Public Key Validation Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void +ecdsa_pkv_test(char *reqfn) +{ + char buf[256]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "Qx = <144 hex digits>\n". + */ + FILE *ecdsareq; /* input stream from the REQUEST file */ + FILE *ecdsaresp; /* output stream to the RESPONSE file */ + char curve[16]; /* "nistxddd" */ + ECParams *ecparams = NULL; + SECItem pubkey; + unsigned int i; + unsigned int len; + PRBool keyvalid = PR_TRUE; + + ecdsareq = fopen(reqfn, "r"); + ecdsaresp = stdout; + strcpy(curve, "nist"); + pubkey.data = NULL; + while (fgets(buf, sizeof buf, ecdsareq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, ecdsaresp); + continue; + } + /* [X-ddd] */ + if (buf[0] == '[') { + const char *src; + char *dst; + SECKEYECParams *encodedparams; + + src = &buf[1]; + dst = &curve[4]; + *dst++ = tolower(*src); + src += 2; /* skip the hyphen */ + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst = '\0'; + if (ecparams != NULL) { + PORT_FreeArena(ecparams->arena, PR_TRUE); + ecparams = NULL; + } + encodedparams = getECParams(curve); + if (encodedparams == NULL) { + goto loser; + } + if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) { + goto loser; + } + SECITEM_FreeItem(encodedparams, PR_TRUE); + len = (ecparams->fieldID.size + 7) >> 3; + if (pubkey.data != NULL) { + PORT_Free(pubkey.data); + pubkey.data = NULL; + } + SECITEM_AllocItem(NULL, &pubkey, 2*len+1); + if (pubkey.data == NULL) { + goto loser; + } + pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED; + fputs(buf, ecdsaresp); + continue; + } + /* Qx = ... */ + if (strncmp(buf, "Qx", 2) == 0) { + fputs(buf, ecdsaresp); + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]); + continue; + } + /* Qy = ... */ + if (strncmp(buf, "Qy", 2) == 0) { + fputs(buf, ecdsaresp); + if (!keyvalid) { + fputs("Result = F\n", ecdsaresp); + continue; + } + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]); + if (!keyvalid) { + fputs("Result = F\n", ecdsaresp); + continue; + } + if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) { + fputs("Result = P\n", ecdsaresp); + } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) { + fputs("Result = F\n", ecdsaresp); + } else { + goto loser; + } + continue; + } + } +loser: + if (ecparams != NULL) { + PORT_FreeArena(ecparams->arena, PR_TRUE); + } + if (pubkey.data != NULL) { + PORT_Free(pubkey.data); + } + fclose(ecdsareq); +} + +/* + * Perform the ECDSA Signature Generation Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void +ecdsa_siggen_test(char *reqfn) +{ + char buf[1024]; /* holds one line from the input REQUEST file + * or to the output RESPONSE file. + * needs to be large enough to hold the longest + * line "Msg = <256 hex digits>\n". + */ + FILE *ecdsareq; /* input stream from the REQUEST file */ + FILE *ecdsaresp; /* output stream to the RESPONSE file */ + char curve[16]; /* "nistxddd" */ + ECParams *ecparams = NULL; + int i, j; + unsigned int len; + unsigned char msg[512]; /* message to be signed (<= 128 bytes) */ + unsigned int msglen; + unsigned char sha1[20]; /* SHA-1 hash (160 bits) */ + unsigned char sig[2*MAX_ECKEY_LEN]; + SECItem signature, digest; + + ecdsareq = fopen(reqfn, "r"); + ecdsaresp = stdout; + strcpy(curve, "nist"); + while (fgets(buf, sizeof buf, ecdsareq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, ecdsaresp); + continue; + } + /* [X-ddd] */ + if (buf[0] == '[') { + const char *src; + char *dst; + SECKEYECParams *encodedparams; + + src = &buf[1]; + dst = &curve[4]; + *dst++ = tolower(*src); + src += 2; /* skip the hyphen */ + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst = '\0'; + if (ecparams != NULL) { + PORT_FreeArena(ecparams->arena, PR_TRUE); + ecparams = NULL; + } + encodedparams = getECParams(curve); + if (encodedparams == NULL) { + goto loser; + } + if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) { + goto loser; + } + SECITEM_FreeItem(encodedparams, PR_TRUE); + fputs(buf, ecdsaresp); + continue; + } + /* Msg = ... */ + if (strncmp(buf, "Msg", 3) == 0) { + ECPrivateKey *ecpriv; + + i = 3; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &msg[j]); + } + msglen = j; + if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) { + goto loser; + } + fputs(buf, ecdsaresp); + + if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) { + goto loser; + } + if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue) + != SECSuccess) { + goto loser; + } + len = ecpriv->publicValue.len; + if (len%2 == 0) { + goto loser; + } + len = (len-1)/2; + if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) { + goto loser; + } + fputs("Qx = ", ecdsaresp); + to_hex_str(buf, &ecpriv->publicValue.data[1], len); + fputs(buf, ecdsaresp); + fputc('\n', ecdsaresp); + fputs("Qy = ", ecdsaresp); + to_hex_str(buf, &ecpriv->publicValue.data[1+len], len); + fputs(buf, ecdsaresp); + fputc('\n', ecdsaresp); + + digest.type = siBuffer; + digest.data = sha1; + digest.len = sizeof sha1; + signature.type = siBuffer; + signature.data = sig; + signature.len = sizeof sig; + if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) { + goto loser; + } + len = signature.len; + if (len%2 != 0) { + goto loser; + } + len = len/2; + fputs("R = ", ecdsaresp); + to_hex_str(buf, &signature.data[0], len); + fputs(buf, ecdsaresp); + fputc('\n', ecdsaresp); + fputs("S = ", ecdsaresp); + to_hex_str(buf, &signature.data[len], len); + fputs(buf, ecdsaresp); + fputc('\n', ecdsaresp); + + PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE); + continue; + } + } +loser: + if (ecparams != NULL) { + PORT_FreeArena(ecparams->arena, PR_TRUE); + } + fclose(ecdsareq); +} + +/* + * Perform the ECDSA Signature Verification Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void +ecdsa_sigver_test(char *reqfn) +{ + char buf[1024]; /* holds one line from the input REQUEST file. + * needs to be large enough to hold the longest + * line "Msg = <256 hex digits>\n". + */ + FILE *ecdsareq; /* input stream from the REQUEST file */ + FILE *ecdsaresp; /* output stream to the RESPONSE file */ + char curve[16]; /* "nistxddd" */ + ECParams *ecparams = NULL; + ECPublicKey ecpub; + unsigned int i, j; + unsigned int flen; /* length in bytes of the field size */ + unsigned int olen; /* length in bytes of the base point order */ + unsigned char msg[512]; /* message that was signed (<= 128 bytes) */ + unsigned int msglen; + unsigned char sha1[20]; /* SHA-1 hash (160 bits) */ + unsigned char sig[2*MAX_ECKEY_LEN]; + SECItem signature, digest; + PRBool keyvalid = PR_TRUE; + PRBool sigvalid = PR_TRUE; + + ecdsareq = fopen(reqfn, "r"); + ecdsaresp = stdout; + ecpub.publicValue.type = siBuffer; + ecpub.publicValue.data = NULL; + ecpub.publicValue.len = 0; + strcpy(curve, "nist"); + while (fgets(buf, sizeof buf, ecdsareq) != NULL) { + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, ecdsaresp); + continue; + } + /* [X-ddd] */ + if (buf[0] == '[') { + const char *src; + char *dst; + SECKEYECParams *encodedparams; + + src = &buf[1]; + dst = &curve[4]; + *dst++ = tolower(*src); + src += 2; /* skip the hyphen */ + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst = '\0'; + if (ecparams != NULL) { + PORT_FreeArena(ecparams->arena, PR_TRUE); + ecparams = NULL; + } + encodedparams = getECParams(curve); + if (encodedparams == NULL) { + goto loser; + } + if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) { + goto loser; + } + SECITEM_FreeItem(encodedparams, PR_TRUE); + ecpub.ecParams = *ecparams; + flen = (ecparams->fieldID.size + 7) >> 3; + olen = ecparams->order.len; + if (2*olen > sizeof sig) { + goto loser; + } + if (ecpub.publicValue.data != NULL) { + SECITEM_FreeItem(&ecpub.publicValue, PR_FALSE); + } + SECITEM_AllocItem(NULL, &ecpub.publicValue, 2*flen+1); + if (ecpub.publicValue.data == NULL) { + goto loser; + } + ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED; + fputs(buf, ecdsaresp); + continue; + } + /* Msg = ... */ + if (strncmp(buf, "Msg", 3) == 0) { + i = 3; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; isxdigit(buf[i]); i+=2,j++) { + hex_from_2char(&buf[i], &msg[j]); + } + msglen = j; + if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) { + goto loser; + } + fputs(buf, ecdsaresp); + + digest.type = siBuffer; + digest.data = sha1; + digest.len = sizeof sha1; + + continue; + } + /* Qx = ... */ + if (strncmp(buf, "Qx", 2) == 0) { + fputs(buf, ecdsaresp); + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen, + &buf[i]); + continue; + } + /* Qy = ... */ + if (strncmp(buf, "Qy", 2) == 0) { + fputs(buf, ecdsaresp); + if (!keyvalid) { + continue; + } + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen, + &buf[i]); + if (!keyvalid) { + continue; + } + if (EC_ValidatePublicKey(ecparams, &ecpub.publicValue) + != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_BAD_KEY) { + keyvalid = PR_FALSE; + } else { + goto loser; + } + } + continue; + } + /* R = ... */ + if (buf[0] == 'R') { + fputs(buf, ecdsaresp); + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + sigvalid = from_hex_str(sig, olen, &buf[i]); + continue; + } + /* S = ... */ + if (buf[0] == 'S') { + fputs(buf, ecdsaresp); + i = 1; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + if (sigvalid) { + sigvalid = from_hex_str(&sig[olen], olen, &buf[i]); + } + signature.type = siBuffer; + signature.data = sig; + signature.len = 2*olen; + + if (!keyvalid || !sigvalid) { + fputs("Result = F\n", ecdsaresp); + } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest) + == SECSuccess) { + fputs("Result = P\n", ecdsaresp); + } else { + fputs("Result = F\n", ecdsaresp); + } + continue; + } + } +loser: + if (ecparams != NULL) { + PORT_FreeArena(ecparams->arena, PR_TRUE); + } + if (ecpub.publicValue.data != NULL) { + SECITEM_FreeItem(&ecpub.publicValue, PR_FALSE); + } + fclose(ecdsareq); +} +#endif /* NSS_ENABLE_ECC */ + void do_random() { int i, j, k = 0; @@ -2344,272 +2920,427 @@ void do_random() } } +/* + * Calculate the SHA Message Digest + * + * MD = Message digest + * MDLen = length of Message Digest and SHA_Type + * msg = message to digest + * msgLen = length of message to digest + */ +SECStatus sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen) +{ + SECStatus sha_status = SECFailure; + + if (MDLen == SHA1_LENGTH) { + sha_status = SHA1_HashBuf(MD, msg, msgLen); + } else if (MDLen == SHA256_LENGTH) { + sha_status = SHA256_HashBuf(MD, msg, msgLen); + } else if (MDLen == SHA384_LENGTH) { + sha_status = SHA384_HashBuf(MD, msg, msgLen); + } else if (MDLen == SHA512_LENGTH) { + sha_status = SHA512_HashBuf(MD, msg, msgLen); + } + + return sha_status; +} + +/* + * Perform the SHA Monte Carlo Test + * + * MDLen = length of Message Digest and SHA_Type + * seed = input seed value + * resp = is the output response file. + */ +SECStatus sha_mct_test(unsigned int MDLen, unsigned char *seed, FILE *resp) +{ + int i, j; + unsigned int msgLen = MDLen*3; + unsigned char MD_i3[HASH_LENGTH_MAX]; /* MD[i-3] */ + unsigned char MD_i2[HASH_LENGTH_MAX]; /* MD[i-2] */ + unsigned char MD_i1[HASH_LENGTH_MAX]; /* MD[i-1] */ + unsigned char MD_i[HASH_LENGTH_MAX]; /* MD[i] */ + unsigned char msg[HASH_LENGTH_MAX*3]; + char buf[HASH_LENGTH_MAX*2 + 1]; /* MAX buf MD_i as a hex string */ + + for (j=0; j<100; j++) { + /* MD_0 = MD_1 = MD_2 = seed */ + memcpy(MD_i3, seed, MDLen); + memcpy(MD_i2, seed, MDLen); + memcpy(MD_i1, seed, MDLen); + + for (i=3; i < 1003; i++) { + /* Mi = MD[i-3] || MD [i-2] || MD [i-1] */ + memcpy(msg, MD_i3, MDLen); + memcpy(&msg[MDLen], MD_i2, MDLen); + memcpy(&msg[MDLen*2], MD_i1,MDLen); + + /* MDi = SHA(Msg) */ + if (sha_calcMD(MD_i, MDLen, + msg, msgLen) != SECSuccess) { + return SECFailure; + } + + /* save MD[i-3] MD[i-2] MD[i-1] */ + memcpy(MD_i3, MD_i2, MDLen); + memcpy(MD_i2, MD_i1, MDLen); + memcpy(MD_i1, MD_i, MDLen); + + } + + /* seed = MD_i */ + memcpy(seed, MD_i, MDLen); + + sprintf(buf, "COUNT = %d\n", j); + fputs(buf, resp); + + /* output MD_i */ + fputs("MD = ", resp); + to_hex_str(buf, MD_i, MDLen); + fputs(buf, resp); + fputc('\n', resp); + } + + return SECSuccess; +} + +/* + * Perform the SHA Tests. + * + * reqfn is the pathname of the input REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void sha_test(char *reqfn) +{ + int i, j; + unsigned int MDlen; /* the length of the Message Digest in Bytes */ + unsigned int msgLen; /* the length of the input Message in Bytes */ + char *msg = NULL; /* holds the message to digest.*/ + size_t bufSize = 25608; /*MAX buffer size */ + char *buf = NULL; /* holds one line from the input REQUEST file.*/ + unsigned char seed[HASH_LENGTH_MAX]; /* max size of seed 64 bytes */ + unsigned char MD[HASH_LENGTH_MAX]; /* message digest */ + + FILE *req; /* input stream from the REQUEST file */ + FILE *resp; /* output stream to the RESPONSE file */ + + buf = PORT_ZAlloc(bufSize); + if (buf == NULL) { + goto loser; + } + + /* zeroize the variables for the test with this data set */ + memset(seed, 0, sizeof seed); + + req = fopen(reqfn, "r"); + resp = stdout; + while (fgets(buf, bufSize, req) != NULL) { + + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, resp); + continue; + } + /* [L = Length of the Message Digest and sha_type */ + if (buf[0] == '[') { + if (strncmp(&buf[1], "L ", 1) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + MDlen = atoi(&buf[i]); + fputs(buf, resp); + continue; + } + } + /* Len = Length of the Input Message Length ... */ + if (strncmp(buf, "Len", 3) == 0) { + i = 3; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + if (msg) { + PORT_ZFree(msg,msgLen); + msg = NULL; + } + msgLen = atoi(&buf[i]); /* in bits */ + msgLen = msgLen/8; /* convert to bytes */ + fputs(buf, resp); + msg = PORT_ZAlloc(msgLen); + if (msg == NULL && msgLen != 0) { + goto loser; + } + continue; + } + /* MSG = ... */ + if (strncmp(buf, "Msg", 3) == 0) { + i = 3; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; j< msgLen; i+=2,j++) { + hex_from_2char(&buf[i], &msg[j]); + } + fputs(buf, resp); + /* calculate the Message Digest */ + memset(MD, 0, sizeof MD); + if (sha_calcMD(MD, MDlen, + msg, msgLen) != SECSuccess) { + goto loser; + } + + fputs("MD = ", resp); + to_hex_str(buf, MD, MDlen); + fputs(buf, resp); + fputc('\n', resp); + + continue; + } + /* Seed = ... */ + if (strncmp(buf, "Seed", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; j<sizeof seed; i+=2,j++) { + hex_from_2char(&buf[i], &seed[j]); + } + + fputs(buf, resp); + fputc('\n', resp); + + /* do the Monte Carlo test */ + if (sha_mct_test(MDlen, seed, resp) != SECSuccess) { + goto loser; + } + + continue; + } + } +loser: + fclose(req); + if (buf) { + PORT_ZFree(buf, bufSize); + } + if (msg) { + PORT_ZFree(msg, msgLen); + } +} + +/****************************************************/ +/* HMAC SHA-X calc */ +/* hmac_computed - the computed HMAC */ +/* hmac_length - the length of the computed HMAC */ +/* secret_key - secret key to HMAC */ +/* secret_key_length - length of secret key, */ +/* message - message to HMAC */ +/* message_length - length ofthe message */ +/****************************************************/ +static SECStatus +hmac_calc(unsigned char *hmac_computed, + const unsigned int hmac_length, + const char *secret_key, + const unsigned int secret_key_length, + const char *message, + const unsigned int message_length, + const HASH_HashType hashAlg ) +{ + SECStatus hmac_status = SECFailure; + HMACContext *cx = NULL; + SECHashObject *hashObj = NULL; + unsigned int bytes_hashed = 0; + + hashObj = (SECHashObject *) HASH_GetRawHashObject(hashAlg); + + if (!hashObj) + return( SECFailure ); + + cx = HMAC_Create(hashObj, secret_key, + secret_key_length, + PR_TRUE); /* PR_TRUE for in FIPS mode */ + + if (cx == NULL) + return( SECFailure ); + + HMAC_Begin(cx); + HMAC_Update(cx, message, message_length); + hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed, + hmac_length); + + HMAC_Destroy(cx, PR_TRUE); + + return( hmac_status ); +} + +/* + * Perform the HMAC Tests. + * + * reqfn is the pathname of the input REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ +void hmac_test(char *reqfn) +{ + int i, j; + size_t bufSize = 288; /* MAX buffer size */ + char *buf = NULL; /* holds one line from the input REQUEST file.*/ + unsigned int keyLen; /* Key Length */ + char key[140]; /* key MAX size = 140 */ + unsigned int msgLen = 128; /* the length of the input */ + /* Message is always 128 Bytes */ + char *msg = NULL; /* holds the message to digest.*/ + unsigned int HMACLen; /* the length of the HMAC Bytes */ + unsigned char HMAC[HASH_LENGTH_MAX]; /* computed HMAC */ + HASH_HashType hash_alg; /* HMAC type */ + + FILE *req; /* input stream from the REQUEST file */ + FILE *resp; /* output stream to the RESPONSE file */ + + buf = PORT_ZAlloc(bufSize); + if (buf == NULL) { + goto loser; + } + msg = PORT_ZAlloc(msgLen); + memset(msg, 0, msgLen); + if (msg == NULL) { + goto loser; + } + + req = fopen(reqfn, "r"); + resp = stdout; + while (fgets(buf, bufSize, req) != NULL) { + + /* a comment or blank line */ + if (buf[0] == '#' || buf[0] == '\n') { + fputs(buf, resp); + continue; + } + /* [L = Length of the MAC and HASH_type */ + if (buf[0] == '[') { + if (strncmp(&buf[1], "L ", 1) == 0) { + i = 2; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + /* HMACLen will get reused for Tlen */ + HMACLen = atoi(&buf[i]); + /* set the HASH algorithm for HMAC */ + if (HMACLen == SHA1_LENGTH) { + hash_alg = HASH_AlgSHA1; + } else if (HMACLen == SHA256_LENGTH) { + hash_alg = HASH_AlgSHA256; + } else if (HMACLen == SHA384_LENGTH) { + hash_alg = HASH_AlgSHA384; + } else if (HMACLen == SHA512_LENGTH) { + hash_alg = HASH_AlgSHA512; + } else { + goto loser; + } + fputs(buf, resp); + continue; + } + } + /* Count = test iteration number*/ + if (strncmp(buf, "Count ", 5) == 0) { + /* count can just be put into resp file */ + fputs(buf, resp); + /* zeroize the variables for the test with this data set */ + keyLen = 0; + HMACLen = 0; + memset(key, 0, sizeof key); + memset(msg, 0, sizeof msg); + memset(HMAC, 0, sizeof HMAC); + continue; + } + /* KLen = Length of the Input Secret Key ... */ + if (strncmp(buf, "Klen", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + keyLen = atoi(&buf[i]); /* in bytes */ + fputs(buf, resp); + continue; + } + /* key = the secret key for the key to MAC */ + if (strncmp(buf, "Key", 3) == 0) { + i = 3; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; j< keyLen; i+=2,j++) { + hex_from_2char(&buf[i], &key[j]); + } + fputs(buf, resp); + } + /* TLen = Length of the calculated HMAC */ + if (strncmp(buf, "Tlen", 4) == 0) { + i = 4; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + HMACLen = atoi(&buf[i]); /* in bytes */ + fputs(buf, resp); + continue; + } + /* MSG = to HMAC always 128 bytes for these tests */ + if (strncmp(buf, "Msg", 3) == 0) { + i = 3; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + for (j=0; j< msgLen; i+=2,j++) { + hex_from_2char(&buf[i], &msg[j]); + } + fputs(buf, resp); + /* calculate the HMAC and output */ + if (hmac_calc(HMAC, HMACLen, key, keyLen, + msg, msgLen, hash_alg) != SECSuccess) { + goto loser; + } + fputs("MAC = ", resp); + to_hex_str(buf, HMAC, HMACLen); + fputs(buf, resp); + fputc('\n', resp); + continue; + } + } +loser: + fclose(req); + if (buf) { + PORT_ZFree(buf, bufSize); + } + if (msg) { + PORT_ZFree(msg, msgLen); + } +} + int main(int argc, char **argv) { - unsigned char key[24]; - unsigned char inp[24]; - unsigned char iv[8]; if (argc < 2) exit (-1); NSS_NoDB_Init(NULL); - memset(inp, 0, sizeof inp); - /*************/ - /* DES */ - /*************/ - /**** ECB ****/ - /* encrypt */ - if ( strcmp(argv[1], "des_5_1_1_1") == 0) { - printf("Variable Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - des_var_pt_kat(NSS_DES, PR_TRUE, 8, key, NULL, NULL); - } else if (strcmp(argv[1], "des_5_1_1_2") == 0) { - printf("Inverse Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - des_inv_perm_kat(NSS_DES, PR_TRUE, 8, key, NULL, NULL); - } else if (strcmp(argv[1], "des_5_1_1_3") == 0) { - printf("Variable Key Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - des_var_key_kat(NSS_DES, PR_TRUE, 8, key, NULL, inp); - } else if (strcmp(argv[1], "des_5_1_1_4") == 0) { - printf("Permutation Operation Known Answer Test - Encryption\n\n"); - des_perm_op_kat(NSS_DES, PR_TRUE, 8, NULL, NULL, inp); - } else if (strcmp(argv[1], "des_5_1_1_5") == 0) { - printf("Substitution Table Known Answer Test - Encryption\n\n"); - des_sub_tbl_kat(NSS_DES, PR_TRUE, 8, NULL, NULL, NULL); - } else if (strcmp(argv[1], "des_5_1_1_6") == 0) { - printf("Modes Test for the Encryption Process\n\n"); - des_modes(NSS_DES, PR_TRUE, 8, des_ecb_enc_key, - NULL, des_ecb_enc_inp, 0); - /* decrypt */ - } else if (strcmp(argv[1], "des_5_1_2_1") == 0) { - printf("Variable Ciphertext Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - des_var_pt_kat(NSS_DES, PR_FALSE, 8, key, NULL, NULL); - } else if (strcmp(argv[1], "des_5_1_2_2") == 0) { - printf("Inverse Permutation Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - des_inv_perm_kat(NSS_DES, PR_FALSE, 8, key, NULL, NULL); - } else if (strcmp(argv[1], "des_5_1_2_3") == 0) { - printf("Variable Key Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - des_var_key_kat(NSS_DES, PR_FALSE, 8, key, NULL, inp); - } else if (strcmp(argv[1], "des_5_1_2_4") == 0) { - printf("Permutation Operation Known Answer Test - Decryption\n\n"); - des_perm_op_kat(NSS_DES, PR_FALSE, 8, NULL, NULL, inp); - } else if (strcmp(argv[1], "des_5_1_2_5") == 0) { - printf("Substitution Table Known Answer Test - Decryption\n\n"); - des_sub_tbl_kat(NSS_DES, PR_FALSE, 8, NULL, NULL, NULL); - } else if (strcmp(argv[1], "des_5_1_2_6") == 0) { - printf("Modes Test for the Decryption Process\n\n"); - des_modes(NSS_DES, PR_FALSE, 8, des_ecb_dec_key, - NULL, des_ecb_dec_inp, 0); - /**** CBC ****/ - /* encrypt */ - } else if (strcmp(argv[1], "des_5_2_1_1") == 0) { - printf("Variable Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_pt_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, NULL); - } else if (strcmp(argv[1], "des_5_2_1_2") == 0) { - printf("Inverse Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_inv_perm_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, NULL); - } else if (strcmp(argv[1], "des_5_2_1_3") == 0) { - printf("Variable Key Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_key_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, inp); - } else if (strcmp(argv[1], "des_5_2_1_4") == 0) { - printf("Permutation Operation Known Answer Test - Encryption\n\n"); - memset(iv, 0, sizeof iv); - des_perm_op_kat(NSS_DES_CBC, PR_TRUE, 8, NULL, iv, inp); - } else if (strcmp(argv[1], "des_5_2_1_5") == 0) { - printf("Substitution Table Known Answer Test - Encryption\n\n"); - memset(iv, 0, sizeof iv); - des_sub_tbl_kat(NSS_DES_CBC, PR_TRUE, 8, NULL, iv, NULL); - } else if (strcmp(argv[1], "des_5_2_1_6") == 0) { - printf("Modes Test for the Encryption Process\n\n"); - des_modes(NSS_DES_CBC, PR_TRUE, 8, des_cbc_enc_key, - des_cbc_enc_iv, des_cbc_enc_inp, 0); - /* decrypt */ - } else if (strcmp(argv[1], "des_5_2_2_1") == 0) { - printf("Variable Ciphertext Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_pt_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, NULL); - } else if (strcmp(argv[1], "des_5_2_2_2") == 0) { - printf("Inverse Permutation Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_inv_perm_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, NULL); - } else if (strcmp(argv[1], "des_5_2_2_3") == 0) { - printf("Variable Key Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_key_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, inp); - } else if (strcmp(argv[1], "des_5_2_2_4") == 0) { - printf("Permutation Operation Known Answer Test - Decryption\n\n"); - memset(iv, 0, sizeof iv); - des_perm_op_kat(NSS_DES_CBC, PR_FALSE, 8, NULL, iv, inp); - } else if (strcmp(argv[1], "des_5_2_2_5") == 0) { - printf("Substitution Table Known Answer Test - Decryption\n\n"); - memset(iv, 0, sizeof iv); - des_sub_tbl_kat(NSS_DES_CBC, PR_FALSE, 8, NULL, iv, NULL); - } else if (strcmp(argv[1], "des_5_2_2_6") == 0) { - printf("Modes Test for the Decryption Process\n\n"); - des_modes(NSS_DES_CBC, PR_FALSE, 8, des_cbc_dec_key, - des_cbc_dec_iv, des_cbc_dec_inp, 0); /*************/ /* TDEA */ /*************/ - /**** ECB ****/ - /* encrypt */ - } else if (strcmp(argv[1], "tdea_5_1_1_1") == 0) { - printf("Variable Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - des_var_pt_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, NULL); - } else if (strcmp(argv[1], "tdea_5_1_1_2") == 0) { - printf("Inverse Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - des_inv_perm_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, NULL); - } else if (strcmp(argv[1], "tdea_5_1_1_3") == 0) { - printf("Variable Key Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - des_var_key_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, inp); - } else if (strcmp(argv[1], "tdea_5_1_1_4") == 0) { - printf("Permutation Operation Known Answer Test - Encryption\n\n"); - des_perm_op_kat(NSS_DES_EDE3, PR_TRUE, 24, NULL, NULL, inp); - } else if (strcmp(argv[1], "tdea_5_1_1_5") == 0) { - printf("Substitution Table Known Answer Test - Encryption\n\n"); - des_sub_tbl_kat(NSS_DES_EDE3, PR_TRUE, 24, NULL, NULL, NULL); - } else if (strcmp(argv[1], "tdea_5_1_1_6_3") == 0) { - printf("Modes Test for the Encryption Process\n"); - printf("DATA FILE UTILIZED: datecbmontee1\n\n"); - des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea1_ecb_enc_key, - NULL, tdea1_ecb_enc_inp, 1); - } else if (strcmp(argv[1], "tdea_5_1_1_6_2") == 0) { - printf("Modes Test for the Encryption Process\n"); - printf("DATA FILE UTILIZED: datecbmontee2\n\n"); - des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea2_ecb_enc_key, - NULL, tdea2_ecb_enc_inp, 2); - } else if (strcmp(argv[1], "tdea_5_1_1_6_1") == 0) { - printf("Modes Test for the Encryption Process\n"); - printf("DATA FILE UTILIZED: datecbmontee3\n\n"); - des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea3_ecb_enc_key, - NULL, tdea3_ecb_enc_inp, 3); - /* decrypt */ - } else if (strcmp(argv[1], "tdea_5_1_2_1") == 0) { - printf("Variable Ciphertext Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - des_var_pt_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, NULL); - } else if (strcmp(argv[1], "tdea_5_1_2_2") == 0) { - printf("Inverse Permutation Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - des_inv_perm_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, NULL); - } else if (strcmp(argv[1], "tdea_5_1_2_3") == 0) { - printf("Variable Key Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - des_var_key_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, inp); - } else if (strcmp(argv[1], "tdea_5_1_2_4") == 0) { - printf("Permutation Operation Known Answer Test - Decryption\n\n"); - des_perm_op_kat(NSS_DES_EDE3, PR_FALSE, 24, NULL, NULL, inp); - } else if (strcmp(argv[1], "tdea_5_1_2_5") == 0) { - printf("Substitution Table Known Answer Test - Decryption\n\n"); - des_sub_tbl_kat(NSS_DES_EDE3, PR_FALSE, 24, NULL, NULL, NULL); - } else if (strcmp(argv[1], "tdea_5_1_2_6_3") == 0) { - printf("Modes Test for the Decryption Process\n"); - printf("DATA FILE UTILIZED: datecbmonted1\n\n"); - des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea1_ecb_dec_key, - NULL, tdea1_ecb_dec_inp, 1); - } else if (strcmp(argv[1], "tdea_5_1_2_6_2") == 0) { - printf("Modes Test for the Decryption Process\n"); - printf("DATA FILE UTILIZED: datecbmonted2\n\n"); - des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea2_ecb_dec_key, - NULL, tdea2_ecb_dec_inp, 2); - } else if (strcmp(argv[1], "tdea_5_1_2_6_1") == 0) { - printf("Modes Test for the Decryption Process\n"); - printf("DATA FILE UTILIZED: datecbmonted3\n\n"); - des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea3_ecb_dec_key, - NULL, tdea3_ecb_dec_inp, 3); - /**** CBC ****/ - /* encrypt */ - } else if (strcmp(argv[1], "tdea_5_2_1_1") == 0) { - printf("Variable Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_pt_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, NULL); - } else if (strcmp(argv[1], "tdea_5_2_1_2") == 0) { - printf("Inverse Plaintext Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_inv_perm_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, NULL); - } else if (strcmp(argv[1], "tdea_5_2_1_3") == 0) { - printf("Variable Key Known Answer Test - Encryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_key_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, inp); - } else if (strcmp(argv[1], "tdea_5_2_1_4") == 0) { - printf("Permutation Operation Known Answer Test - Encryption\n\n"); - memset(iv, 0, sizeof iv); - des_perm_op_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, NULL, iv, inp); - } else if (strcmp(argv[1], "tdea_5_2_1_5") == 0) { - memset(iv, 0, sizeof iv); - printf("Substitution Table Known Answer Test - Encryption\n\n"); - des_sub_tbl_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, NULL, iv, NULL); - } else if (strcmp(argv[1], "tdea_5_2_1_6_3") == 0) { - printf("Modes Test for the Encryption Process\n"); - printf("DATA FILE UTILIZED: datcbcmontee1\n\n"); - des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea1_cbc_enc_key, - tdea1_cbc_enc_iv, tdea1_cbc_enc_inp, 1); - } else if (strcmp(argv[1], "tdea_5_2_1_6_2") == 0) { - printf("Modes Test for the Encryption Process\n"); - printf("DATA FILE UTILIZED: datcbcmontee2\n\n"); - des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea2_cbc_enc_key, - tdea2_cbc_enc_iv, tdea2_cbc_enc_inp, 2); - } else if (strcmp(argv[1], "tdea_5_2_1_6_1") == 0) { - printf("Modes Test for the Encryption Process\n"); - printf("DATA FILE UTILIZED: datcbcmontee3\n\n"); - des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea3_cbc_enc_key, - tdea3_cbc_enc_iv, tdea3_cbc_enc_inp, 3); - /* decrypt */ - } else if (strcmp(argv[1], "tdea_5_2_2_1") == 0) { - printf("Variable Ciphertext Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_pt_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, NULL); - } else if (strcmp(argv[1], "tdea_5_2_2_2") == 0) { - printf("Inverse Permutation Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_inv_perm_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, NULL); - } else if (strcmp(argv[1], "tdea_5_2_2_3") == 0) { - printf("Variable Key Known Answer Test - Decryption\n\n"); - memset(key, 1, sizeof key); - memset(iv, 0, sizeof iv); - des_var_key_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, inp); - } else if (strcmp(argv[1], "tdea_5_2_2_4") == 0) { - printf("Permutation Operation Known Answer Test - Decryption\n\n"); - memset(iv, 0, sizeof iv); - des_perm_op_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, NULL, iv, inp); - } else if (strcmp(argv[1], "tdea_5_2_2_5") == 0) { - printf("Substitution Table Known Answer Test - Decryption\n\n"); - memset(iv, 0, sizeof iv); - des_sub_tbl_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, NULL, iv, NULL); - } else if (strcmp(argv[1], "tdea_5_2_2_6_3") == 0) { - printf("Modes Test for the Decryption Process\n"); - printf("DATA FILE UTILIZED: datcbcmonted1\n\n"); - des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea1_cbc_dec_key, - tdea1_cbc_dec_iv, tdea1_cbc_dec_inp, 1); - } else if (strcmp(argv[1], "tdea_5_2_2_6_2") == 0) { - printf("Modes Test for the Decryption Process\n"); - printf("DATA FILE UTILIZED: datcbcmonted2\n\n"); - des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea2_cbc_dec_key, - tdea2_cbc_dec_iv, tdea2_cbc_dec_inp, 2); - } else if (strcmp(argv[1], "tdea_5_2_2_6_1") == 0) { - printf("Modes Test for the Decryption Process\n"); - printf("DATA FILE UTILIZED: datcbcmonted3\n\n"); - des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea3_cbc_dec_key, - tdea3_cbc_dec_iv, tdea3_cbc_dec_inp, 3); + if (strcmp(argv[1], "tdea") == 0) { + /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */ + if (strcmp(argv[2], "kat") == 0) { + /* Known Answer Test (KAT) */ + tdea_kat_mmt(argv[4]); + } else if (strcmp(argv[2], "mmt") == 0) { + /* Multi-block Message Test (MMT) */ + tdea_kat_mmt(argv[4]); + } else if (strcmp(argv[2], "mct") == 0) { + /* Monte Carlo Test (MCT) */ + if (strcmp(argv[3], "ecb") == 0) { + /* ECB mode */ + tdea_mct(NSS_DES_EDE3, argv[4]); + } else if (strcmp(argv[3], "cbc") == 0) { + /* CBC mode */ + tdea_mct(NSS_DES_EDE3_CBC, argv[4]); + } + } /*************/ /* AES */ /*************/ @@ -2632,15 +3363,40 @@ int main(int argc, char **argv) } } /*************/ - /* SHS */ + /* SHA */ /*************/ - } else if (strcmp(argv[1], "shs") == 0) { - shs_test(argv[2]); + } else if (strcmp(argv[1], "sha") == 0) { + sha_test(argv[2]); + /*************/ + /* HMAC */ + /*************/ + } else if (strcmp(argv[1], "hmac") == 0) { + hmac_test(argv[2]); /*************/ /* DSS */ /*************/ } else if (strcmp(argv[1], "dss") == 0) { dss_test(argv[2], argv[3]); +#ifdef NSS_ENABLE_ECC + /*************/ + /* ECDSA */ + /*************/ + } else if (strcmp(argv[1], "ecdsa") == 0) { + /* argv[2]=keypair|pkv|siggen|sigver argv[3]=<test name>.req */ + if ( strcmp(argv[2], "keypair") == 0) { + /* Key Pair Generation Test */ + ecdsa_keypair_test(argv[3]); + } else if (strcmp(argv[2], "pkv") == 0) { + /* Public Key Validation Test */ + ecdsa_pkv_test(argv[3]); + } else if (strcmp(argv[2], "siggen") == 0) { + /* Signature Generation Test */ + ecdsa_siggen_test(argv[3]); + } else if (strcmp(argv[2], "sigver") == 0) { + /* Signature Verification Test */ + ecdsa_sigver_test(argv[3]); + } +#endif /* NSS_ENABLE_ECC */ /*************/ /* RNG */ /*************/ diff --git a/security/nss/cmd/fipstest/hmac.sh b/security/nss/cmd/fipstest/hmac.sh new file mode 100755 index 000000000..ace988c7f --- /dev/null +++ b/security/nss/cmd/fipstest/hmac.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# +# A Bourne shell script for running the NIST HMAC Algorithm Validation Suite +# +# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment +# variables appropriately so that the fipstest command and the NSPR and NSS +# shared libraries/DLLs are on the search path. Then run this script in the +# directory where the REQUEST (.req) files reside. The script generates the +# RESPONSE (.rsp) files in the same directory. + +hmac_requests=" +HMAC.req +" + +for request in $hmac_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest hmac $request > $response +done + diff --git a/security/nss/cmd/fipstest/sha.sh b/security/nss/cmd/fipstest/sha.sh new file mode 100644 index 000000000..685a41b00 --- /dev/null +++ b/security/nss/cmd/fipstest/sha.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# A Bourne shell script for running the NIST SHA Algorithm Validation Suite +# +# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment +# variables appropriately so that the fipstest command and the NSPR and NSS +# shared libraries/DLLs are on the search path. Then run this script in the +# directory where the REQUEST (.req) files reside. The script generates the +# RESPONSE (.rsp) files in the same directory. + +sha_ShortMsg_requests=" +SHA1ShortMsg.req +SHA256ShortMsg.req +SHA384ShortMsg.req +SHA512ShortMsg.req +" + +sha_LongMsg_requests=" +SHA1LongMsg.req +SHA256LongMsg.req +SHA384LongMsg.req +SHA512LongMsg.req +" + +sha_Monte_requests=" +SHA1Monte.req +SHA256Monte.req +SHA384Monte.req +SHA512Monte.req +" +for request in $sha_ShortMsg_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest sha $request > $response +done +for request in $sha_LongMsg_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest sha $request > $response +done +for request in $sha_Monte_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest sha $request > $response +done + diff --git a/security/nss/cmd/fipstest/tdea.sh b/security/nss/cmd/fipstest/tdea.sh new file mode 100644 index 000000000..505478039 --- /dev/null +++ b/security/nss/cmd/fipstest/tdea.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# +# A Bourne shell script for running the NIST tdea Algorithm Validation Suite +# +# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment +# variables appropriately so that the fipstest command and the NSPR and NSS +# shared libraries/DLLs are on the search path. Then run this script in the +# directory where the REQUEST (.req) files reside. The script generates the +# RESPONSE (.rsp) files in the same directory. + +#CBC_Known_Answer_tests +#Initial Permutation KAT +#Permutation Operation KAT +#Subsitution Table KAT +#Variable Key KAT +#Variable PlainText KAT +cbc_kat_requests=" +TCBCinvperm.req +TCBCpermop.req +TCBCsubtab.req +TCBCvarkey.req +TCBCvartext.req +" + +#CBC Monte Carlo KATs +cbc_monte_requests=" +TCBCMonte1.req +TCBCMonte2.req +TCBCMonte3.req +" +#Multi-block Message KATs +cbc_mmt_requests=" +TCBCMMT1.req +TCBCMMT2.req +TCBCMMT3.req +" + +ecb_kat_requests=" +TECBinvperm.req +TECBpermop.req +TECBsubtab.req +TECBvarkey.req +TECBvartext.req +" + +ecb_monte_requests=" +TECBMonte1.req +TECBMonte2.req +TECBMonte3.req +" + +ecb_mmt_requests=" +TECBMMT1.req +TECBMMT2.req +TECBMMT3.req +" + +for request in $ecb_mmt_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest tdea mmt ecb $request > $response +done +for request in $ecb_kat_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest tdea kat ecb $request > $response +done +for request in $ecb_monte_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest tdea mct ecb $request > $response +done +for request in $cbc_mmt_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest tdea mmt cbc $request > $response +done +for request in $cbc_kat_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest tdea kat cbc $request > $response +done +for request in $cbc_monte_requests; do + response=`echo $request | sed -e "s/req/rsp/"` + echo $request $response + fipstest tdea mct cbc $request > $response +done 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/dbm/Makefile b/security/nss/cmd/pkiutil/Makefile index 34cd6d899..865888882 100644 --- a/security/dbm/Makefile +++ b/security/nss/cmd/pkiutil/Makefile @@ -1,36 +1,40 @@ #! gmake -# -# 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. # +# ***** 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 Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# +# +# 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 the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. # +# 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). # @@ -48,12 +52,11 @@ include $(CORE_DEPTH)/coreconf/config.mk # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### - - ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### +include platlibs.mk ####################################################################### @@ -72,9 +75,6 @@ include $(CORE_DEPTH)/coreconf/rules.mk # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### -coreconf_hack: - cd ../coreconf; gmake - gmake import -RelEng_bld: coreconf_hack - gmake +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/shlibsign/sign.sh b/security/nss/cmd/shlibsign/sign.sh index 97c582a79..764012d7b 100644 --- a/security/nss/cmd/shlibsign/sign.sh +++ b/security/nss/cmd/shlibsign/sign.sh @@ -50,6 +50,8 @@ OpenVMS) export DYLD_LIBRARY_PATH LIBRARY_PATH=${1}/lib:${4}:$LIBRARY_PATH export LIBRARY_PATH + ADDON_PATH=${1}/lib:${4}:$ADDON_PATH + export ADDON_PATH echo ${2}/shlibsign -v -i ${5} ${2}/shlibsign -v -i ${5} ;; 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/dbm/include/Makefile b/security/nss/cmd/ttformat/Makefile index ba4dd8ddf..4de295a9c 100644 --- a/security/dbm/include/Makefile +++ b/security/nss/cmd/ttformat/Makefile @@ -1,36 +1,40 @@ #! gmake -# -# 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. # +# ***** 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 Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# +# +# 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 the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. # +# 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). # @@ -48,13 +52,10 @@ 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) # @@ -73,4 +74,5 @@ include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### +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 */ diff --git a/security/nss/lib/fortcrypt/Makefile b/security/nss/lib/fortcrypt/Makefile new file mode 100644 index 000000000..02bd50ca6 --- /dev/null +++ b/security/nss/lib/fortcrypt/Makefile @@ -0,0 +1,180 @@ +#! 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 ***** + +include manifest.mn +include $(CORE_DEPTH)/coreconf/config.mk +include config.mk + +CILIB = $(OBJDIR)/cilib.$(LIB_SUFFIX) +ORIG_CILIB = libci/$(OS_TARGET)$(OS_RELEASE).$(LIB_SUFFIX) + +ifeq (,$(filter-out WINNT WINCE,$(OS_TARGET))) # omits WIN16 WIN95 +ORIG_CILIB = libci/tssp32.lib +endif + +ifeq ($(OS_TARGET), WIN16) +ORIG_CILIB = libci/tssp.lib +endif + +ifeq ($(OS_TARGET), WIN95) +ORIG_CILIB = libci/tssp32.lib +endif + +ifeq (,$(filter-out WIN%,$(OS_TARGET))) +STUBDLL = $(OBJDIR)/stub.$(DLL_SUFFIX) +endif + +STUBLIB = $(OBJDIR)/stub.$(LIB_SUFFIX) + +ifeq ($(OS_TARGET), WIN16) +W16LIBS += $(CILIB) +else +EXTRA_LIBS += $(CILIB) +endif + +INST_JS = inst.js +LIBCI_JAR = $(OBJDIR)/libfort.jar +LIBCI_JAR_SRC = $(INST_JS) $(SHARED_LIBRARY) + +ifneq ($(OS_TARGET), WIN16) +TARGETS : $(LIBCI_JAR) +endif + +ifeq ($(OS_TARGET), WIN16) +# note that rules.mk is not included below for WIN16 +all: + @echo Skipping fortcrypt directory for 16-bit windows builds + +all_platforms alltags clean clobber clobber_all realclean: all + +boot export install libs program release: all + +endif + +$(SHARED_LIBRARY): $(CILIB) $(DIRS) + +cilib_name: + @echo $(CILIB) + +$(CILIB): + @$(MAKE_OBJDIR) + @if test -f $(ORIG_CILIB); then \ + echo "Copying $(ORIG_CILIB) to $@"; \ + cp $(ORIG_CILIB) $@; \ + else \ + echo "Making empty stub $@"; \ + $(MAKE) $(STUBLIB); \ + fi + @$(RANLIB) $@ + +$(STUBLIB): $(OBJDIR)/maci$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq (,$(filter-out WIN%,$(OS_TARGET))) + $(MAKE) $(STUBDLL) +else + $(AR) $< +endif + cp $@ $(CILIB) + +ifeq (,$(filter-out WIN%,$(OS_TARGET))) +$(STUBDLL): $(OBJDIR)/maci.o +ifdef NS_USE_GCC + $(LINK_DLL) -Wl,--out-implib,$(STUBLIB) $(OBJDIR)/maci.o $(OS_LIBS) +else + $(LINK_DLL) -MAP $(DLLBASE) $(subst /,\\,$(OBJDIR)/maci.o $(OS_LIBS)) +endif + +$(OBJDIR)/maci.o: maci.c +ifdef NS_USE_GCC + $(CC) -o $@ -c $(CFLAGS) $< +else + $(CC) -Fo$@ -c $(CFLAGS) $< +endif +endif + +# +# The following rules packages the shared library into a JAR, +# ready to be signed +# +$(OBJDIR)/replace: replace.c + $(CC) -o $@ $< + +# ZIP options: +# -5 means medium compression +# -q means quiet +# -j means do not store tree structure, all files go into one dir +# +$(LIBCI_JAR): $(DIRS) $(LIBCI_JAR_SRC) + @echo +++ building $@ from $(LIBCI_JAR_SRC) + @rm -f $@ + zip -5qj $@ $(LIBCI_JAR_SRC) + +force: + (cd swfort ; $(MAKE)) + + +MD_FILES += $(LIBCI_JAR) + +# coreconf doesn't build the AIX shared library for FORTEZZA, +# so I'm going to override their shared library command and build the shared +# library the way config used to. +# +ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1) +DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry +EXTRA_DSO_LDOPTS = -lc +MKSHLIB = svld $(DSO_LDOPTS) + +$(SHARED_LIBRARY): $(OBJS) + @$(MAKE_OBJDIR) + rm -f $@ + $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS) + chmod +x $@ +endif + +ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2) +LD += -G +endif + + +ifneq ($(OS_TARGET), WIN16) +include $(CORE_DEPTH)/coreconf/rules.mk +endif + +export:: private_export + + diff --git a/security/nss/lib/fortcrypt/config.mk b/security/nss/lib/fortcrypt/config.mk new file mode 100644 index 000000000..a454d139e --- /dev/null +++ b/security/nss/lib/fortcrypt/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 shared libraries +# are specifed as dependencies within rules.mk. +# + +TARGETS = $(SHARED_LIBRARY) +LIBRARY = +IMPORT_LIBRARY = +PROGRAM = + diff --git a/security/nss/lib/fortcrypt/cryptint.h b/security/nss/lib/fortcrypt/cryptint.h new file mode 100644 index 000000000..7760971da --- /dev/null +++ b/security/nss/lib/fortcrypt/cryptint.h @@ -0,0 +1,706 @@ +/* ***** 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 ***** */ +/* @(#)cryptint.h 1.26\t10 Nov 1995 */ +/***************************************************************************** + Definitive Fortezza header file. + Application Level Interface to Fortezza CI Library. + + Version for CI Library 1.52 + November 8, 1995 + + + NOTICE: Fortezza Export Policy + + The Fortezza Cryptologic Interface (CI) Library (both source and + object) and Fortezza CI Library based applications are defense + articles, as defined in the International Traffic In Arms + Regulations (ITAR), and are subject to export controls under the + ITAR and the Arms Export Control Act. Any export to any country + of (a) the Fortezza CI Library, related documentation, and + technical data, or (b) your cryptographic application, process, + or service that is the direct product of, or contains the + Fortezza CI Library must comply with the requirements of the ITAR. + If you or your customer intends to engage in such export, contact + the United States Department of State, Office of Defense Trade + Controls for specific guidance. + + + ****************************************************************************/ +#ifndef __CRYPTINT_H +#define __CRYPTINT_H + +#if __cplusplus__ || __cplusplus +extern "C" +{ +#endif /* C++ */ + +#ifndef PROTO_LIST +#ifdef _K_AND_R_ +#define PROTO_LIST(list) () +#else +#define PROTO_LIST(list) list +#endif /*_K_AND_R_ */ +#endif /* PROTO_LIST */ + + +#ifndef RETURN_TYPE +#if defined( _WIN32 ) || defined( __WIN32__ ) +#define RETURN_TYPE __declspec(dllimport) int +#elif defined( _WINDOWS ) || defined( _Windows ) +#define RETURN_TYPE extern int _far _pascal +#else +#define RETURN_TYPE extern int +#endif /* Windows */ +#endif /* RETURN_TYPE */ + +/* MS Visual C++ defines _MSDOS and _WINDOWS */ +/* Borland C/C++ defines __MSDOS__ and _Windows */ +#if defined( _WIN32 ) || defined ( __WIN32__ ) +#define CI_FAR +#elif defined( _WINDOWS ) || defined( _Windows ) +#define CI_FAR _far +#else +#define CI_FAR +#endif /* MS DOS or Windows */ + + +/***************************************************************************** + Constants + ****************************************************************************/ +#define CI_LIB_VERSION_VAL 0x0152 /* Version 1.52 */ + +#define CI_CERT_SIZE 2048 +#define CI_CERT_FLAGS_SIZE 16 +#define CI_CERT_NAME_SIZE 32 +#define CI_CHALLENGE_SIZE 20 + +#define CI_G_SIZE 128 + +#define CI_HASHVALUE_SIZE 20 + +#define CI_IV_SIZE 24 + +#define CI_KEY_SIZE 12 +#define CI_KS_SIZE 10 + +#define CI_NAME_SIZE 32 + +#define CI_PASSWORD_SIZE 24 +#define CI_PIN_SIZE 12 +#define CI_P_SIZE 128 + +#define CI_Q_SIZE 20 + +#define CI_R_SIZE 40 +#define CI_RANDOM_NO_SIZE 20 +#define CI_RANDOM_SEED_SIZE 8 +#define CI_RA_SIZE 128 +#define CI_RB_SIZE 128 +#define CI_REG_FLAGS_SIZE 4 + +#define CI_S_SIZE 40 +#define CI_SAVE_DATA_SIZE 28 +#define CI_SERIAL_NUMBER_SIZE 8 +#define CI_SIGNATURE_SIZE 40 +#define CI_STATUS_FLAGS_SIZE 4 + +#define CI_TIME_SIZE 16 +#define CI_TIMESTAMP_SIZE 16 + +#define CI_WRAPPED_X_SIZE 24 + +#define CI_Y_SIZE 128 + +#define CI_X_SIZE 20 + + +/* Miscellaneous */ +#define CI_NULL_FLAG 0 +#define CI_POWER_DOWN_FLAG 2 +#define CI_NO_LOG_OFF_FLAG 4 +#define CI_INITIATOR_FLAG 0 +#define CI_RECIPIENT_FLAG 1 + +#define CI_BLOCK_LOCK_FLAG 1 +#define CI_SSO_LOGGED_ON 0x40 +#define CI_USER_LOGGED_ON 0x00 +#define CI_FAST_MODE 0x10 +#define CI_SLOW_MODE 0x00 +#define CI_WORST_CASE_MODE 0x40 +#define CI_TYPICAL_CASE_MODE 0x00 + +/* Card Public Key Algorithms Types */ +#define CI_DSA_TYPE 0xA +#define CI_KEA_TYPE 0x5 +#define CI_DSA_KEA_TYPE 0xF + +/* Fortezza Pin Types */ +#define CI_SSO_PIN 0x25 +#define CI_USER_PIN 0x2A + +/* Crypto Types */ +#define CI_ENCRYPT_TYPE 0 +#define CI_DECRYPT_TYPE 1 +#define CI_HASH_TYPE 2 + +/* Save and Restore Types */ +#define CI_ENCRYPT_INT_TYPE 0x00 /* Internal Encryption */ +#define CI_ENCRYPT_EXT_TYPE 0x10 /* External Encryption */ +#define CI_DECRYPT_INT_TYPE 0x01 /* Internal Decryption */ +#define CI_DECRYPT_EXT_TYPE 0x11 /* External Decryption */ +#define CI_HASH_INT_TYPE 0x02 /* Internal Hash */ +#define CI_HASH_EXT_TYPE 0x12 /* External Hash */ +#define CI_TYPE_EXT_FLAG 0x10 /* Used to differentiate */ + +/* Configuration types */ +#define CI_SET_SPEED_TYPE 1 +#define CI_SET_TIMING_TYPE 2 + +/* Lock States */ +#define CI_SOCKET_UNLOCKED 0 +#define CI_HOLD_LOCK 1 +#define CI_SOCKET_LOCKED 2 + +/* Fortezza Crypto Types Modes */ +#define CI_ECB64_MODE 0 +#define CI_CBC64_MODE 1 +#define CI_OFB64_MODE 2 +#define CI_CFB64_MODE 3 +#define CI_CFB32_MODE 4 +#define CI_CFB16_MODE 5 +#define CI_CFB8_MODE 6 + +/* Card States */ +#define CI_POWER_UP 0 +#define CI_UNINITIALIZED 1 +#define CI_INITIALIZED 2 +#define CI_SSO_INITIALIZED 3 +#define CI_LAW_INITIALIZED 4 +#define CI_USER_INITIALIZED 5 +#define CI_STANDBY 6 +#define CI_READY 7 +#define CI_ZEROIZE 8 +#define CI_INTERNAL_FAILURE (-1) + +/* Flags for Firmware Update. */ +#define CI_NOT_LAST_BLOCK_FLAG 0x00000000UL +#define CI_LAST_BLOCK_FLAG 0x80000000UL +#define CI_DESTRUCTIVE_FLAG 0x000000FFUL +#define CI_NONDESTRUCTIVE_FLAG 0x0000FF00UL + + +/**************************************************************************** + Fortezza Library Return Codes + ***************************************************************************/ + +/* Card Responses */ +#define CI_OK 0 +#define CI_FAIL 1 +#define CI_CHECKWORD_FAIL 2 +#define CI_INV_TYPE 3 +#define CI_INV_MODE 4 +#define CI_INV_KEY_INDEX 5 +#define CI_INV_CERT_INDEX 6 +#define CI_INV_SIZE 7 +#define CI_INV_HEADER 8 +#define CI_INV_STATE 9 +#define CI_EXEC_FAIL 10 +#define CI_NO_KEY 11 +#define CI_NO_IV 12 +#define CI_NO_X 13 + +#define CI_NO_SAVE 15 +#define CI_REG_IN_USE 16 +#define CI_INV_COMMAND 17 +#define CI_INV_POINTER 18 +#define CI_BAD_CLOCK 19 +#define CI_NO_DSA_PARMS 20 + +/* Library Errors */ +#define CI_ERROR (-1) +#define CI_LIB_NOT_INIT (-2) +#define CI_CARD_NOT_READY (-3) +#define CI_CARD_IN_USE (-4) +#define CI_TIME_OUT (-5) +#define CI_OUT_OF_MEMORY (-6) +#define CI_NULL_PTR (-7) +#define CI_BAD_SIZE (-8) +#define CI_NO_DECRYPT (-9) +#define CI_NO_ENCRYPT (-10) +#define CI_NO_EXECUTE (-11) +#define CI_BAD_PARAMETER (-12) +#define CI_OUT_OF_RESOURCES (-13) + +#define CI_NO_CARD (-20) +#define CI_NO_DRIVER (-21) +#define CI_NO_CRDSRV (-22) +#define CI_NO_SCTSRV (-23) + +#define CI_BAD_CARD (-30) +#define CI_BAD_IOCTL (-31) +#define CI_BAD_READ (-32) +#define CI_BAD_SEEK (-33) +#define CI_BAD_WRITE (-34) +#define CI_BAD_FLUSH (-35) +#define CI_BAD_IOSEEK (-36) +#define CI_BAD_ADDR (-37) + +#define CI_INV_SOCKET_INDEX (-40) +#define CI_SOCKET_IN_USE (-41) +#define CI_NO_SOCKET (-42) +#define CI_SOCKET_NOT_OPENED (-43) +#define CI_BAD_TUPLES (-44) +#define CI_NOT_A_CRYPTO_CARD (-45) + +#define CI_INVALID_FUNCTION (-50) +#define CI_LIB_ALRDY_INIT (-51) +#define CI_SRVR_ERROR (-52) + + +/***************************************************************************** + Data Structures + ****************************************************************************/ + +typedef unsigned char CI_CERTIFICATE[CI_CERT_SIZE]; + +typedef unsigned char CI_CERT_FLAGS[CI_CERT_FLAGS_SIZE]; + +typedef unsigned char CI_CERT_STR[CI_CERT_NAME_SIZE+4]; + +typedef unsigned char CI_FAR *CI_DATA; + +typedef unsigned char CI_G[CI_G_SIZE]; + +typedef unsigned char CI_HASHVALUE[CI_HASHVALUE_SIZE]; + +typedef unsigned char CI_IV[CI_IV_SIZE]; + +typedef unsigned char CI_KEY[CI_KEY_SIZE]; + +typedef unsigned char CI_KS[CI_KS_SIZE]; + +typedef unsigned char CI_P[CI_P_SIZE]; + +typedef unsigned char CI_PASSWORD[CI_PASSWORD_SIZE + 4]; + +typedef unsigned char CI_PIN[CI_PIN_SIZE + 4]; + +typedef unsigned char CI_Q[CI_Q_SIZE]; + +typedef unsigned char CI_RA[CI_RA_SIZE]; + +typedef unsigned char CI_RB[CI_RB_SIZE]; + +typedef unsigned char CI_RANDOM[CI_RANDOM_NO_SIZE]; + +typedef unsigned char CI_RANDSEED[CI_RANDOM_SEED_SIZE]; + +typedef unsigned char CI_REG_FLAGS[CI_REG_FLAGS_SIZE]; + +typedef unsigned char CI_SIGNATURE[CI_SIGNATURE_SIZE]; + +typedef unsigned char CI_SAVE_DATA[CI_SAVE_DATA_SIZE]; + +typedef unsigned char CI_SERIAL_NUMBER[CI_SERIAL_NUMBER_SIZE]; + +typedef unsigned int CI_STATE, CI_FAR *CI_STATE_PTR; + +typedef unsigned char CI_TIME[CI_TIME_SIZE]; + +typedef unsigned char CI_TIMESTAMP[CI_TIMESTAMP_SIZE]; + +typedef unsigned char CI_WRAPPED_X[CI_WRAPPED_X_SIZE]; + +typedef unsigned char CI_Y[CI_Y_SIZE]; + +typedef unsigned char CI_X[CI_X_SIZE]; + +typedef struct { + int LibraryVersion; /* CI Library version */ + int ManufacturerVersion; /* Card's hardware version */ + char ManufacturerName[CI_NAME_SIZE+4]; /* Card manufacturer's name*/ + char ProductName[CI_NAME_SIZE+4]; /* Card's product name */ + char ProcessorType[CI_NAME_SIZE+4]; /* Card's processor type */ + unsigned long UserRAMSize; /* Amount of User RAM in bytes */ + unsigned long LargestBlockSize; /* Largest block of data to pass in */ + int KeyRegisterCount; /* Number of key registers */ + int CertificateCount; /* Maximum number of personalities (# certs-1) */ + int CryptoCardFlag; /* A flag that if non-zero indicates that there is + a Crypto-Card in the socket. If this value is + zero then there is NOT a Crypto-Card in the + sockets. */ + int ICDVersion; /* The ICD compliance level */ + int ManufacturerSWVer; /* The Manufacturer's Software Version */ + int DriverVersion; /* Driver Version */ +} CI_CONFIG, CI_FAR *CI_CONFIG_PTR; + +typedef struct { + int CertificateIndex; /* Index from 1 to CertificateCount */ + CI_CERT_STR CertLabel; /* The certificate label */ +} CI_PERSON, CI_FAR *CI_PERSON_PTR; + +typedef struct { + int CurrentSocket; /* The currently selected socket */ + int LockState; /* Lock status of the current socket */ + CI_SERIAL_NUMBER SerialNumber; /* Serial number of the Crypto Engine chip */ + CI_STATE CurrentState; /* State of The Card */ + int DecryptionMode; /* Decryption mode of The Card */ + int EncryptionMode; /* Encryption mode of The Card */ + int CurrentPersonality; /* Index of the current personality */ + int KeyRegisterCount; /* No. of Key Register on The Card */ + CI_REG_FLAGS KeyRegisterFlags; /* Bit Masks indicating Key Register use */ + int CertificateCount; /* No. of Certificates on The Card */ + CI_CERT_FLAGS CertificateFlags; /* Bit Mask indicating certificate use */ + unsigned char Flags[CI_STATUS_FLAGS_SIZE]; + /* Flag[0] : bit 6 for Condition mode */ + /* bit 4 for Clock mode */ +} CI_STATUS, CI_FAR *CI_STATUS_PTR; + + +/***************************************************************************** + Function Call Prototypes + ****************************************************************************/ + +RETURN_TYPE +CI_ChangePIN PROTO_LIST( ( + int PINType, + CI_PIN CI_FAR pOldPIN, + CI_PIN CI_FAR pNewPIN ) ); + +RETURN_TYPE +CI_CheckPIN PROTO_LIST( ( + int PINType, + CI_PIN CI_FAR pPIN ) ); + +RETURN_TYPE +CI_Close PROTO_LIST( ( + unsigned int Flags, + int SocketIndex ) ); + +RETURN_TYPE +CI_Decrypt PROTO_LIST( ( + unsigned int CipherSize, + CI_DATA pCipher, + CI_DATA pPlain ) ); + +RETURN_TYPE +CI_DeleteCertificate PROTO_LIST( ( + int CertificateIndex ) ); + +RETURN_TYPE +CI_DeleteKey PROTO_LIST( ( + int RegisterIndex ) ); + +RETURN_TYPE +CI_Encrypt PROTO_LIST( ( + unsigned int PlainSize, + CI_DATA pPlain, + CI_DATA pCipher ) ); + +RETURN_TYPE +CI_ExtractX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ); + +RETURN_TYPE +CI_FirmwareUpdate PROTO_LIST( ( + unsigned long Flags, + long Cksum, + unsigned int CksumLength, + unsigned int DataSize, + CI_DATA pData ) ); + +RETURN_TYPE +CI_GenerateIV PROTO_LIST( ( + CI_IV CI_FAR pIV ) ); + +RETURN_TYPE +CI_GenerateMEK PROTO_LIST( ( + int RegisterIndex, + int Reserved ) ); + +RETURN_TYPE +CI_GenerateRa PROTO_LIST( ( + CI_RA CI_FAR pRa ) ); + +RETURN_TYPE +CI_GenerateRandom PROTO_LIST( ( + CI_RANDOM CI_FAR pRandom ) ); + +RETURN_TYPE +CI_GenerateTEK PROTO_LIST( ( + int Flags, + int RegisterIndex, + CI_RA CI_FAR pRa, + CI_RB CI_FAR pRb, + unsigned int YSize, + CI_Y CI_FAR pY ) ); + +RETURN_TYPE +CI_GenerateX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + unsigned int YSize, + CI_Y CI_FAR pY ) ); + +RETURN_TYPE +CI_GetCertificate PROTO_LIST( ( + int CertificateIndex, + CI_CERTIFICATE CI_FAR pCertificate ) ); + +RETURN_TYPE +CI_GetConfiguration PROTO_LIST( ( + CI_CONFIG_PTR pConfiguration ) ); + +RETURN_TYPE +CI_GetHash PROTO_LIST( ( + unsigned int DataSize, + CI_DATA pData, + CI_HASHVALUE CI_FAR pHashValue ) ); + +RETURN_TYPE +CI_GetPersonalityList PROTO_LIST( ( + int EntryCount, + CI_PERSON CI_FAR pPersonalityList[] ) ); + +RETURN_TYPE +CI_GetState PROTO_LIST( ( + CI_STATE_PTR pState ) ); + +RETURN_TYPE +CI_GetStatus PROTO_LIST( ( + CI_STATUS_PTR pStatus ) ); + +RETURN_TYPE +CI_GetTime PROTO_LIST( ( + CI_TIME CI_FAR pTime ) ); + +RETURN_TYPE +CI_Hash PROTO_LIST( ( + unsigned int DataSize, + CI_DATA pData ) ); + +RETURN_TYPE +CI_Initialize PROTO_LIST( ( + int CI_FAR *SocketCount ) ); + +RETURN_TYPE +CI_InitializeHash PROTO_LIST( ( + void ) ); + +RETURN_TYPE +CI_InstallX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pWrappedX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ); + +RETURN_TYPE +CI_LoadCertificate PROTO_LIST( ( + int CertificateIndex, + CI_CERT_STR CI_FAR pCertLabel, + CI_CERTIFICATE CI_FAR pCertificate, + long Reserved ) ); + +RETURN_TYPE +CI_LoadDSAParameters PROTO_LIST( ( + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ); + +RETURN_TYPE +CI_LoadInitValues PROTO_LIST( ( + CI_RANDSEED CI_FAR pRandSeed, + CI_KS CI_FAR pKs ) ); + +RETURN_TYPE +CI_LoadIV PROTO_LIST( ( + CI_IV CI_FAR pIV ) ); + +RETURN_TYPE +CI_LoadX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + CI_X CI_FAR pX, + unsigned int YSize, + CI_Y CI_FAR pY ) ); + +RETURN_TYPE +CI_Lock PROTO_LIST( ( + int Flags ) ); + +RETURN_TYPE +CI_Open PROTO_LIST( ( + unsigned int Flags, + int SocketIndex ) ); + +RETURN_TYPE +CI_RelayX PROTO_LIST( ( + CI_PASSWORD CI_FAR pOldPassword, + unsigned int OldYSize, + CI_Y CI_FAR pOldY, + CI_RA CI_FAR pOldRa, + CI_WRAPPED_X CI_FAR pOldWrappedX, + CI_PASSWORD CI_FAR pNewPassword, + unsigned int NewYSize, + CI_Y CI_FAR pNewY, + CI_RA CI_FAR pNewRa, + CI_WRAPPED_X CI_FAR pNewWrappedX ) ); + +RETURN_TYPE +CI_Reset PROTO_LIST( ( + void ) ); + +RETURN_TYPE +CI_Restore PROTO_LIST( ( + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ); + +RETURN_TYPE +CI_Save PROTO_LIST( ( + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ); + +RETURN_TYPE +CI_Select PROTO_LIST( ( + int SocketIndex ) ); + +RETURN_TYPE +CI_SetConfiguration PROTO_LIST( ( + int Type, + unsigned int DataSize, + CI_DATA pData ) ); + +RETURN_TYPE +CI_SetKey PROTO_LIST( ( + int RegisterIndex ) ); + +RETURN_TYPE +CI_SetMode PROTO_LIST( ( + int CryptoType, + int CryptoMode ) ); + +RETURN_TYPE +CI_SetPersonality PROTO_LIST( ( + int CertificateIndex ) ); + +RETURN_TYPE +CI_SetTime PROTO_LIST( ( + CI_TIME CI_FAR pTime ) ); + +RETURN_TYPE +CI_Sign PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature ) ); + +RETURN_TYPE +CI_Terminate PROTO_LIST( ( + void ) ); + +RETURN_TYPE +CI_TimeStamp PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ); + +RETURN_TYPE +CI_Unlock PROTO_LIST( ( + void ) ); + +RETURN_TYPE +CI_UnwrapKey PROTO_LIST( ( + int UnwrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ); + +RETURN_TYPE +CI_VerifySignature PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_SIGNATURE CI_FAR pSignature ) ); + +RETURN_TYPE +CI_VerifyTimeStamp PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ); + +RETURN_TYPE +CI_WrapKey PROTO_LIST( ( + int WrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ); + +RETURN_TYPE +CI_Zeroize PROTO_LIST( ( + void ) ); + +#if __cplusplus__ || __cplusplus +} +#endif /* C++ */ + +#endif /* CRYPTINT_H */ diff --git a/security/nss/lib/fortcrypt/fmutex.c b/security/nss/lib/fortcrypt/fmutex.c new file mode 100644 index 000000000..6a75321e2 --- /dev/null +++ b/security/nss/lib/fortcrypt/fmutex.c @@ -0,0 +1,116 @@ +/* ***** 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 "fmutex.h" +#include "fpkmem.h" +#include <stdio.h> + +typedef struct PKMutexFunctions { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + int useMutex; +} PKMutexFunctions; + +static PKMutexFunctions gMutex = {NULL, NULL, NULL, NULL, 0}; +static int gInit = 0; + +#define FMUTEX_CHECKS() \ + if (gInit == 0) { \ + return CKR_GENERAL_ERROR; \ + } \ + if (!gMutex.useMutex) { \ + return CKR_GENERAL_ERROR; \ + } + +CK_RV FMUTEX_Init(CK_C_INITIALIZE_ARGS_PTR pArgs) { + if (gInit != 0) { + return CKR_GENERAL_ERROR; + } + + if (pArgs && pArgs->CreateMutex && pArgs->DestroyMutex && + pArgs->LockMutex && pArgs->UnlockMutex) { + + gMutex.CreateMutex = pArgs->CreateMutex; + gMutex.DestroyMutex = pArgs->DestroyMutex; + gMutex.LockMutex = pArgs->LockMutex; + gMutex.UnlockMutex = pArgs->UnlockMutex; + gMutex.useMutex = 1; + gInit = 1; + } else { + gInit = 0; + return CKR_GENERAL_ERROR; + } + + return CKR_OK; +} + + +CK_RV FMUTEX_Create(CK_VOID_PTR_PTR pMutex) { + CK_RV rv; + FMUTEX_CHECKS() + + rv = gMutex.CreateMutex(pMutex); + return rv; +} + +CK_RV FMUTEX_Destroy(CK_VOID_PTR pMutex) { + CK_RV rv; + FMUTEX_CHECKS() + + rv = gMutex.DestroyMutex(pMutex); + return rv; +} + +CK_RV FMUTEX_Lock(CK_VOID_PTR pMutex) { + CK_RV rv; + FMUTEX_CHECKS() + + rv = gMutex.LockMutex(pMutex); + return rv; +} + +CK_RV FMUTEX_Unlock(CK_VOID_PTR pMutex) { + CK_RV rv; + FMUTEX_CHECKS() + + rv = gMutex.UnlockMutex(pMutex); + return rv; +} + +int FMUTEX_MutexEnabled (void) { + return gMutex.useMutex; +} diff --git a/security/nss/lib/fortcrypt/fmutex.h b/security/nss/lib/fortcrypt/fmutex.h new file mode 100644 index 000000000..bfa8f10fe --- /dev/null +++ b/security/nss/lib/fortcrypt/fmutex.h @@ -0,0 +1,60 @@ +/* ***** 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 _FMUTEX_H_ +#define _FMUTEX_H_ 1 + +#include "fpkcs11t.h" + +/* + * All of these functions will return CK_RV values. + */ +extern CK_RV FMUTEX_Init(CK_C_INITIALIZE_ARGS_PTR pArgs); + + +extern CK_RV FMUTEX_Create(CK_VOID_PTR_PTR pMutex); + +extern CK_RV FMUTEX_Destroy(CK_VOID_PTR pMutex); + +extern CK_RV FMUTEX_Lock(CK_VOID_PTR pMutex); + +extern CK_RV FMUTEX_Unlock(CK_VOID_PTR pMutex); + +/* Returns 0 if mutexes have not been enabled. + * Returns 1 if mutexes have been enabled. + */ +extern int FMUTEX_MutexEnabled(void); + +#endif /*_FMUTEX_H_*/ diff --git a/security/nss/lib/fortcrypt/forsock.c b/security/nss/lib/fortcrypt/forsock.c new file mode 100644 index 000000000..7479f8dd4 --- /dev/null +++ b/security/nss/lib/fortcrypt/forsock.c @@ -0,0 +1,819 @@ +/* ***** 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 "fortsock.h" +#include "fpkmem.h" +#include "fmutex.h" +#include <string.h> +#include <stdlib.h> + +#define DEF_ENCRYPT_SIZE 0x8000 + +static unsigned char Fortezza_mail_Rb[128] = { +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1, +}; + +int InitSocket (FortezzaSocket *inSocket, int inSlotID) { + int ci_rv; + CK_RV mrv; + + if (inSocket == NULL) + return SOCKET_FAILURE; + + inSocket->isLoggedIn = PR_FALSE; + inSocket->personalitiesLoaded = PR_FALSE; + inSocket->isOpen = PR_FALSE; + inSocket->personalityList = NULL; + inSocket->keyRegisters = NULL; + inSocket->keys = NULL; + inSocket->numPersonalities = 0; + inSocket->numKeyRegisters = 0; + inSocket->hitCount = 0; + + inSocket->slotID = inSlotID; + ci_rv = MACI_GetSessionID(&(inSocket->maciSession)); + if (ci_rv != CI_OK) + return SOCKET_FAILURE; + + ci_rv = MACI_Open (inSocket->maciSession, 0, inSlotID); + if (ci_rv == CI_OK) { + inSocket->isOpen = PR_TRUE; + } else { + MACI_Close (inSocket->maciSession, CI_NULL_FLAG, inSlotID); + } + + if (FMUTEX_MutexEnabled()) { + mrv = FMUTEX_Create(&inSocket->registersLock); + if (mrv != CKR_OK) { + inSocket->registersLock = NULL; + } + } else { + inSocket->registersLock = NULL; + } + + return SOCKET_SUCCESS; +} + +int FreeSocket (FortezzaSocket *inSocket) { + if (inSocket->registersLock) { + FMUTEX_Destroy(inSocket->registersLock); + } + MACI_Close(inSocket->maciSession, CI_NULL_FLAG, inSocket->slotID); + return SOCKET_SUCCESS; +} + +int LoginToSocket (FortezzaSocket *inSocket, int inUserType, CI_PIN inPin) { + int ci_rv, i; + CI_STATUS ciStatus; + CI_CONFIG ciConfig; + FortezzaKey **oldRegisters, **newRegisters; + int oldCount; + HSESSION hs; + + if (inSocket == NULL || inSocket->isLoggedIn) + return SOCKET_FAILURE; + + hs = inSocket->maciSession; + ci_rv = MACI_Select (hs, inSocket->slotID); + if (ci_rv != CI_OK) + return ci_rv; + + ci_rv = MACI_CheckPIN(hs, inUserType, inPin); + + if (ci_rv != CI_OK) { + return ci_rv; + } + + ci_rv = MACI_GetStatus(hs, &ciStatus); + + if (ci_rv != CI_OK) { + if (ci_rv == CI_FAIL) { + ci_rv = CI_EXEC_FAIL; + } + return ci_rv; + } + + ci_rv = MACI_GetConfiguration(hs, &ciConfig); + if (ci_rv != CI_OK) { + return ci_rv; + } + + inSocket->isLoggedIn = PR_TRUE; + inSocket->hasLoggedIn = PR_TRUE; + PORT_Memcpy (inSocket->openCardSerial, ciStatus.SerialNumber, + sizeof (CI_SERIAL_NUMBER)); + inSocket->openCardState = ciStatus.CurrentState; + inSocket->numPersonalities = ciStatus.CertificateCount; + inSocket->numKeyRegisters = ciConfig.KeyRegisterCount; + newRegisters = + (FortezzaKey**)PORT_Alloc (sizeof(FortezzaKey)*ciConfig.KeyRegisterCount); + + FMUTEX_Lock(inSocket->registersLock); + oldRegisters = inSocket->keyRegisters; + oldCount = inSocket->numKeyRegisters; + inSocket->keyRegisters = newRegisters; + if (oldRegisters) { + for (i=0; i<oldCount; i++) { + if (oldRegisters[i]) { + oldRegisters[i]->keyRegister = KeyNotLoaded; + } + oldRegisters[i] = NULL; + } + PORT_Free(oldRegisters); + } + + if (inSocket->keyRegisters == NULL) { + FMUTEX_Unlock(inSocket->registersLock); + return SOCKET_FAILURE; + } + + for (i=0; i<ciConfig.KeyRegisterCount; i++) { + inSocket->keyRegisters[i] = NULL; + } + FMUTEX_Unlock(inSocket->registersLock); + + return SOCKET_SUCCESS; +} + +int LogoutFromSocket (FortezzaSocket *inSocket) { + if (inSocket == NULL) + return SOCKET_FAILURE; + + inSocket->isLoggedIn = PR_FALSE; + inSocket->hasLoggedIn = PR_FALSE; + if (UnloadPersonalityList(inSocket) != SOCKET_SUCCESS) + return SOCKET_FAILURE; + + + return SOCKET_SUCCESS; +} + + +int FetchPersonalityList(FortezzaSocket *inSocket) { + int rv; + + if (inSocket == NULL || inSocket->numPersonalities == 0) { + return SOCKET_FAILURE; + } + + rv = MACI_Select (inSocket->maciSession, inSocket->slotID); + + inSocket->personalityList = + (CI_PERSON*)PORT_Alloc (sizeof(CI_PERSON)*inSocket->numPersonalities); + + if (inSocket->personalityList == NULL) { + return SOCKET_FAILURE; + } + + rv = MACI_GetPersonalityList(inSocket->maciSession, + inSocket->numPersonalities, + inSocket->personalityList); + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + inSocket->personalitiesLoaded = PR_TRUE; + return SOCKET_SUCCESS; +} + +int UnloadPersonalityList(FortezzaSocket *inSocket) { + if (inSocket == NULL) + return SOCKET_FAILURE; + + inSocket->personalitiesLoaded = PR_FALSE; + if (inSocket->personalityList) { + PORT_Free(inSocket->personalityList); + } + inSocket->numPersonalities = 0; + inSocket->personalityList = NULL; + + return SOCKET_SUCCESS; +} + +PRBool SocketIsLoggedIn(CI_STATE status) { + + return (PRBool)((status == CI_READY) || (status == CI_STANDBY)); +} + +PRBool SocketStateUnchanged(FortezzaSocket* inSocket) { + CI_STATUS ciStatus; + int ciRV; + + ciRV = MACI_Select (inSocket->maciSession, inSocket->slotID); + if (ciRV != CI_OK) + return PR_FALSE; + + if (inSocket->hasLoggedIn && !inSocket->isLoggedIn) + return PR_FALSE; /* User Logged out from the socket */ + + /* + * Some vendor cards are slow. so if we think we are logged in, + * and the card still thinks we're logged in, we must have the same + * card. + */ + if (inSocket->isLoggedIn) { + CI_STATE state; + ciRV = MACI_GetState(inSocket->maciSession, &state); + if (ciRV != CI_OK) return PR_FALSE; + + return SocketIsLoggedIn(state); + } + + ciRV = MACI_GetStatus(inSocket->maciSession, &ciStatus); + if(ciRV != CI_OK) { + return PR_FALSE; + } + if (inSocket->isLoggedIn) { + if (PORT_Memcmp(ciStatus.SerialNumber, inSocket->openCardSerial, + sizeof (CI_SERIAL_NUMBER)) != 0) + return PR_FALSE; /* Serial Number of card in slot has changed */ + /* Probably means there is a new card */ + } + + if (inSocket->isLoggedIn && !SocketIsLoggedIn(ciStatus.CurrentState)) + return PR_FALSE; /* State of card changed. */ + /* Probably re-inserted same card */ + + return PR_TRUE; /* No change in the state of the socket */ +} + +/* + * can we regenerate this key on the fly? + */ +static PRBool +FortezzaIsRegenerating(FortezzaKey *key) { + /* TEK's are the only type of key that can't be regenerated */ + if (key->keyType != TEK) return PR_TRUE; + /* Client TEK's can never be regenerated */ + if (key->keyData.tek.flags == CI_INITIATOR_FLAG) return PR_FALSE; + /* Only Server TEK's that use the Mail protocol can be regenerated */ + return ((PRBool)(memcmp(key->keyData.tek.Rb,Fortezza_mail_Rb, + sizeof(key->keyData.tek.Rb)) == 0)); +} + +int GetBestKeyRegister(FortezzaSocket *inSocket) { + int i, candidate = -1, candidate2 = 1; + CK_ULONG minHitCount = 0xffffffff; + CK_ULONG minRegHitCount = 0xffffffff; + FortezzaKey **registers; + + registers = inSocket->keyRegisters; + for (i=1; i< inSocket->numKeyRegisters; i++) { + if (registers[i] == NULL) + return i; + } + + for (i=1; i < inSocket->numKeyRegisters; i++) { + if (registers[i]->hitCount < minHitCount) { + minHitCount = registers[i]->hitCount; + candidate2 = i; + } + + if (FortezzaIsRegenerating(registers[i]) && + (registers[i]->hitCount < minRegHitCount)) { + minRegHitCount = registers[i]->hitCount; + candidate = i; + } + } + + if (candidate == -1) + candidate = candidate2; + + return candidate; +} + +int SetFortezzaKeyHandle (FortezzaKey *inKey, CK_OBJECT_HANDLE inHandle) { + inKey->keyHandle = inHandle; + return SOCKET_SUCCESS; +} + +void +RemoveKey (FortezzaKey *inKey) { + if (inKey != NULL && inKey->keySocket->keyRegisters != NULL) { + if (inKey->keyRegister != KeyNotLoaded) { + FortezzaKey **registers = inKey->keySocket->keyRegisters; + registers[inKey->keyRegister] = NULL; + MACI_DeleteKey(inKey->keySocket->maciSession, inKey->keyRegister); + } + + PORT_Free(inKey); + } +} + +FortezzaKey *NewFortezzaKey(FortezzaSocket *inSocket, + FortezzaKeyType inKeyType, + CreateTEKInfo *TEKinfo, + int inKeyRegister) { + FortezzaKey *newKey, *oldKey; + FortezzaKey **registers; + HSESSION hs = inSocket->maciSession; + int ciRV; + + newKey = (FortezzaKey*)PORT_Alloc (sizeof(FortezzaKey)); + if (newKey == NULL) { + return NULL; + } + + newKey->keyHandle = 0; + newKey->keyRegister = KeyNotLoaded; + newKey->keyType = inKeyType; + newKey->keySocket = inSocket; + newKey->hitCount = 0; + newKey->id = TEKinfo ? TEKinfo->personality : 0; + + if (inKeyType != Ks && inSocket->keyRegisters) { + registers = inSocket->keyRegisters; + oldKey = registers[inKeyRegister]; + if (oldKey != NULL) { + oldKey->keyRegister = KeyNotLoaded; + } + + registers[inKeyRegister] = newKey; + newKey->hitCount = inSocket->hitCount++; + + MACI_DeleteKey (hs, inKeyRegister); + } + newKey->keyRegister = inKeyRegister; + + MACI_Lock(hs, CI_BLOCK_LOCK_FLAG); + switch (inKeyType) { + case MEK: + ciRV = MACI_GenerateMEK (hs, inKeyRegister, 0); + if (ciRV != CI_OK) { + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + MACI_WrapKey(hs, 0, inKeyRegister, newKey->keyData.mek); + break; + case TEK: + PORT_Memcpy (newKey->keyData.tek.Rb, TEKinfo->Rb, TEKinfo->randomLen); + PORT_Memcpy (newKey->keyData.tek.Ra, TEKinfo->Ra, TEKinfo->randomLen); + PORT_Memcpy (newKey->keyData.tek.pY, TEKinfo->pY, TEKinfo->YSize); + newKey->keyData.tek.ySize = TEKinfo->YSize; + newKey->keyData.tek.randomLen = TEKinfo->randomLen; + newKey->keyData.tek.registerIndex = TEKinfo->personality; + newKey->keyData.tek.flags = TEKinfo->flag; + + ciRV = MACI_SetPersonality(hs,TEKinfo->personality); + if (ciRV != CI_OK) { + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + ciRV = MACI_GenerateTEK(hs, TEKinfo->flag, inKeyRegister, + newKey->keyData.tek.Ra, TEKinfo->Rb, + TEKinfo->YSize, TEKinfo->pY); + if (ciRV != CI_OK) { + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + + + break; + case Ks: + break; + default: + RemoveKey(newKey); + MACI_Unlock(hs); + return NULL; + } + MACI_Unlock(hs); + return newKey; +} + +FortezzaKey *NewUnwrappedKey(int inKeyRegister, int id, + FortezzaSocket *inSocket) { + FortezzaKey *newKey; + + newKey = (FortezzaKey*)PORT_Alloc (sizeof(FortezzaKey)); + if (newKey == NULL) { + return NULL; + } + + newKey->keyRegister = inKeyRegister; + newKey->keyType = UNWRAP; + newKey->keySocket = inSocket; + newKey->id = id; + newKey->hitCount = inSocket->hitCount++; + MACI_WrapKey(inSocket->maciSession,0 , inKeyRegister, newKey->keyData.mek); + inSocket->keyRegisters[inKeyRegister] = newKey; + + return newKey; +} + +int LoadKeyIntoRegister (FortezzaKey *inKey) { + int registerIndex = GetBestKeyRegister(inKey->keySocket); + FortezzaSocket *socket = inKey->keySocket; + FortezzaKey **registers = socket->keyRegisters; + HSESSION hs = socket->maciSession; + FortezzaTEK *tek = &inKey->keyData.tek; + FortezzaKey *oldKey; + int rv = CI_FAIL; + + if (inKey->keyRegister != KeyNotLoaded) { + return inKey->keyRegister; + } + + oldKey = registers[registerIndex]; + + MACI_Select(hs, socket->slotID); + if (oldKey) { + oldKey->keyRegister = KeyNotLoaded; + } + MACI_DeleteKey (hs, registerIndex); + + switch (inKey->keyType) { + case TEK: + if (!FortezzaIsRegenerating(inKey)) { + return KeyNotLoaded; + } + if (MACI_SetPersonality(hs, tek->registerIndex) == CI_OK) { + rv = MACI_GenerateTEK (hs, tek->flags, registerIndex, + tek->Ra, tek->Rb, tek->ySize, + tek->pY); + } + if (rv != CI_OK) + return KeyNotLoaded; + break; + case MEK: + case UNWRAP: + rv = MACI_UnwrapKey (hs, 0, registerIndex, inKey->keyData.mek); + if (rv != CI_OK) + return KeyNotLoaded; + break; + default: + return KeyNotLoaded; + } + inKey->keyRegister = registerIndex; + registers[registerIndex] = inKey; + + return registerIndex; +} + +int InitCryptoOperation (FortezzaContext *inContext, + CryptoType inCryptoOperation) { + inContext->cryptoOperation = inCryptoOperation; + return SOCKET_SUCCESS; +} + +int EndCryptoOperation (FortezzaContext *inContext, + CryptoType inCryptoOperation) { + if (inCryptoOperation != inContext->cryptoOperation) { + return SOCKET_FAILURE; + } + inContext->cryptoOperation = None; + return SOCKET_SUCCESS; +} + +CryptoType GetCryptoOperation (FortezzaContext *inContext) { + return inContext->cryptoOperation; +} + +void InitContext(FortezzaContext *inContext, FortezzaSocket *inSocket, + CK_OBJECT_HANDLE hKey) { + inContext->fortezzaKey = NULL; + inContext->fortezzaSocket = inSocket; + inContext->session = NULL; + inContext->mechanism = NO_MECHANISM; + inContext->userRamSize = 0; + inContext->cryptoOperation = None; + inContext->hKey = hKey; +} + +extern PRBool fort11_FortezzaIsUserCert(unsigned char *label); + +static int +GetValidPersonality (FortezzaSocket *inSocket) { + int index = -1; /* return an invalid personalidyt if one isn't found */ + int i; + PRBool unLoadList = PR_FALSE; + int numPersonalities = 0; + + if (!inSocket->personalitiesLoaded) { + numPersonalities = inSocket->numPersonalities; + FetchPersonalityList (inSocket); + unLoadList = PR_TRUE; + } + + for (i=0; i<inSocket->numPersonalities; i++) { + if (fort11_FortezzaIsUserCert(inSocket->personalityList[i].CertLabel)) { + index = inSocket->personalityList[i].CertificateIndex; + break; + } + } + + if (unLoadList) { + UnloadPersonalityList(inSocket); + /* UnloadPersonality sets numPersonalities to zero, + * so we set it back to what it was when this function + * was called. + */ + inSocket->numPersonalities = numPersonalities; + } + return index; +} + +int RestoreState (FortezzaContext *inContext, CryptoType inType) { + FortezzaKey *key = inContext->fortezzaKey; + FortezzaSocket *socket = inContext->fortezzaSocket; + HSESSION hs = socket->maciSession; + CI_IV bogus_iv; + int rv, cryptoType = -1; + int personality = inContext->fortezzaKey->id; + + if (key == NULL) + return SOCKET_FAILURE; + + if (personality == 0) { + personality = GetValidPersonality (socket); + } + rv = MACI_SetPersonality(hs, personality); + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + /* + * The cards need to have some state bits set because + * save and restore don't necessarily save all the state. + * Instead of fixing the cards, they decided to change the + * protocol :(. + */ + switch (inType) { + case Encrypt: + rv = MACI_SetKey(hs, key->keyRegister); + if (rv != CI_OK) + break; + rv = MACI_GenerateIV (hs, bogus_iv); + cryptoType = CI_ENCRYPT_EXT_TYPE; + break; + case Decrypt: + rv = MACI_SetKey(hs, key->keyRegister); + rv = MACI_LoadIV (hs, inContext->cardIV); + cryptoType = CI_DECRYPT_EXT_TYPE; + break; + default: + rv = CI_INV_POINTER; + break; + } + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + /*PORT_Assert(cryptoType != -1); */ + + rv = MACI_Restore(hs, cryptoType, inContext->cardState); + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + return SOCKET_SUCCESS; +} + +int SaveState (FortezzaContext *inContext, CI_IV inIV, + PK11Session *inSession, FortezzaKey *inKey, + int inCryptoType, CK_MECHANISM_TYPE inMechanism){ + int ciRV; + FortezzaSocket *socket = inContext->fortezzaSocket; + HSESSION hs = socket->maciSession; + CI_CONFIG ciConfig; + + ciRV = MACI_Select (hs, socket->slotID); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + inContext->session = inSession; + inContext->fortezzaKey = inKey; + inContext->mechanism = inMechanism; + PORT_Memcpy (inContext->cardIV, inIV, sizeof (CI_IV)); + ciRV = MACI_Save(hs, inCryptoType, inContext->cardState); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + ciRV = MACI_GetConfiguration (hs, &ciConfig); + if (ciRV == CI_OK) { + inContext->userRamSize = ciConfig.LargestBlockSize; + } + + if (inContext->userRamSize == 0) inContext->userRamSize = 0x4000; + + return SOCKET_SUCCESS; +} + +int SocketSaveState (FortezzaContext *inContext, int inCryptoType) { + int ciRV; + + ciRV = MACI_Save (inContext->fortezzaSocket->maciSession, inCryptoType, + inContext->cardState); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + return SOCKET_SUCCESS; +} + +int DecryptData (FortezzaContext *inContext, + CK_BYTE_PTR inData, + CK_ULONG inDataLen, + CK_BYTE_PTR inDest, + CK_ULONG inDestLen) { + FortezzaSocket *socket = inContext->fortezzaSocket; + FortezzaKey *key = inContext->fortezzaKey; + HSESSION hs = socket->maciSession; + CK_ULONG defaultEncryptSize; + CK_ULONG left = inDataLen; + CK_BYTE_PTR loopin, loopout; + int rv = CI_OK; + + MACI_Select (hs, socket->slotID); + + defaultEncryptSize = (inContext->userRamSize > DEF_ENCRYPT_SIZE) + ? DEF_ENCRYPT_SIZE : inContext->userRamSize; + + if (key->keyRegister == KeyNotLoaded) { + rv = LoadKeyIntoRegister(key); + if (rv == KeyNotLoaded) { + return SOCKET_FAILURE; + } + } + + key->hitCount = socket->hitCount++; + loopin = inData; + loopout = inDest; + left = inDataLen; + rv = CI_OK; + + MACI_Lock(hs, CI_BLOCK_LOCK_FLAG); + RestoreState (inContext, Decrypt); + + while ((left > 0) && (rv == CI_OK)) { + CK_ULONG current = (left > defaultEncryptSize) + ? defaultEncryptSize : left; + rv = MACI_Decrypt(hs, current, loopin, loopout); + loopin += current; + loopout += current; + left -= current; + } + + MACI_Unlock(hs); + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + + rv = SocketSaveState (inContext, CI_DECRYPT_EXT_TYPE); + if (rv != SOCKET_SUCCESS) { + return rv; + } + + + return SOCKET_SUCCESS; +} + +int EncryptData (FortezzaContext *inContext, + CK_BYTE_PTR inData, + CK_ULONG inDataLen, + CK_BYTE_PTR inDest, + CK_ULONG inDestLen) { + FortezzaSocket *socket = inContext->fortezzaSocket; + FortezzaKey *key = inContext->fortezzaKey; + HSESSION hs = socket->maciSession; + CK_ULONG defaultEncryptSize; + CK_ULONG left = inDataLen; + CK_BYTE_PTR loopin, loopout; + int rv = CI_OK; + + MACI_Select (hs, socket->slotID); + + defaultEncryptSize = (inContext->userRamSize > DEF_ENCRYPT_SIZE) + ? DEF_ENCRYPT_SIZE : inContext->userRamSize; + if (key->keyRegister == KeyNotLoaded) { + rv = LoadKeyIntoRegister(key); + if (rv == KeyNotLoaded) { + return rv; + } + } + + key->hitCount = socket->hitCount++; + loopin = inData; + loopout = inDest; + + RestoreState (inContext,Encrypt); + + rv = CI_OK; + while ((left > 0) && (rv == CI_OK)) { + CK_ULONG current = (left > defaultEncryptSize) ? defaultEncryptSize : + left; + rv = MACI_Encrypt(hs, current, loopin, loopout); + loopin += current; + loopout += current; + left -= current; + } + + if (rv != CI_OK) { + return SOCKET_FAILURE; + } + + rv = SocketSaveState (inContext, CI_ENCRYPT_EXT_TYPE); + if (rv != SOCKET_SUCCESS) { + return rv; + } + + return SOCKET_SUCCESS; +} + +int WrapKey (FortezzaKey *wrappingKey, FortezzaKey *srcKey, + CK_BYTE_PTR pDest, CK_ULONG ulDestLen) { + int ciRV; + HSESSION hs = wrappingKey->keySocket->maciSession; + + if (wrappingKey->keyRegister == KeyNotLoaded) { + if (LoadKeyIntoRegister(wrappingKey) == KeyNotLoaded) { + return SOCKET_FAILURE; + } + } + + if (srcKey->id == 0) srcKey->id = wrappingKey->id; + + ciRV = MACI_WrapKey (hs, wrappingKey->keyRegister, + srcKey->keyRegister, pDest); + if (ciRV != CI_OK) { + return SOCKET_FAILURE; + } + + return SOCKET_SUCCESS; +} + +int UnwrapKey (CK_BYTE_PTR inWrappedKey, FortezzaKey *inUnwrapKey) { + int newIndex; + int ciRV; + FortezzaSocket *socket = inUnwrapKey->keySocket; + HSESSION hs = socket->maciSession; + FortezzaKey *oldKey; + + if (inUnwrapKey->keyRegister == KeyNotLoaded) { + if (LoadKeyIntoRegister(inUnwrapKey) == KeyNotLoaded) { + return KeyNotLoaded; + } + } + + ciRV = MACI_Select(hs, socket->slotID); + if (ciRV != CI_OK) { + return KeyNotLoaded; + } + + newIndex = GetBestKeyRegister(inUnwrapKey->keySocket); + oldKey = socket->keyRegisters[newIndex]; + + MACI_Select(hs, socket->slotID); + if (oldKey) { + oldKey->keyRegister = KeyNotLoaded; + socket->keyRegisters[newIndex] = NULL; + } + MACI_DeleteKey (hs, newIndex); + ciRV = MACI_UnwrapKey(hs,inUnwrapKey->keyRegister, newIndex, inWrappedKey); + if (ciRV != CI_OK) { + inUnwrapKey->keyRegister = KeyNotLoaded; + socket->keyRegisters[newIndex] = NULL; + return KeyNotLoaded; + } + + return newIndex; +} + diff --git a/security/nss/lib/fortcrypt/fortinst.htm b/security/nss/lib/fortcrypt/fortinst.htm new file mode 100644 index 000000000..d682176d4 --- /dev/null +++ b/security/nss/lib/fortcrypt/fortinst.htm @@ -0,0 +1,165 @@ +<HTML> +<TITLE>Generic PKCS #11 Installer</TITLE> +<-- + - ***** 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 ***** --> + +<SCRIPT> +// Crypto Mechanism Flags +PKCS11_MECH_RSA_FLAG = 0x1<<0; +PKCS11_MECH_DSA_FLAG = 0x1<<1; +PKCS11_MECH_RC2_FLAG = 0x1<<2; +PKCS11_MECH_RC4_FLAG = 0x1<<3; +PKCS11_MECH_DES_FLAG = 0x1<<4; +PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman +PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards +PKCS11_MECH_RC5_FLAG = 0x1<<7; +PKCS11_MECH_SHA1_FLAG = 0x1<<8; +PKCS11_MECH_MD5_FLAG = 0x1<<9; +PKCS11_MECH_MD2_FLAG = 0x1<<10; +PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator +PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in +PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default + +// Important: +// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should always be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which mechanisms should be turned on by +pkcs11MechanismFlags = 0; + + +// Ciphers that support SSL or S/MIME +PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0; + +// Important: +// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should ALWAYS be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which SSL ciphers are supported +pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG; + + +// Return values of pkcs11.addmodule() & pkcs11.delmodule() +// success codes +JS_OK_ADD_MODULE = 3 // Successfully added a module +JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module +JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module + +// failure codes +JS_ERR_OTHER = -1 // Other errors than the followings +JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action +JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments +JS_ERR_DEL_MODULE = -4 // Error deleting a module +JS_ERR_ADD_MODULE = -5 // Error adding a module +JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid +JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad +JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid +JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid + +var new_window; +var has_new_window = 0; + +function HandleCipher(checkBox) { + if (checkBox.checked) { + pkcs11MechanismFlags |= checkBox.value; + } else { + pkcs11MechanismFlags &= ~checkBox.value; + } +} + +function HandleSSL(checkBox) { + if (checkBox.checked) { + pkcs11CipherFlags |= checkBox.value; + } else { + pkcs11CipherFlags &= ~checkBox.value; + } +} + +function colonize(string) { + len = string.length; + end = len -1; + + if (len == 0) return string; + + + for (i=0; i < len; i++) { + if (string.charAt(i) == "/") { + if (i == 0) { + new_string = ":" + string.substring(1,len); + } else if (i == end) { + new_string = string.substring(0,i)+':'; + } else { + new_string = string.substring(0,i)+':'+ + string.substring(i+1,len); + } + string = new_string; + } + } + + if (string.charAt(0) == ":") string = string.substring(1,len); + return string; +} + +function DoInstall(name,module) { + if ((navigator.platform == "MacPPC") + || (navigator.platform == "Mac68K")) { + module = colonize(module); + } + result = pkcs11.addmodule(name, module, + pkcs11MechanismFlags, pkcs11CipherFlags); + if ( result < 0) { + window.alert("New module setup failed. Error code: " + result); + } + if (has_new_window) new_window.close(); +} + +default_name = "Netscape FORTEZZA Module" + +default_module = "D:/dogbert/ns/dist/WIN32_D.OBJ/bin/fort32.dll" +document.writeln("<FORM name=instform target=_self> <H2>FORTEZZA PKCS #11 Installer version 1.5</H2>"); +document.writeln(" Module name: <Input Type=Text Name=modName value=\""+default_name+"\" size=50 required><br>"); +document.writeln(" Module Library: <Input Type=FILE required Name=module><br>"); +document.writeln("<i>Note: If you use the browse button, be sure to change the filter to show all the files (*), not just the HTML files (*.html).</i><p>"); +document.writeln("<hr>"); +document.write("<Input type=submit Name=Install Value=Install onclick=DoInstall("); +document.writeln( "document.instform.modName.value,document.instform.module.value) >"); +document.writeln("</FORM>"); +</SCRIPT> diff --git a/security/nss/lib/fortcrypt/fortpk11.c b/security/nss/lib/fortcrypt/fortpk11.c new file mode 100644 index 000000000..92d917fce --- /dev/null +++ b/security/nss/lib/fortcrypt/fortpk11.c @@ -0,0 +1,4540 @@ +/* ***** 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 "fpkmem.h" +#include "seccomon.h" +#include "fpkcs11.h" +#include "fpkcs11i.h" +#include "cryptint.h" +#include "pk11func.h" +#include "fortsock.h" +#include "fmutex.h" +#ifdef notdef +#include <ctype.h> +#include <stdio.h> +#endif + +/* sigh */ +#ifndef EOF +/* stdio was not included */ +extern int sprintf(char *out, char *fmt, ...); +#endif + +#ifdef XP_MAC +#ifndef __POWERPC__ +#include <A4Stuff.h> +#endif + + +/* This is not a 4.0 project, so I can't depend on + * 4.0 defines, so instead I depend on CodeWarrior + * defines. I define XP_MAC in fpkmem.h + */ +#if __POWERPC__ +#elif __CFM68K__ +#else +/* These include are taken fromn npmac.cpp which are used + * by the plugin group to properly set-up a plug-in for + * dynamic loading on 68K. + */ + +#include <Quickdraw.h> + +/* +** The Mixed Mode procInfos defined in npupp.h assume Think C- +** style calling conventions. These conventions are used by +** Metrowerks with the exception of pointer return types, which +** in Metrowerks 68K are returned in A0, instead of the standard +** D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers, +** Mixed Mode will return the values to a 68K plugin in D0, but +** a 68K plugin compiled by Metrowerks will expect the result in +** A0. The following pragma forces Metrowerks to use D0 instead. +*/ +#ifdef __MWERKS__ +#ifndef powerc +#pragma pointers_in_D0 +#endif +#endif + +#ifdef __MWERKS__ +#ifndef powerc +#pragma pointers_in_A0 +#endif +#endif + +/* The following fix for static initializers fixes a previous +** incompatibility with some parts of PowerPlant. +*/ +#ifdef __MWERKS__ +#ifdef __cplusplus + extern "C" { +#endif +#ifndef powerc + extern void __InitCode__(void); +#else + extern void __sinit(void); +#endif + extern void __destroy_global_chain(void); +#ifdef __cplusplus + } +#endif /* __cplusplus */ +#endif /* __MWERKS__ */ + +#endif +#endif + + +typedef struct { + unsigned char *data; + int len; +} CertItem; + + +/* + * ******************** Static data ******************************* + */ + +/* The next three strings must be exactly 32 characters long */ +static char *manufacturerID = "Netscape Communications Corp "; +static char *libraryDescription = "Communicator Fortezza Crypto Svc"; + +typedef enum {DSA_KEY, KEA_KEY, V1_KEY, INVALID_KEY } PrivKeyType; + +static PK11Slot fort11_slot[NUM_SLOTS]; +static FortezzaSocket fortezzaSockets[NUM_SLOTS]; +static PRBool init = PR_FALSE; +static CK_ULONG kNumSockets = 0; + +#define __PASTE(x,y) x##y + + +#undef CK_FUNC +#undef CK_EXTERN +#undef CK_NEED_ARG_LIST +#undef _CK_RV + +#define fort11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen +#define fort11_SlotFromSession pk11_SlotFromSession +#define fort11_isToken pk11_isToken + +static CK_FUNCTION_LIST fort11_funcList = { + { 2, 1 }, + +#undef CK_FUNC +#undef CK_EXTERN +#undef CK_NEED_ARG_LIST +#undef _CK_RV + +#define CK_EXTERN +#define CK_FUNC(name) name, +#define _CK_RV + +#include "fpkcs11f.h" + +}; + +#undef CK_FUNC +#undef CK_EXTERN +#undef _CK_RV + + +#undef __PASTE +#undef pk11_SlotFromSessionHandle +#undef pk11_SlotFromID + +#define MAJOR_VERSION_MASK 0xFF00 +#define MINOR_VERSION_MASK 0x00FF + +/* Mechanisms */ +struct mechanismList { + CK_MECHANISM_TYPE type; + CK_MECHANISM_INFO domestic; + PRBool privkey; +}; + +static struct mechanismList mechanisms[] = { + {CKM_DSA, {512,1024,CKF_SIGN}, PR_TRUE}, + {CKM_SKIPJACK_KEY_GEN, {92, 92, CKF_GENERATE}, PR_TRUE}, + {CKM_SKIPJACK_CBC64, {92, 92, CKF_ENCRYPT | CKF_DECRYPT}, PR_TRUE}, + {CKM_SKIPJACK_WRAP, {92, 92, CKF_WRAP}, PR_TRUE}, + {CKM_KEA_KEY_DERIVE, {128, 128, CKF_DERIVE}, PR_TRUE}, +}; +static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]); + +/*************Static function prototypes********************************/ +static PRBool fort11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type); +static void fort11_FreeAttribute(PK11Attribute *attribute); +static void fort11_DestroyAttribute(PK11Attribute *attribute); +static PK11Object* fort11_NewObject(PK11Slot *slot); +static PK11FreeStatus fort11_FreeObject(PK11Object *object); +static CK_RV fort11_AddAttributeType(PK11Object *object, + CK_ATTRIBUTE_TYPE type, + void *valPtr, + CK_ULONG length); +static void fort11_AddSlotObject(PK11Slot *slot, PK11Object *object); +static PK11Attribute* fort11_FindAttribute(PK11Object *object, + CK_ATTRIBUTE_TYPE type); +static PK11Attribute* fort11_NewAttribute(CK_ATTRIBUTE_TYPE type, + CK_VOID_PTR value, CK_ULONG len); +static void fort11_DeleteAttributeType(PK11Object *object, + CK_ATTRIBUTE_TYPE type); +static void fort11_AddAttribute(PK11Object *object, + PK11Attribute *attribute); +static void fort11_AddObject(PK11Session *session, + PK11Object *object); +static PK11Object * fort11_ObjectFromHandle(CK_OBJECT_HANDLE handle, + PK11Session *session); +static void fort11_DeleteObject(PK11Session *session,PK11Object *object); +static CK_RV fort11_DestroyObject(PK11Object *object); +void fort11_FreeSession(PK11Session *session); + +#define FIRST_SLOT_SESS_ID 0x00000100L +#define ADD_NEXT_SESS_ID 0x00000100L +#define SLOT_MASK 0x000000FFL + +#define FAILED CKR_FUNCTION_FAILED + +static void +fort11_FreeFortezzaKey (void *inFortezzaKey) { + RemoveKey ((FortezzaKey*) inFortezzaKey); +} + +static void +fort11_DestroySlotObjects (PK11Slot *slot, PK11Session *session) { + PK11Object *currObject, *nextObject = NULL, *oldObject; + int i; + + for (i=0; i<HASH_SIZE; i++) { + currObject = slot->tokObjects[i]; + slot->tokObjects[i] = NULL; + do { + FMUTEX_Lock(slot->sessionLock); + + if (currObject) { + nextObject = currObject->next; + FMUTEX_Lock(currObject->refLock); + currObject->refCount++; + FMUTEX_Unlock(currObject->refLock); + fort11_DeleteObject(session, currObject); + } + FMUTEX_Unlock(slot->sessionLock); + if (currObject) { + oldObject = currObject; + currObject = nextObject; + fort11_FreeObject(oldObject); + } + } while (currObject != NULL); + } +} + +static void +fort11_TokenRemoved(PK11Slot *slot, PK11Session *session) { + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + + LogoutFromSocket (socket); + slot->isLoggedIn = PR_FALSE; + if (session && session->notify) { + /*If no session pointer exists, lots of leaked memory*/ + session->notify (session->handle, CKN_SURRENDER, + session->appData); + fort11_FreeSession(session); /* Release the reference held + * by the slot with the session + */ + } + + fort11_DestroySlotObjects(slot, session); + fort11_FreeSession(session); /* Release the reference held + * by the slot with the session + */ + + /* All keys will have been freed at this point so we can + * NULL out this pointer + */ + socket->keys = NULL; + +} + +PRBool +fort11_FortezzaIsUserCert(unsigned char * label) { + + if ( (!PORT_Memcmp(label, "KEAK", 4)) || /* v3 user certs */ + (!PORT_Memcmp(label, "DSA1", 4)) || + (!PORT_Memcmp(label, "DSAI", 4)) || + (!PORT_Memcmp(label, "DSAO", 4)) || + (!PORT_Memcmp(label, "INKS", 4)) || /* v1 user certs */ + (!PORT_Memcmp(label, "INKX", 4)) || + (!PORT_Memcmp(label, "ONKS", 4)) || + (!PORT_Memcmp(label, "ONKX", 4)) || + (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 user certs */ + (!PORT_Memcmp(label, "3OXS", 4)) || + (!PORT_Memcmp(label, "3IKX", 4)) ) { + + return PR_TRUE; + + } else { return PR_FALSE; } + +} + +static PRBool +fort11_FortezzaIsACert(unsigned char * label) { + if (label == NULL) return PR_FALSE; + + if ( (!PORT_Memcmp(label, "DSA1", 4)) || /* v3 certs */ + (!PORT_Memcmp(label, "DSAI", 4)) || + (!PORT_Memcmp(label, "DSAO", 4)) || + (!PORT_Memcmp(label, "DSAX", 4)) || + (!PORT_Memcmp(label, "KEAK", 4)) || + (!PORT_Memcmp(label, "KEAX", 4)) || + (!PORT_Memcmp(label, "CAX1", 4)) || + (!PORT_Memcmp(label, "PCA1", 4)) || + (!PORT_Memcmp(label, "PAA1", 4)) || + (!PORT_Memcmp(label, "ICA1", 4)) || + + (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 certs */ + (!PORT_Memcmp(label, "3OXS", 4)) || + (!PORT_Memcmp(label, "3CAX", 4)) || + (!PORT_Memcmp(label, "3IKX", 4)) || + (!PORT_Memcmp(label, "3PCA", 4)) || + (!PORT_Memcmp(label, "3PAA", 4)) || + (!PORT_Memcmp(label, "3ICA", 4)) || + + (!PORT_Memcmp(label, "INKS", 4)) || /* v1 certs */ + (!PORT_Memcmp(label, "INKX", 4)) || + (!PORT_Memcmp(label, "ONKS", 4)) || + (!PORT_Memcmp(label, "ONKX", 4)) || + (!PORT_Memcmp(label, "RRXX", 4)) || + (!PORT_Memcmp(label, "RTXX", 4)) || + (!PORT_Memcmp(label, "LAXX", 4)) ) { + + return PR_TRUE; + + } + + return PR_FALSE; +} + +static +int fort11_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); +} + +unsigned char *fort11_data_start(unsigned char *buf, int length, + int *data_length, PRBool includeTag) { + 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; + } + if (includeTag) *data_length += used_length; + + return (buf + (includeTag ? 0 : used_length)); +} + +int +fort11_GetCertFields(unsigned char *cert,int cert_length,CertItem *issuer, + CertItem *serial,CertItem *subject) +{ + unsigned char *buf; + int buf_length; + unsigned char *date; + int datelen; + + /* get past the signature wrap */ + buf = fort11_data_start(cert,cert_length,&buf_length,PR_FALSE); + if (buf == NULL) return FAILED; + /* get into the raw cert data */ + buf = fort11_data_start(buf,buf_length,&buf_length,PR_FALSE); + if (buf == NULL) return FAILED; + /* skip past any optional version number */ + if ((buf[0] & 0xa0) == 0xa0) { + date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE); + if (date == NULL) return FAILED; + buf_length -= (date-buf) + datelen; + buf = date + datelen; + } + /* serial number */ + serial->data = fort11_data_start(buf,buf_length,&serial->len,PR_FALSE); + if (serial->data == NULL) return FAILED; + buf_length -= (serial->data-buf) + serial->len; + buf = serial->data + serial->len; + /* skip the OID */ + date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE); + if (date == NULL) return FAILED; + buf_length -= (date-buf) + datelen; + buf = date + datelen; + /* issuer */ + issuer->data = fort11_data_start(buf,buf_length,&issuer->len,PR_TRUE); + if (issuer->data == NULL) return FAILED; + buf_length -= (issuer->data-buf) + issuer->len; + buf = issuer->data + issuer->len; + /* skip the date */ + date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE); + if (date == NULL) return FAILED; + buf_length -= (date-buf) + datelen; + buf = date + datelen; + /*subject */ + subject->data=fort11_data_start(buf,buf_length,&subject->len,PR_TRUE); + if (subject->data == NULL) return FAILED; + buf_length -= (subject->data-buf) + subject->len; + buf = subject->data +subject->len; + /*subject */ + return CKR_OK; +} + +/* quick tohex function to get rid of scanf */ +static +int fort11_tohex(char *s) { + int val = 0; + + for(;*s;s++) { + if ((*s >= '0') && (*s <= '9')) { + val = (val << 4) + (*s - '0'); + continue; + } else if ((*s >= 'a') && (*s <= 'f')) { + val = (val << 4) + (*s - 'a') + 10; + continue; + } else if ((*s >= 'A') && (*s <= 'F')) { + val = (val << 4) + (*s - 'A') + 10; + continue; + } + break; + } + return val; +} + +/* only should be called for V3 KEA cert labels. */ + +static int +fort11_GetSibling(CI_CERT_STR label) { + + int value = 0; + char s[3]; + + label +=4; + + strcpy(s,"00"); + memcpy(s, label, 2); + value = fort11_tohex(s); + + /* sibling of 255 means no sibling */ + if (value == 255) { + value = -1; + } + + return value; +} + + +static PrivKeyType +fort11_GetKeyType(CI_CERT_STR label) { + if (label == NULL) return INVALID_KEY; + + if ( (!PORT_Memcmp(label, "DSA1", 4)) || /* v3 certs */ + (!PORT_Memcmp(label, "DSAI", 4)) || + (!PORT_Memcmp(label, "DSAO", 4)) || + (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 certs */ + (!PORT_Memcmp(label, "3OXS", 4)) ) { + + return DSA_KEY; + } + + + if ( (!PORT_Memcmp(label, "KEAK", 4)) || + (!PORT_Memcmp(label, "3IKX", 4)) ) { + return KEA_KEY; + } + + if ( (!PORT_Memcmp(label, "INKS", 4)) || /* V1 Certs*/ + (!PORT_Memcmp(label, "INKX", 4)) || + (!PORT_Memcmp(label, "ONKS", 4)) || + (!PORT_Memcmp(label, "ONKX", 4)) || + (!PORT_Memcmp(label, "RRXX", 4)) || + (!PORT_Memcmp(label, "RTXX", 4)) || + (!PORT_Memcmp(label, "LAXX", 4)) ) { + + return V1_KEY; + } + + return INVALID_KEY; +} + +static CK_RV +fort11_ConvertToDSAKey(PK11Object *privateKey, PK11Slot *slot) { + CK_KEY_TYPE key_type = CKK_DSA; + CK_BBOOL cktrue = TRUE; + CK_BBOOL ckfalse = FALSE; + CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; + CK_CHAR label[] = "A DSA Private Key"; + + + /* Fill in the common Default values */ + if (fort11_AddAttributeType(privateKey,CKA_START_DATE, NULL, 0) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey,CKA_END_DATE, NULL, 0) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey,CKA_SUBJECT, NULL, 0) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_CLASS, &privClass, + sizeof (CK_OBJECT_CLASS)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_KEY_TYPE, &key_type, + sizeof(CK_KEY_TYPE)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType (privateKey, CKA_TOKEN, &cktrue, + sizeof (CK_BBOOL)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType (privateKey, CKA_LABEL, label, + PORT_Strlen((char*)label)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_SENSITIVE, &cktrue, + sizeof (CK_BBOOL)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_SIGN, &cktrue, + sizeof (CK_BBOOL)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(privateKey, CKA_DERIVE, &cktrue, + sizeof(cktrue)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_LOCAL, &ckfalse, + sizeof(ckfalse)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_DECRYPT, &ckfalse, + sizeof(ckfalse)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_SIGN_RECOVER, &ckfalse, + sizeof(ckfalse)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_UNWRAP, &ckfalse, + sizeof(ckfalse)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_EXTRACTABLE, &ckfalse, + sizeof(ckfalse)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_ALWAYS_SENSITIVE, &cktrue, + sizeof(cktrue)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_NEVER_EXTRACTABLE, &cktrue, + sizeof(ckfalse)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_PRIME, NULL, 0) != CKR_OK){ + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_SUBPRIME, NULL, 0) != CKR_OK){ + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_BASE, NULL, 0) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_VALUE, NULL, 0) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_PRIVATE, &cktrue, + sizeof(cktrue)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_MODIFIABLE,&ckfalse, + sizeof(ckfalse)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + FMUTEX_Lock(slot->objectLock); + privateKey->handle = slot->tokenIDCount++; + privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV); + FMUTEX_Unlock(slot->objectLock); + privateKey->objclass = privClass; + privateKey->slot = slot; + privateKey->inDB = PR_TRUE; + + + return CKR_OK; +} + +static int +fort11_LoadRootPAAKey(PK11Slot *slot, PK11Session *session) { + CK_OBJECT_CLASS theClass = CKO_SECRET_KEY; + int id = 0; + CK_BBOOL True = TRUE; + CK_BBOOL False = FALSE; + CK_CHAR label[] = "Trusted Root PAA Key"; + PK11Object *rootKey; + FortezzaKey *newKey; + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + + /*Don't know the key type. Does is matter?*/ + + rootKey = fort11_NewObject(slot); + + if (rootKey == NULL) { + return CKR_HOST_MEMORY; + } + + if (fort11_AddAttributeType(rootKey, CKA_CLASS, &theClass, + sizeof(theClass)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(rootKey, CKA_TOKEN, &True, + sizeof(True)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(rootKey, CKA_LABEL, label, + sizeof(label)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(rootKey, CKA_PRIVATE, &True, + sizeof (True)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(rootKey,CKA_MODIFIABLE, &False, + sizeof(False)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(rootKey, CKA_ID, &id, + sizeof(int)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(rootKey, CKA_DERIVE, &True, + sizeof(True)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + if (fort11_AddAttributeType(rootKey, CKA_SENSITIVE, &True, + sizeof(True)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + FMUTEX_Lock(slot->objectLock); + rootKey->handle = slot->tokenIDCount++; + rootKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV); + FMUTEX_Unlock(slot->objectLock); + + rootKey->objclass = theClass; + rootKey->slot = slot; + rootKey->inDB = PR_TRUE; + + newKey = NewFortezzaKey(socket, Ks, NULL, 0); + if (newKey == NULL) { + fort11_FreeObject(rootKey); + return CKR_HOST_MEMORY; + } + + rootKey->objectInfo = (void*)newKey; + rootKey->infoFree = fort11_FreeFortezzaKey; + fort11_AddObject(session, rootKey); + + return CKR_OK; +} + +static CK_RV +fort11_ConvertToKEAKey (PK11Object *privateKey, PK11Slot *slot) { + CK_OBJECT_CLASS theClass = CKO_PRIVATE_KEY; + CK_KEY_TYPE keyType = CKK_KEA; + CK_CHAR label[] = "A KEA private key Object"; + CK_BBOOL True = TRUE; + CK_BBOOL False = FALSE; + + if (fort11_AddAttributeType(privateKey, CKA_CLASS, &theClass, + sizeof (CK_OBJECT_CLASS)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_KEY_TYPE, &keyType, + sizeof (CK_KEY_TYPE)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_TOKEN, &True, + sizeof(CK_BBOOL)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType (privateKey, CKA_LABEL, label, + PORT_Strlen((char*)label)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType (privateKey, CKA_SENSITIVE, + &True, sizeof(CK_BBOOL)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType (privateKey, CKA_DERIVE, + &True, sizeof(CK_BBOOL)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_PRIVATE, &True, + sizeof(True)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_START_DATE, NULL, 0) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_END_DATE, NULL, 0) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + if (fort11_AddAttributeType(privateKey, CKA_LOCAL, &False, + sizeof(False)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + FMUTEX_Lock(slot->objectLock); + privateKey->handle = slot->tokenIDCount++; + privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV); + FMUTEX_Unlock(slot->objectLock); + privateKey->objclass = theClass; + privateKey->slot = slot; + privateKey->inDB = PR_TRUE; + + return CKR_OK; +} + +static CK_RV +fort11_ConvertToV1Key (PK11Object* privateKey, PK11Slot *slot) { + CK_RV rv; + CK_BBOOL True = TRUE; + + rv = fort11_ConvertToDSAKey(privateKey, slot); + if (rv != CKR_OK) { + return rv; + } + + if (fort11_AddAttributeType(privateKey, CKA_DERIVE, &True, + sizeof (CK_BBOOL)) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + return CKR_OK; +} + +static CK_RV +fort11_NewPrivateKey(PK11Object *privKeyObject, PK11Slot *slot,CI_PERSON currPerson) { + PrivKeyType keyType = fort11_GetKeyType(currPerson.CertLabel); + CK_RV rv; + + switch (keyType) { + case DSA_KEY: + rv = fort11_ConvertToDSAKey(privKeyObject, slot); + break; + case KEA_KEY: + rv = fort11_ConvertToKEAKey(privKeyObject, slot); + break; + case V1_KEY: + rv = fort11_ConvertToV1Key(privKeyObject, slot); + break; + default: + rv = CKR_GENERAL_ERROR; + break; + } + return rv; +} + + +PRBool +fort11_LoadCertObjectForSearch(CI_PERSON currPerson, PK11Slot *slot, + PK11Session *session, CI_PERSON *pers_array) { + PK11Object *certObject, *privKeyObject; + PK11Attribute *attribute, *newAttribute; + int ci_rv; + CI_CERTIFICATE cert; + CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; + CK_CERTIFICATE_TYPE certType = CKC_X_509; + CK_BBOOL cktrue = TRUE; + CK_BBOOL ckfalse = FALSE; + CertItem issuer, serial, subject; + int certSize; + char nickname[50]; + char *cursor; + PrivKeyType priv_key; + int sibling; + + + certObject = fort11_NewObject(slot); + if (certObject == NULL) + return PR_FALSE; + + ci_rv = MACI_GetCertificate (fortezzaSockets[slot->slotID-1].maciSession, + currPerson.CertificateIndex, cert); + if (ci_rv != CI_OK){ + fort11_FreeObject(certObject); + return PR_FALSE; + } + + ci_rv = fort11_GetCertFields(cert,CI_CERT_SIZE,&issuer,&serial,&subject); + + if (ci_rv != CKR_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + + if (fort11_AddAttributeType(certObject, CKA_CLASS, &certClass, + sizeof (CK_OBJECT_CLASS)) != CKR_OK) { + fort11_FreeObject (certObject); + return PR_FALSE; + } + if (fort11_AddAttributeType(certObject, CKA_TOKEN, &cktrue, + sizeof (CK_BBOOL)) != CKR_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + if (fort11_AddAttributeType(certObject, CKA_PRIVATE, &ckfalse, + sizeof (CK_BBOOL)) != CKR_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + + + /* check if the label represents a KEA key. if so, the + nickname should be made the same as the corresponding DSA + sibling cert. */ + + priv_key = fort11_GetKeyType(currPerson.CertLabel); + + if (priv_key == KEA_KEY) { + sibling = fort11_GetSibling(currPerson.CertLabel); + + /* check for failure of fort11_GetSibling. also check that + the sibling is not zero. */ + + if (sibling > 0) { + /* assign the KEA cert label to be the same as the + sibling DSA label */ + + sprintf (nickname, "%s", &pers_array[sibling-1].CertLabel[8] ); + } else { + sprintf (nickname, "%s", &currPerson.CertLabel[8]); + } + } else { + sprintf (nickname, "%s", &currPerson.CertLabel[8]); + } + + cursor = nickname+PORT_Strlen(nickname)-1; + while ((*cursor) == ' ') { + cursor--; + } + cursor[1] = '\0'; + if (fort11_AddAttributeType(certObject, CKA_LABEL, nickname, + PORT_Strlen(nickname)) != CKR_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + + + + if (fort11_AddAttributeType(certObject, CKA_CERTIFICATE_TYPE, &certType, + sizeof(CK_CERTIFICATE_TYPE)) != CKR_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + certSize = fort11_cert_length(cert,CI_CERT_SIZE); + if (fort11_AddAttributeType (certObject, CKA_VALUE, cert, certSize) + != CI_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + if (fort11_AddAttributeType(certObject, CKA_ISSUER, issuer.data, + issuer.len) != CKR_OK) { + fort11_FreeObject (certObject); + return PR_FALSE; + } + if (fort11_AddAttributeType(certObject, CKA_SUBJECT, subject.data, + subject.len) != CKR_OK) { + fort11_FreeObject (certObject); + return PR_FALSE; + } + if (fort11_AddAttributeType(certObject, CKA_SERIAL_NUMBER, + serial.data, serial.len) != CKR_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + /*Change this to a byte array later*/ + if (fort11_AddAttributeType(certObject, CKA_ID, + &currPerson.CertificateIndex, + sizeof(int)) != CKR_OK) { + fort11_FreeObject(certObject); + return PR_FALSE; + } + certObject->objectInfo = NULL; + certObject->infoFree = NULL; + + certObject->objclass = certClass; + certObject->slot = slot; + certObject->inDB = PR_TRUE; + + FMUTEX_Lock(slot->objectLock); + + certObject->handle = slot->tokenIDCount++; + certObject->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT); + + FMUTEX_Unlock(slot->objectLock); + + if (fort11_FortezzaIsUserCert (currPerson.CertLabel)) { + privKeyObject = fort11_NewObject(slot); + if (fort11_NewPrivateKey(privKeyObject, slot, currPerson) != CKR_OK) { + fort11_FreeObject(privKeyObject); + fort11_FreeObject(certObject); + return PR_FALSE; + } + if(fort11_AddAttributeType(privKeyObject,CKA_ID, + &currPerson.CertificateIndex, + sizeof(int)) != CKR_OK) { + fort11_FreeObject(privKeyObject); + fort11_FreeObject(certObject); + return PR_FALSE; + } + attribute = fort11_FindAttribute(certObject,CKA_SUBJECT); + newAttribute= + fort11_NewAttribute(pk11_attr_expand(&attribute->attrib)); + fort11_FreeAttribute(attribute); + if (newAttribute != NULL) { + fort11_DeleteAttributeType(privKeyObject, + CKA_SUBJECT); + fort11_AddAttribute(privKeyObject, + newAttribute); + } + fort11_AddObject (session, privKeyObject); + } + + + fort11_AddObject (session, certObject); + + + return PR_TRUE; +} + +#define TRUSTED_PAA "00000000Trusted Root PAA" + +static int +fort11_BuildCertObjects(FortezzaSocket *currSocket, PK11Slot *slot, + PK11Session *session) { + + int i; + CI_PERSON rootPAA; + + PORT_Memcpy (rootPAA.CertLabel, TRUSTED_PAA, 1+PORT_Strlen (TRUSTED_PAA)); + rootPAA.CertificateIndex = 0; + + if (!fort11_LoadCertObjectForSearch(rootPAA, slot, session, + currSocket->personalityList)) { + return CKR_GENERAL_ERROR; + } + + if (fort11_LoadRootPAAKey(slot, session) != CKR_OK) { + return CKR_GENERAL_ERROR; + } + + for (i=0 ; i < currSocket->numPersonalities; i++) { + if (fort11_FortezzaIsACert (currSocket->personalityList[i].CertLabel)){ + if (!fort11_LoadCertObjectForSearch(currSocket->personalityList[i], + slot, session, + currSocket->personalityList)){ + return CKR_GENERAL_ERROR; + } + } + } + + return CKR_OK; +} + +PK11Slot* +fort11_SlotFromSessionHandle(CK_SESSION_HANDLE inHandle) { + CK_SESSION_HANDLE whichSlot = inHandle & SLOT_MASK; + + if (whichSlot >= kNumSockets) return NULL_PTR; + + return &fort11_slot[whichSlot]; +} + +PK11Slot* +fort11_SlotFromID (CK_SLOT_ID inSlotID) { + if (inSlotID == 0 || inSlotID > kNumSockets) + return NULL; + + return &fort11_slot[inSlotID-1]; +} + +CK_ULONG fort11_firstSessionID (int inSlotNum) { + return (CK_ULONG)(inSlotNum); +} + +/* + * Utility to convert passed in PIN to a CI_PIN + */ +void fort11_convertToCIPin (CI_PIN ciPin,CK_CHAR_PTR pPin, CK_ULONG ulLen) { + unsigned long i; + + for (i=0; i<ulLen; i++) { + ciPin[i] = pPin[i]; + } + ciPin[ulLen] = '\0'; +} + + +/* + * return true if object has attribute + */ +static PRBool +fort11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type) { + PK11Attribute *attribute; + + FMUTEX_Lock(object->attributeLock); + pk11queue_find(attribute,type,object->head,HASH_SIZE); + FMUTEX_Unlock(object->attributeLock); + + return (PRBool)(attribute != NULL); +} + +/* + * create a new attribute with type, value, and length. Space is allocated + * to hold value. + */ +static PK11Attribute * +fort11_NewAttribute(CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value, CK_ULONG len) { + PK11Attribute *attribute; + CK_RV mrv; + + attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute)); + if (attribute == NULL) return NULL; + + attribute->attrib.type = type; + if (value) { + attribute->attrib.pValue = (CK_VOID_PTR)PORT_Alloc(len); + if (attribute->attrib.pValue == NULL) { + PORT_Free(attribute); + return NULL; + } + PORT_Memcpy(attribute->attrib.pValue,value,len); + attribute->attrib.ulValueLen = len; + } else { + attribute->attrib.pValue = NULL; + attribute->attrib.ulValueLen = 0; + } + attribute->handle = type; + attribute->next = attribute->prev = NULL; + attribute->refCount = 1; + if (FMUTEX_MutexEnabled()) { + mrv = FMUTEX_Create (&attribute->refLock); + if (mrv != CKR_OK) { + if (attribute->attrib.pValue) PORT_Free(attribute->attrib.pValue); + PORT_Free(attribute); + return NULL; + } + } else { + attribute->refLock = NULL; + } + + return attribute; +} + +/* + * add an attribute to an object + */ +static +void fort11_AddAttribute(PK11Object *object,PK11Attribute *attribute) { + FMUTEX_Lock (object->attributeLock); + pk11queue_add(attribute,attribute->handle,object->head,HASH_SIZE); + FMUTEX_Unlock(object->attributeLock); +} + +static CK_RV +fort11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr, + CK_ULONG length) { + PK11Attribute *attribute; + attribute = fort11_NewAttribute(type,valPtr,length); + if (attribute == NULL) { return CKR_HOST_MEMORY; } + fort11_AddAttribute(object,attribute); + return CKR_OK; +} + + + +/* Make sure a given attribute exists. If it doesn't, initialize it to + * value and len + */ +static CK_RV +fort11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *value, + unsigned int len) { + if ( !fort11_hasAttribute(object, type)) { + return fort11_AddAttributeType(object,type,value,len); + } + return CKR_OK; +} + +/* + * look up and attribute structure from a type and Object structure. + * The returned attribute is referenced and needs to be freed when + * it is no longer needed. + */ +static PK11Attribute * +fort11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type) { + PK11Attribute *attribute; + + FMUTEX_Lock(object->attributeLock); + pk11queue_find(attribute,type,object->head,HASH_SIZE); + if (attribute) { + /* atomic increment would be nice here */ + FMUTEX_Lock(attribute->refLock); + attribute->refCount++; + FMUTEX_Unlock(attribute->refLock); + } + FMUTEX_Unlock(object->attributeLock); + + return(attribute); +} + +/* + * this is only valid for CK_BBOOL type attributes. Return the state + * of that attribute. + */ +static PRBool +fort11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type) { + PK11Attribute *attribute; + PRBool tok = PR_FALSE; + + attribute=fort11_FindAttribute(object,type); + if (attribute == NULL) { return PR_FALSE; } + tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue); + fort11_FreeAttribute(attribute); + + return tok; +} + +/* + * add an object to a slot and session queue + */ +static +void fort11_AddSlotObject(PK11Slot *slot, PK11Object *object) { + FMUTEX_Lock(slot->objectLock); + pk11queue_add(object,object->handle,slot->tokObjects,HASH_SIZE); + FMUTEX_Unlock(slot->objectLock); +} + +static +void fort11_AddObject(PK11Session *session, PK11Object *object) { + PK11Slot *slot = fort11_SlotFromSession(session); + + if (!fort11_isToken(object->handle)) { + FMUTEX_Lock(session->objectLock); + pk11queue_add(&object->sessionList,0,session->objects,0); + FMUTEX_Unlock(session->objectLock); + } + fort11_AddSlotObject(slot,object); +} + +/* + * free all the data associated with an object. Object reference count must + * be 'zero'. + */ +static CK_RV +fort11_DestroyObject(PK11Object *object) { + int i; + CK_RV crv = CKR_OK; +/* PORT_Assert(object->refCount == 0);*/ + + if (object->label) PORT_Free(object->label); + + /* clean out the attributes */ + /* since no one is referencing us, it's safe to walk the chain + * without a lock */ + for (i=0; i < HASH_SIZE; i++) { + PK11Attribute *ap,*next; + for (ap = object->head[i]; ap != NULL; ap = next) { + next = ap->next; + /* paranoia */ + ap->next = ap->prev = NULL; + fort11_FreeAttribute(ap); + } + object->head[i] = NULL; + } + FMUTEX_Destroy(object->attributeLock); + FMUTEX_Destroy(object->refLock); + if (object->objectInfo) { + (*object->infoFree)(object->objectInfo); + } + PORT_Free(object); + return crv; +} + + +/* + * release a reference to an attribute structure + */ +static void +fort11_FreeAttribute(PK11Attribute *attribute) { + PRBool destroy = PR_FALSE; + + FMUTEX_Lock(attribute->refLock); + if (attribute->refCount == 1) destroy = PR_TRUE; + attribute->refCount--; + FMUTEX_Unlock(attribute->refLock); + + if (destroy) fort11_DestroyAttribute(attribute); +} + + +/* + * release a reference to an object handle + */ +static PK11FreeStatus +fort11_FreeObject(PK11Object *object) { + PRBool destroy = PR_FALSE; + CK_RV crv; + + FMUTEX_Lock(object->refLock); + if (object->refCount == 1) destroy = PR_TRUE; + object->refCount--; + FMUTEX_Unlock(object->refLock); + + if (destroy) { + crv = fort11_DestroyObject(object); + if (crv != CKR_OK) { + return PK11_DestroyFailure; + } + return PK11_Destroyed; + } + return PK11_Busy; +} + +static void +fort11_update_state(PK11Slot *slot,PK11Session *session) { + if (slot->isLoggedIn) { + if (slot->ssoLoggedIn) { + session->info.state = CKS_RW_SO_FUNCTIONS; + } else if (session->info.flags & CKF_RW_SESSION) { + session->info.state = CKS_RW_USER_FUNCTIONS; + } else { + session->info.state = CKS_RO_USER_FUNCTIONS; + } + } else { + if (session->info.flags & CKF_RW_SESSION) { + session->info.state = CKS_RW_PUBLIC_SESSION; + } else { + session->info.state = CKS_RO_PUBLIC_SESSION; + } + } +} + +/* update the state of all the sessions on a slot */ +static void +fort11_update_all_states(PK11Slot *slot) { + int i; + PK11Session *session; + + for (i=0; i < SESSION_HASH_SIZE; i++) { + FMUTEX_Lock(slot->sessionLock); + for (session = slot->head[i]; session; session = session->next) { + fort11_update_state(slot,session); + } + FMUTEX_Unlock(slot->sessionLock); + } +} + + +/* + * Create a new object + */ +static PK11Object * +fort11_NewObject(PK11Slot *slot) { + PK11Object *object; + CK_RV mrv; + int i; + + object = (PK11Object*)PORT_Alloc(sizeof(PK11Object)); + if (object == NULL) return NULL; + + object->handle = 0; + object->next = object->prev = NULL; + object->sessionList.next = NULL; + object->sessionList.prev = NULL; + object->sessionList.parent = object; + object->inDB = PR_FALSE; + object->label = NULL; + object->refCount = 1; + object->session = NULL; + object->slot = slot; + object->objclass = 0xffff; + if (FMUTEX_MutexEnabled()) { + mrv = FMUTEX_Create(&object->refLock); + if (mrv != CKR_OK) { + PORT_Free(object); + return NULL; + } + mrv = FMUTEX_Create(&object->attributeLock); + if (mrv != CKR_OK) { + FMUTEX_Destroy(object->refLock); + PORT_Free(object); + return NULL; + } + } else { + object->attributeLock = NULL; + object->refLock = NULL; + } + for (i=0; i < HASH_SIZE; i++) { + object->head[i] = NULL; + } + object->objectInfo = NULL; + object->infoFree = NULL; + return object; +} + +/* + * look up and object structure from a handle. OBJECT_Handles only make + * sense in terms of a given session. make a reference to that object + * structure returned. + */ +static PK11Object * fort11_ObjectFromHandle(CK_OBJECT_HANDLE handle, + PK11Session *session) { + PK11Object **head; + void *lock; + PK11Slot *slot = fort11_SlotFromSession(session); + PK11Object *object; + + /* + * Token objects are stored in the slot. Session objects are stored + * with the session. + */ + head = slot->tokObjects; + lock = slot->objectLock; + + FMUTEX_Lock(lock); + pk11queue_find(object,handle,head,HASH_SIZE); + if (object) { + FMUTEX_Lock(object->refLock); + object->refCount++; + FMUTEX_Unlock(object->refLock); + } + FMUTEX_Unlock(lock); + + return(object); +} + +/* + * add an object to a slot andsession queue + */ +static +void fort11_DeleteObject(PK11Session *session, PK11Object *object) { + PK11Slot *slot; + + if (session == NULL) + return; + slot = fort11_SlotFromSession(session); + if (!fort11_isToken(object->handle)) { + FMUTEX_Lock(session->objectLock); + pk11queue_delete(&object->sessionList,0,session->objects,0); + FMUTEX_Unlock(session->objectLock); + } + FMUTEX_Lock(slot->objectLock); + pk11queue_delete(object,object->handle,slot->tokObjects,HASH_SIZE); + FMUTEX_Unlock(slot->objectLock); + fort11_FreeObject(object); +} + + + +/* + * ******************** Search Utilities ******************************* + */ + +/* add an object to a search list */ +CK_RV +fort11_AddToList(PK11ObjectListElement **list,PK11Object *object) { + PK11ObjectListElement *newelem = + (PK11ObjectListElement *)PORT_Alloc(sizeof(PK11ObjectListElement)); + + if (newelem == NULL) return CKR_HOST_MEMORY; + + newelem->next = *list; + newelem->object = object; + FMUTEX_Lock(object->refLock); + object->refCount++; + FMUTEX_Unlock(object->refLock); + + *list = newelem; + return CKR_OK; +} + + +/* + * free a single list element. Return the Next object in the list. + */ +PK11ObjectListElement * +fort11_FreeObjectListElement(PK11ObjectListElement *objectList) { + PK11ObjectListElement *ol = objectList->next; + + fort11_FreeObject(objectList->object); + PORT_Free(objectList); + return ol; +} + +/* free an entire object list */ +void +fort11_FreeObjectList(PK11ObjectListElement *objectList) { + PK11ObjectListElement *ol; + + for (ol= objectList; ol != NULL; ol = fort11_FreeObjectListElement(ol)) {} +} + +/* + * free a search structure + */ +void +fort11_FreeSearch(PK11SearchResults *search) { + if (search->handles) { + PORT_Free(search->handles); + } + PORT_Free(search); +} + + +/* + * Free up all the memory associated with an attribute. Reference count + * must be zero to call this. + */ +static void +fort11_DestroyAttribute(PK11Attribute *attribute) { + /*PORT_Assert(attribute->refCount == 0);*/ + FMUTEX_Destroy(attribute->refLock); + if (attribute->attrib.pValue) { + /* clear out the data in the attribute value... it may have been + * sensitive data */ + PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen); + PORT_Free(attribute->attrib.pValue); + } + PORT_Free(attribute); +} + +/* + * delete an attribute from an object + */ +static void +fort11_DeleteAttribute(PK11Object *object, PK11Attribute *attribute) { + FMUTEX_Lock(object->attributeLock); + if (attribute->next || attribute->prev) { + pk11queue_delete(attribute,attribute->handle, + object->head,HASH_SIZE); + } + FMUTEX_Unlock(object->attributeLock); + fort11_FreeAttribute(attribute); +} + +/* + * decode when a particular attribute may be modified + * PK11_NEVER: This attribute must be set at object creation time and + * can never be modified. + * PK11_ONCOPY: This attribute may be modified only when you copy the + * object. + * PK11_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from + * FALSE to TRUE. + * PK11_ALWAYS: This attribute can always be modified. + * Some attributes vary their modification type based on the class of the + * object. + */ +PK11ModifyType +fort11_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) { + /* if we don't know about it, user user defined, always allow modify */ + PK11ModifyType mtype = PK11_ALWAYS; + + switch(type) { + /* NEVER */ + case CKA_CLASS: + case CKA_CERTIFICATE_TYPE: + case CKA_KEY_TYPE: + case CKA_MODULUS: + case CKA_MODULUS_BITS: + case CKA_PUBLIC_EXPONENT: + case CKA_PRIVATE_EXPONENT: + case CKA_PRIME: + case CKA_SUBPRIME: + case CKA_BASE: + case CKA_PRIME_1: + case CKA_PRIME_2: + case CKA_EXPONENT_1: + case CKA_EXPONENT_2: + case CKA_COEFFICIENT: + case CKA_VALUE_LEN: + mtype = PK11_NEVER; + break; + + /* ONCOPY */ + case CKA_TOKEN: + case CKA_PRIVATE: + mtype = PK11_ONCOPY; + break; + + /* SENSITIVE */ + case CKA_SENSITIVE: + mtype = PK11_SENSITIVE; + break; + + /* ALWAYS */ + case CKA_LABEL: + case CKA_APPLICATION: + case CKA_ID: + case CKA_SERIAL_NUMBER: + case CKA_START_DATE: + case CKA_END_DATE: + case CKA_DERIVE: + case CKA_ENCRYPT: + case CKA_DECRYPT: + case CKA_SIGN: + case CKA_VERIFY: + case CKA_SIGN_RECOVER: + case CKA_VERIFY_RECOVER: + case CKA_WRAP: + case CKA_UNWRAP: + mtype = PK11_ALWAYS; + break; + + /* DEPENDS ON CLASS */ + case CKA_VALUE: + mtype = (inClass == CKO_DATA) ? PK11_ALWAYS : PK11_NEVER; + break; + + case CKA_SUBJECT: + mtype = (inClass == CKO_CERTIFICATE) ? PK11_NEVER : PK11_ALWAYS; + break; + default: + break; + } + return mtype; +} + +/* decode if a particular attribute is sensitive (cannot be read + * back to the user of if the object is set to SENSITIVE) */ +PRBool +fort11_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) { + switch(type) { + /* ALWAYS */ + case CKA_PRIVATE_EXPONENT: + case CKA_PRIME_1: + case CKA_PRIME_2: + case CKA_EXPONENT_1: + case CKA_EXPONENT_2: + case CKA_COEFFICIENT: + return PR_TRUE; + + /* DEPENDS ON CLASS */ + case CKA_VALUE: + /* PRIVATE and SECRET KEYS have SENSITIVE values */ + return (PRBool)((inClass == CKO_PRIVATE_KEY) || + (inClass == CKO_SECRET_KEY)); + + default: + break; + } + return PR_FALSE; +} + +static void +fort11_DeleteAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type) { + PK11Attribute *attribute; + attribute = fort11_FindAttribute(object, type); + if (attribute == NULL) return ; + fort11_DeleteAttribute(object,attribute); +} + + +/* + * create a new nession. NOTE: The session handle is not set, and the + * session is not added to the slot's session queue. + */ +static PK11Session * +fort11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, + CK_VOID_PTR pApplication, + CK_FLAGS flags) { + PK11Session *session; + PK11Slot *slot = &fort11_slot[slotID-1]; + CK_RV mrv; + + if (slot == NULL) return NULL; + + session = (PK11Session*)PORT_Alloc(sizeof(PK11Session)); + if (session == NULL) return NULL; + + session->next = session->prev = NULL; + session->refCount = 1; + session->context = NULL; + session->search = NULL; + session->objectIDCount = 1; + session->fortezzaContext.fortezzaKey = NULL; + session->fortezzaContext.fortezzaSocket = NULL; + + if (FMUTEX_MutexEnabled()) { + mrv = FMUTEX_Create(&session->refLock); + if (mrv != CKR_OK) { + PORT_Free(session); + return NULL; + } + mrv = FMUTEX_Create(&session->objectLock); + if (mrv != CKR_OK) { + FMUTEX_Destroy(session->refLock); + PORT_Free(session); + return NULL; + } + } else { + session->refLock = NULL; + session->objectLock = NULL; + } + + session->objects[0] = NULL; + + session->slot = slot; + session->notify = notify; + session->appData = pApplication; + session->info.flags = flags; + session->info.slotID = slotID; + fort11_update_state(slot,session); + return session; +} + + +/* + * look up a session structure from a session handle + * generate a reference to it. + */ +PK11Session * +fort11_SessionFromHandle(CK_SESSION_HANDLE handle, PRBool isCloseSession) { + PK11Slot *slot = fort11_SlotFromSessionHandle(handle); + PK11Session *session; + + if (!isCloseSession && + !SocketStateUnchanged(&fortezzaSockets[slot->slotID-1])) + return NULL; + + FMUTEX_Lock(slot->sessionLock); + pk11queue_find(session,handle,slot->head,SESSION_HASH_SIZE); + if (session) session->refCount++; + FMUTEX_Unlock(slot->sessionLock); + + return (session); +} + +/* free all the data associated with a session. */ +static void +fort11_DestroySession(PK11Session *session) +{ + PK11ObjectList *op,*next; +/* PORT_Assert(session->refCount == 0);*/ + + /* clean out the attributes */ + FMUTEX_Lock(session->objectLock); + for (op = session->objects[0]; op != NULL; op = next) { + next = op->next; + /* paranoia */ + op->next = op->prev = NULL; + fort11_DeleteObject(session,op->parent); + } + FMUTEX_Unlock(session->objectLock); + + FMUTEX_Destroy(session->objectLock); + FMUTEX_Destroy(session->refLock); + + if (session->search) { + fort11_FreeSearch(session->search); + } + + pk11queue_delete(session, session->handle, session->slot->head, + SESSION_HASH_SIZE); + + PORT_Free(session); +} + + +/* + * release a reference to a session handle + */ +void +fort11_FreeSession(PK11Session *session) { + PRBool destroy = PR_FALSE; + PK11Slot *slot = NULL; + + if (!session) return; /*Quick fix to elminate crash*/ + /*Fix in later version */ + + if (FMUTEX_MutexEnabled()) { + slot = fort11_SlotFromSession(session); + FMUTEX_Lock(slot->sessionLock); + } + if (session->refCount == 1) destroy = PR_TRUE; + session->refCount--; + if (FMUTEX_MutexEnabled()) { + FMUTEX_Unlock(slot->sessionLock); + } + + if (destroy) { + fort11_DestroySession(session); + } +} + + +/* return true if the object matches the template */ +PRBool +fort11_objectMatch(PK11Object *object,CK_ATTRIBUTE_PTR theTemplate,int count) { + int i; + + for (i=0; i < count; i++) { + PK11Attribute *attribute = + fort11_FindAttribute(object,theTemplate[i].type); + if (attribute == NULL) { + return PR_FALSE; + } + if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) { + if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue, + theTemplate[i].ulValueLen) == 0) { + fort11_FreeAttribute(attribute); + continue; + } + } + fort11_FreeAttribute(attribute); + return PR_FALSE; + } + return PR_TRUE; +} + +/* search through all the objects in the queue and return the template matches + * in the object list. + */ +CK_RV +fort11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head, + void *lock, CK_ATTRIBUTE_PTR theTemplate, int count) { + int i; + PK11Object *object; + CK_RV rv; + + for(i=0; i < HASH_SIZE; i++) { + /* We need to hold the lock to copy a consistant version of + * the linked list. */ + FMUTEX_Lock(lock); + for (object = head[i]; object != NULL; object= object->next) { + if (fort11_objectMatch(object,theTemplate,count)) { + rv = fort11_AddToList(objectList,object); + if (rv != CKR_OK) { + return rv; + } + } + } + FMUTEX_Unlock(lock); + } + return CKR_OK; +} + +static PRBool +fort11_NotAllFuncsNULL (CK_C_INITIALIZE_ARGS_PTR pArgs) { + return (PRBool)(pArgs && pArgs->CreateMutex && pArgs->DestroyMutex && + pArgs->LockMutex && pArgs->UnlockMutex); +} + +static PRBool +fort11_InArgCheck(CK_C_INITIALIZE_ARGS_PTR pArgs) { + PRBool rv; + /* The only check for now, is to make sure that all of the + * function pointers are either all NULL or all Non-NULL. + * We also need to make sure the pReserved field in pArgs is + * set to NULL. + */ + if (pArgs == NULL) { + return PR_TRUE; /* If the argument is NULL, no + * inconsistencies can exist. + */ + } + + if (pArgs->pReserved != NULL) { + return PR_FALSE; + } + + if (pArgs->CreateMutex != NULL) { + rv = (PRBool) (pArgs->DestroyMutex != NULL && + pArgs->LockMutex != NULL && + pArgs->UnlockMutex != NULL); + } else { /*pArgs->CreateMutex == NULL*/ + rv = (PRBool) (pArgs->DestroyMutex == NULL && + pArgs->LockMutex == NULL && + pArgs->UnlockMutex == NULL); + } + return rv; +} + + + +/********************************************************************** + * + * Start of PKCS 11 functions + * + **********************************************************************/ + + +/********************************************************************** + * + * In order to get this to work on 68K, we have to do some special tricks, + * First trick is that we need to make the module a Code Resource, and + * all Code Resources on 68K have to have a main function. So we + * define main to be a wrapper for C_GetFunctionList which will be the + * first funnction called by any software that uses the PKCS11 module. + * + * The second trick is that whenever you access a global variable from + * the Code Resource, it does funny things to the stack on 68K, so we + * need to call some macros that handle the stack for us. First thing + * you do is call EnterCodeResource() first thing in a function that + * accesses a global, right before you leave that function, you call + * ExitCodeResource. This will take care of stack management. + * + * Third trick is to call __InitCode__() when we first enter the module + * so that all of the global variables get initialized properly. + * + **********************************************************************/ + +#if defined(XP_MAC) && !defined(__POWERPC__) + +#define FORT11_RETURN(exp) {ExitCodeResource(); return (exp);} +#define FORT11_ENTER() EnterCodeResource(); + +#else /*XP_MAC*/ + +#define FORT11_RETURN(exp) return (exp); +#define FORT11_ENTER() + +#endif /*XP_MAC*/ + +#define CARD_OK(rv) if ((rv) != CI_OK) FORT11_RETURN (CKR_DEVICE_ERROR); +#define SLOT_OK(slot) if ((slot) > kNumSockets) FORT11_RETURN (CKR_SLOT_ID_INVALID); + +#ifdef XP_MAC +/* This is not a 4.0 project, so I can't depend on + * 4.0 defines, so instead I depend on CodeWarrior + * defines. + */ +#if __POWERPC__ +#elif __CFM68K__ +#else +/* To get this to work on 68K, we need to have + * the symbol main. So we just make it a wrapper for C_GetFunctionList. + */ +PR_PUBLIC_API(CK_RV) main(CK_FUNCTION_LIST_PTR *pFunctionList) { + FORT11_ENTER() + CK_RV rv; + + __InitCode__(); + + rv = C_GetFunctionList(pFunctionList); + FORT11_RETURN (rv); +} +#endif + +#endif /*XP_MAC*/ + +/* Return the function list */ +PR_PUBLIC_API(CK_RV) C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) { + /* No need to do a FORT11_RETURN as this function will never be directly + * called in the case where we need to do stack management. + * The main function will call this after taking care of stack stuff. + */ + *pFunctionList = &fort11_funcList; + return CKR_OK; +} + + +/* C_Initialize initializes the Cryptoki library. */ +PR_PUBLIC_API(CK_RV) C_Initialize(CK_VOID_PTR pReserved) { + FORT11_ENTER() + int i,j, tempNumSockets; + int rv = 1; + CK_C_INITIALIZE_ARGS_PTR pArgs = (CK_C_INITIALIZE_ARGS_PTR)pReserved; + CK_RV mrv; + + /* intialize all the slots */ + if (!init) { + init = PR_TRUE; + + /* need to initialize locks before MACI_Initialize is called in + * software fortezza. */ + if (pArgs) { + if (!fort11_InArgCheck(pArgs)) { + FORT11_RETURN (CKR_ARGUMENTS_BAD); + } + if (pArgs->flags & CKF_OS_LOCKING_OK){ + if (!fort11_NotAllFuncsNULL(pArgs)) { + FORT11_RETURN (CKR_CANT_LOCK); + } + } + if (fort11_NotAllFuncsNULL(pArgs)) { + mrv = FMUTEX_Init(pArgs); + if (mrv != CKR_OK) { + return CKR_GENERAL_ERROR; + } + } + } + rv = MACI_Initialize (&tempNumSockets); + kNumSockets = (CK_ULONG)tempNumSockets; + + CARD_OK (rv); + for (i=0; i < (int) kNumSockets; i++) { + if (FMUTEX_MutexEnabled()) { + mrv = FMUTEX_Create(&fort11_slot[i].sessionLock); + if (mrv != CKR_OK) { + FORT11_RETURN (CKR_GENERAL_ERROR); + } + mrv = FMUTEX_Create(&fort11_slot[i].objectLock); + if (mrv != CKR_OK) { + FMUTEX_Destroy(fort11_slot[i].sessionLock); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + } else { + fort11_slot[i].sessionLock = NULL; + fort11_slot[i].objectLock = NULL; + } + for(j=0; j < SESSION_HASH_SIZE; j++) { + fort11_slot[i].head[j] = NULL; + } + for(j=0; j < HASH_SIZE; j++) { + fort11_slot[i].tokObjects[j] = NULL; + } + fort11_slot[i].password = NULL; + fort11_slot[i].hasTokens = PR_FALSE; + fort11_slot[i].sessionIDCount = fort11_firstSessionID (i); + fort11_slot[i].sessionCount = 0; + fort11_slot[i].rwSessionCount = 0; + fort11_slot[i].tokenIDCount = 1; + fort11_slot[i].needLogin = PR_TRUE; + fort11_slot[i].isLoggedIn = PR_FALSE; + fort11_slot[i].ssoLoggedIn = PR_FALSE; + fort11_slot[i].DB_loaded = PR_FALSE; + fort11_slot[i].slotID= i+1; + InitSocket(&fortezzaSockets[i], i+1); + } + } + FORT11_RETURN (CKR_OK); +} + +/*C_Finalize indicates that an application is done with the Cryptoki library.*/ +PR_PUBLIC_API(CK_RV) C_Finalize (CK_VOID_PTR pReserved) { + FORT11_ENTER() + int i; + + for (i=0; i< (int) kNumSockets; i++) { + FreeSocket(&fortezzaSockets[i]); + } + MACI_Terminate(fortezzaSockets[0].maciSession); + init = PR_FALSE; + FORT11_RETURN (CKR_OK); +} + + + + +/* C_GetInfo returns general information about Cryptoki. */ +PR_PUBLIC_API(CK_RV) C_GetInfo(CK_INFO_PTR pInfo) { + FORT11_ENTER() + pInfo->cryptokiVersion = fort11_funcList.version; + PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32); + pInfo->libraryVersion.major = 1; + pInfo->libraryVersion.minor = 7; + PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32); + pInfo->flags = 0; + FORT11_RETURN (CKR_OK); +} + +/* C_GetSlotList obtains a list of slots in the system. */ +PR_PUBLIC_API(CK_RV) C_GetSlotList(CK_BBOOL tokenPresent, + CK_SLOT_ID_PTR pSlotList, + CK_ULONG_PTR pulCount) { + FORT11_ENTER() + int i; + + if (pSlotList != NULL) { + if (*pulCount >= kNumSockets) { + for (i=0; i < (int) kNumSockets; i++) { + pSlotList[i] = i+1; + } + } else { + FORT11_RETURN (CKR_BUFFER_TOO_SMALL); + } + } else { + *pulCount = kNumSockets; + } + FORT11_RETURN (CKR_OK); +} + +/* C_GetSlotInfo obtains information about a particular slot in the system. */ +PR_PUBLIC_API(CK_RV) C_GetSlotInfo(CK_SLOT_ID slotID, + CK_SLOT_INFO_PTR pInfo) { + FORT11_ENTER() + int rv; + CI_CONFIG ciConfig; + CI_STATE ciState; + HSESSION maciSession; + char slotDescription[65]; + FortezzaSocket *socket; + + + SLOT_OK(slotID); + + socket = &fortezzaSockets[slotID-1]; + if (!socket->isOpen) { + InitSocket(socket, slotID); + } + maciSession = socket->maciSession; + + rv = MACI_Select(maciSession, slotID); + + CARD_OK (rv) + + rv = MACI_GetConfiguration (maciSession, &ciConfig); + + + pInfo->firmwareVersion.major = 0; + pInfo->firmwareVersion.minor = 0; +#ifdef SWFORT + PORT_Memcpy (pInfo->manufacturerID,"Netscape Communications Corp ",32); + PORT_Memcpy (slotDescription,"Netscape Software Slot # ",32); +#define _local_BASE 24 +#else + PORT_Memcpy (pInfo->manufacturerID,"LITRONIC ",32); + PORT_Memcpy (slotDescription,"Litronic MACI Slot # ",32); +#define _local_BASE 20 +#endif + slotDescription[_local_BASE] = (char )((slotID < 10) ? slotID : + slotID/10) + '0'; + if (slotID >= 10) slotDescription[_local_BASE+1] = + (char)(slotID % 10) + '0'; + PORT_Memcpy (&slotDescription[32]," ",32); + PORT_Memcpy (pInfo->slotDescription, slotDescription , 64); + if (rv == CI_OK) { + pInfo->hardwareVersion.major = + (ciConfig.ManufacturerVersion & MAJOR_VERSION_MASK) >> 8; + pInfo->hardwareVersion.minor = + ciConfig.ManufacturerVersion & MINOR_VERSION_MASK; + pInfo->flags = CKF_TOKEN_PRESENT; + } else { + pInfo->hardwareVersion.major = 0; + pInfo->hardwareVersion.minor = 0; + pInfo->flags = 0; + } +#ifdef SWFORT + /* do we need to make it a removable device as well?? */ + pInfo->flags |= CKF_REMOVABLE_DEVICE; +#else + pInfo->flags |= (CKF_REMOVABLE_DEVICE | CKF_HW_SLOT); +#endif + + rv = MACI_GetState(maciSession, &ciState); + + if (rv == CI_OK) { + switch (ciState) { + case CI_ZEROIZE: + case CI_INTERNAL_FAILURE: + pInfo->flags &= (~CKF_TOKEN_PRESENT); + default: + break; + } + } else { + pInfo->flags &= (~CKF_TOKEN_PRESENT); + } + + FORT11_RETURN (CKR_OK); +} + +#define CKF_THREAD_SAFE 0x8000 + +/* C_GetTokenInfo obtains information about a particular token + in the system. */ +PR_PUBLIC_API(CK_RV) C_GetTokenInfo(CK_SLOT_ID slotID, + CK_TOKEN_INFO_PTR pInfo) { + FORT11_ENTER() + CI_STATUS cardStatus; + CI_CONFIG ciConfig; + PK11Slot *slot; + int rv, i; + char tmp[33]; + FortezzaSocket *socket; + + SLOT_OK (slotID); + + slot = &fort11_slot[slotID-1]; + + socket = &fortezzaSockets[slotID-1]; + if (!socket->isOpen) { + InitSocket(socket, slotID); + } + + rv = MACI_Select (socket->maciSession, slotID); + rv = MACI_GetStatus (socket->maciSession, &cardStatus); + if (rv != CI_OK) { + FORT11_RETURN (CKR_DEVICE_ERROR); + } + +#ifdef SWFORT + sprintf (tmp, "Software FORTEZZA Slot #%d", (int) slotID); +#else + sprintf (tmp, "FORTEZZA Slot #%d", (int) slotID); +#endif + + PORT_Memcpy (pInfo->label, tmp, PORT_Strlen(tmp)+1); + + for (i=0; i<8; i++) { + int serNum; + + serNum = (int)cardStatus.SerialNumber[i]; + sprintf ((char*)&pInfo->serialNumber[2*i], "%.2x", serNum); + } + + rv = MACI_GetTime (fortezzaSockets[slotID-1].maciSession, pInfo->utcTime); + if (rv == CI_OK) { + pInfo->flags = CKF_CLOCK_ON_TOKEN; + } else { + switch (rv) { + case CI_LIB_NOT_INIT: + case CI_INV_POINTER: + case CI_NO_CARD: + case CI_NO_SOCKET: + FORT11_RETURN (CKR_DEVICE_ERROR); + default: + pInfo->flags = 0; + break; + } + } + + rv = MACI_GetConfiguration (fortezzaSockets[slotID-1].maciSession, + &ciConfig); + + if (rv == CI_OK) { + PORT_Memcpy(pInfo->manufacturerID,ciConfig.ManufacturerName, + PORT_Strlen(ciConfig.ManufacturerName)); + for (i=PORT_Strlen(ciConfig.ManufacturerName); i<32; i++) { + pInfo->manufacturerID[i] = ' '; + } + PORT_Memcpy(pInfo->model,ciConfig.ProcessorType,16); + } + pInfo->ulMaxPinLen = CI_PIN_SIZE; + pInfo->ulMinPinLen = 0; + pInfo->ulTotalPublicMemory = 0; + pInfo->ulFreePublicMemory = 0; + pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED| CKF_USER_PIN_INITIALIZED | + CKF_THREAD_SAFE | CKF_WRITE_PROTECTED; + + pInfo->ulMaxSessionCount = 0; + pInfo->ulSessionCount = slot->sessionCount; + pInfo->ulMaxRwSessionCount = 0; + pInfo->ulRwSessionCount = slot->rwSessionCount; + + if (rv == CI_OK) { + pInfo->firmwareVersion.major = + (ciConfig.ManufacturerSWVer & MAJOR_VERSION_MASK) >> 8; + pInfo->firmwareVersion.minor = + ciConfig.ManufacturerSWVer & MINOR_VERSION_MASK; + pInfo->hardwareVersion.major = + (ciConfig.ManufacturerVersion & MAJOR_VERSION_MASK) >> 8; + pInfo->hardwareVersion.minor = + ciConfig.ManufacturerVersion & MINOR_VERSION_MASK; + } + FORT11_RETURN (CKR_OK); +} + + + +/* C_GetMechanismList obtains a list of mechanism types supported by a + token. */ +PR_PUBLIC_API(CK_RV) C_GetMechanismList(CK_SLOT_ID slotID, + CK_MECHANISM_TYPE_PTR pMechanismList, + CK_ULONG_PTR pulCount) { + FORT11_ENTER() + CK_RV rv = CKR_OK; + int i; + + SLOT_OK (slotID); + + if (pMechanismList == NULL) { + *pulCount = mechanismCount; + } else { + if (*pulCount >= mechanismCount) { + *pulCount = mechanismCount; + for (i=0; i< (int)mechanismCount; i++) { + pMechanismList[i] = mechanisms[i].type; + } + } else { + rv = CKR_BUFFER_TOO_SMALL; + } + } + FORT11_RETURN (rv); +} + + +/* C_GetMechanismInfo obtains information about a particular mechanism + * possibly supported by a token. */ +PR_PUBLIC_API(CK_RV) C_GetMechanismInfo(CK_SLOT_ID slotID, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR pInfo) { + int i; + FORT11_ENTER() + SLOT_OK (slotID); + + for (i=0; i< (int)mechanismCount; i++) { + if (type == mechanisms[i].type) { + PORT_Memcpy (pInfo, &mechanisms[i].domestic, sizeof (CK_MECHANISM_INFO)); + FORT11_RETURN (CKR_OK); + } + } + FORT11_RETURN (CKR_MECHANISM_INVALID); +} + + +/* C_InitToken initializes a token. */ +PR_PUBLIC_API(CK_RV) C_InitToken(CK_SLOT_ID slotID, + CK_CHAR_PTR pPin, + CK_ULONG ulPinLen, + CK_CHAR_PTR pLabel) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_InitPIN initializes the normal user's PIN. */ +PR_PUBLIC_API(CK_RV) C_InitPIN(CK_SESSION_HANDLE hSession, + CK_CHAR_PTR pPin, + CK_ULONG ulPinLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_SetPIN modifies the PIN of user that is currently logged in. */ +/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */ +PR_PUBLIC_API(CK_RV) C_SetPIN(CK_SESSION_HANDLE hSession, + CK_CHAR_PTR pOldPin, + CK_ULONG ulOldLen, + CK_CHAR_PTR pNewPin, + CK_ULONG ulNewLen) { + FORT11_ENTER() +#ifndef SWFORT + CI_PIN ciOldPin, ciNewPin; +#endif + PK11Session *session; + PK11Slot *slot; + int rv; + + session = fort11_SessionFromHandle (hSession, PR_FALSE); + + slot = fort11_SlotFromSession (session); + SLOT_OK(slot->slotID) + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + rv = MACI_Select (fortezzaSockets[slot->slotID-1].maciSession, slot->slotID); + CARD_OK (rv) + + if (slot->needLogin && session->info.state != CKS_RW_USER_FUNCTIONS) { + fort11_FreeSession (session); + FORT11_RETURN (CKR_USER_NOT_LOGGED_IN); + } + + fort11_FreeSession (session); + + if (ulNewLen > CI_PIN_SIZE || ulOldLen > CI_PIN_SIZE) + FORT11_RETURN (CKR_PIN_LEN_RANGE); + +#ifndef SWFORT + fort11_convertToCIPin (ciOldPin,pOldPin, ulOldLen); + fort11_convertToCIPin (ciNewPin,pNewPin, ulNewLen); + + rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession, + CI_USER_PIN, ciOldPin, ciNewPin); +#else + rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession, + CI_USER_PIN, pOldPin, pNewPin); +#endif + + if (rv != CI_OK) { + switch (rv) { + case CI_FAIL: + FORT11_RETURN (CKR_PIN_INCORRECT); + default: + FORT11_RETURN (CKR_DEVICE_ERROR); + } + } + FORT11_RETURN (CKR_OK); +} + +/* C_OpenSession opens a session between an application and a token. */ +PR_PUBLIC_API(CK_RV) C_OpenSession(CK_SLOT_ID slotID, + CK_FLAGS flags, + CK_VOID_PTR pApplication, + CK_NOTIFY Notify, + CK_SESSION_HANDLE_PTR phSession) { + FORT11_ENTER() + PK11Slot *slot; + CK_SESSION_HANDLE sessionID; + PK11Session *session; + FortezzaSocket *socket; + + SLOT_OK (slotID) + slot = &fort11_slot[slotID-1]; + socket = &fortezzaSockets[slotID-1]; + + if (!socket->isOpen) { + if (InitSocket(socket, slotID) != SOCKET_SUCCESS) { + FORT11_RETURN (CKR_TOKEN_NOT_PRESENT); + } + } + + session = fort11_NewSession (slotID, Notify, pApplication, + flags | CKF_SERIAL_SESSION); + + if (session == NULL) FORT11_RETURN (CKR_HOST_MEMORY); + + FMUTEX_Lock(slot->sessionLock); + + slot->sessionIDCount += ADD_NEXT_SESS_ID; + sessionID = slot->sessionIDCount; + fort11_update_state (slot, session); + pk11queue_add (session, sessionID, slot->head, SESSION_HASH_SIZE); + slot->sessionCount++; + if (session->info.flags & CKF_RW_SESSION) { + slot->rwSessionCount++; + } + session->handle = sessionID; + session->info.ulDeviceError = 0; + + FMUTEX_Unlock(slot->sessionLock); + + *phSession = sessionID; + FORT11_RETURN (CKR_OK); +} + + +/* C_CloseSession closes a session between an application and a token. */ +PR_PUBLIC_API(CK_RV) C_CloseSession(CK_SESSION_HANDLE hSession) { + FORT11_ENTER() + PK11Slot *slot; + PK11Session *session; + + session = fort11_SessionFromHandle (hSession, PR_TRUE); + slot = fort11_SlotFromSessionHandle (hSession); + + if (session == NULL) { + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + FMUTEX_Lock(slot->sessionLock); + if (session->next || session->prev) { + session->refCount--; + if (session->info.flags & CKF_RW_SESSION) { + slot->rwSessionCount--; + } + if (slot->sessionCount == 0) { + slot->isLoggedIn = PR_FALSE; + slot->password = NULL; + } + } + + FMUTEX_Unlock(slot->sessionLock); + + fort11_FreeSession (session); + FORT11_RETURN (CKR_OK); +} + + +/* C_CloseAllSessions closes all sessions with a token. */ +PR_PUBLIC_API(CK_RV) C_CloseAllSessions (CK_SLOT_ID slotID) { + FORT11_ENTER() + PK11Slot *slot; + PK11Session *session; + int i; + + + slot = fort11_SlotFromID(slotID); + if (slot == NULL) FORT11_RETURN (CKR_SLOT_ID_INVALID); + + /* first log out the card */ + FMUTEX_Lock(slot->sessionLock); + slot->isLoggedIn = PR_FALSE; + slot->password = NULL; + FMUTEX_Unlock(slot->sessionLock); + + /* now close all the current sessions */ + /* NOTE: If you try to open new sessions before C_CloseAllSessions + * completes, some of those new sessions may or may not be closed by + * C_CloseAllSessions... but any session running when this code starts + * will guarrenteed be close, and no session will be partially closed */ + for (i=0; i < SESSION_HASH_SIZE; i++) { + do { + FMUTEX_Lock(slot->sessionLock); + session = slot->head[i]; + /* hand deque */ + /* this duplicates much of C_close session functionality, but because + * we know that we are freeing all the sessions, we and do some + * more efficient processing */ + if (session) { + slot->head[i] = session->next; + if (session->next) session->next->prev = NULL; + session->next = session->prev = NULL; + slot->sessionCount--; + if (session->info.flags & CKF_RW_SESSION) { + slot->rwSessionCount--; + } + } + FMUTEX_Unlock(slot->sessionLock); + if (session) fort11_FreeSession(session); + } while (session != NULL); + } + FORT11_RETURN (CKR_OK); +} + + +/* C_GetSessionInfo obtains information about the session. */ +PR_PUBLIC_API(CK_RV) C_GetSessionInfo(CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo) { + FORT11_ENTER() + PK11Session *session; + PK11Slot *slot; + CI_STATE cardState; + FortezzaSocket *socket; + int ciRV; + + session = fort11_SessionFromHandle (hSession, PR_FALSE); + slot = fort11_SlotFromSessionHandle(hSession); + socket = &fortezzaSockets[slot->slotID-1]; + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + PORT_Memcpy (pInfo, &session->info, sizeof (CK_SESSION_INFO)); + fort11_FreeSession(session); + + ciRV = MACI_Select(socket->maciSession, slot->slotID); + CARD_OK(ciRV) + + ciRV = MACI_GetState(socket->maciSession, &cardState); + CARD_OK(ciRV) + + if (socket->isLoggedIn) { + switch (cardState) { + case CI_POWER_UP: + case CI_UNINITIALIZED: + case CI_INITIALIZED: + case CI_SSO_INITIALIZED: + case CI_LAW_INITIALIZED: + case CI_USER_INITIALIZED: + pInfo->state = CKS_RO_PUBLIC_SESSION; + break; + case CI_STANDBY: + case CI_READY: + pInfo->state = CKS_RO_USER_FUNCTIONS; + break; + default: + pInfo->state = CKS_RO_PUBLIC_SESSION; + break; + } + } else { + pInfo->state = CKS_RO_PUBLIC_SESSION; + } + + FORT11_RETURN (CKR_OK); +} + +/* C_Login logs a user into a token. */ +PR_PUBLIC_API(CK_RV) C_Login(CK_SESSION_HANDLE hSession, + CK_USER_TYPE userType, + CK_CHAR_PTR pPin, + CK_ULONG ulPinLen) { + FORT11_ENTER() + PK11Slot *slot; + PK11Session *session; +#ifndef SWFORT + CI_PIN ciPin; +#endif + int rv, ciUserType; + + slot = fort11_SlotFromSessionHandle (hSession); + session = fort11_SessionFromHandle(hSession, PR_FALSE); + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + fort11_FreeSession(session); + + if (slot->isLoggedIn) FORT11_RETURN (CKR_USER_ALREADY_LOGGED_IN); + slot->ssoLoggedIn = PR_FALSE; + +#ifndef SWFORT + if (ulPinLen > CI_PIN_SIZE) FORT11_RETURN (CKR_PIN_LEN_RANGE); + + fort11_convertToCIPin (ciPin, pPin, ulPinLen); +#endif + switch (userType) { + case CKU_SO: + ciUserType = CI_SSO_PIN; + break; + case CKU_USER: + ciUserType = CI_USER_PIN; + break; + default: + FORT11_RETURN (CKR_USER_TYPE_INVALID); + } + +#ifndef SWFORT + rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, ciPin); +#else + rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, pPin); +#endif + + switch (rv) { + case SOCKET_SUCCESS: + break; + case CI_FAIL: + FORT11_RETURN (CKR_PIN_INCORRECT); + default: + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + FMUTEX_Lock(slot->sessionLock); + slot->isLoggedIn = PR_TRUE; + if (userType == CKU_SO) { + slot->ssoLoggedIn = PR_TRUE; + } + FMUTEX_Unlock(slot->sessionLock); + + fort11_update_all_states(slot); + FORT11_RETURN (CKR_OK); +} + +/* C_Logout logs a user out from a token. */ +PR_PUBLIC_API(CK_RV) C_Logout(CK_SESSION_HANDLE hSession) { + FORT11_ENTER() + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + if (!slot->isLoggedIn) + FORT11_RETURN (CKR_USER_NOT_LOGGED_IN); + + FMUTEX_Lock(slot->sessionLock); + + slot->isLoggedIn = PR_FALSE; + slot->ssoLoggedIn = PR_FALSE; + slot->password = NULL; + LogoutFromSocket (&fortezzaSockets[slot->slotID-1]); + + FMUTEX_Unlock(slot->sessionLock); + + fort11_update_all_states(slot); + FORT11_RETURN (CKR_OK); +} + +/* C_CreateObject creates a new object. */ +PR_PUBLIC_API(CK_RV) C_CreateObject(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_CopyObject copies an object, creating a new object for the copy. */ +PR_PUBLIC_API(CK_RV) C_CopyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_DestroyObject destroys an object. */ +PR_PUBLIC_API(CK_RV) C_DestroyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject) { + FORT11_ENTER() + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Session *session; + PK11Object *object; + PK11FreeStatus status; + + /* + * This whole block just makes sure we really can destroy the + * requested object. + */ + session = fort11_SessionFromHandle(hSession, PR_FALSE); + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + object = fort11_ObjectFromHandle(hObject,session); + if (object == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID); + } + + /* don't destroy a private object if we aren't logged in */ + if ((!slot->isLoggedIn) && (slot->needLogin) && + (fort11_isTrue(object,CKA_PRIVATE))) { + fort11_FreeSession(session); + fort11_FreeObject(object); + FORT11_RETURN (CKR_USER_NOT_LOGGED_IN); + } + + /* don't destroy a token object if we aren't in a rw session */ + + if (((session->info.flags & CKF_RW_SESSION) == 0) && + (fort11_isTrue(object,CKA_TOKEN))) { + fort11_FreeSession(session); + fort11_FreeObject(object); + FORT11_RETURN (CKR_SESSION_READ_ONLY); + } + + /* ACTUALLY WE NEED TO DEAL WITH TOKEN OBJECTS AS WELL */ + FMUTEX_Lock(session->objectLock); + fort11_DeleteObject(session,object); + FMUTEX_Unlock(session->objectLock); + + fort11_FreeSession(session); + + /* + * get some indication if the object is destroyed. Note: this is not + * 100%. Someone may have an object reference outstanding (though that + * should not be the case by here. Also now that the object is "half" + * destroyed. Our internal representation is destroyed, but it is still + * in the data base. + */ + status = fort11_FreeObject(object); + + FORT11_RETURN ((status != PK11_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR); +} + + +/* C_GetObjectSize gets the size of an object in bytes. */ +PR_PUBLIC_API(CK_RV) C_GetObjectSize(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ULONG_PTR pulSize) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + *pulSize = 0; + return CKR_OK; +} + + +/* C_GetAttributeValue obtains the value of one or more object attributes. */ +PR_PUBLIC_API(CK_RV) C_GetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount) { + FORT11_ENTER() + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Session *session; + PK11Object *object; + PK11Attribute *attribute; + PRBool sensitive; + int i; + + /* + * make sure we're allowed + */ + session = fort11_SessionFromHandle(hSession, PR_FALSE); + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + object = fort11_ObjectFromHandle(hObject,session); + fort11_FreeSession(session); + if (object == NULL) { + FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID); + } + + /* don't read a private object if we aren't logged in */ + if ((!slot->isLoggedIn) && (slot->needLogin) && + (fort11_isTrue(object,CKA_PRIVATE))) { + fort11_FreeObject(object); + FORT11_RETURN (CKR_USER_NOT_LOGGED_IN); + } + + sensitive = fort11_isTrue(object,CKA_SENSITIVE); + for (i=0; i < (int)ulCount; i++) { + /* Make sure that this attribute is retrievable */ + if (sensitive && fort11_isSensitive(pTemplate[i].type,object->objclass)) { + fort11_FreeObject(object); + FORT11_RETURN (CKR_ATTRIBUTE_SENSITIVE); + } + attribute = fort11_FindAttribute(object,pTemplate[i].type); + if (attribute == NULL) { + fort11_FreeObject(object); + FORT11_RETURN (CKR_ATTRIBUTE_TYPE_INVALID); + } + if (pTemplate[i].pValue != NULL) { + PORT_Memcpy(pTemplate[i].pValue,attribute->attrib.pValue, + attribute->attrib.ulValueLen); + } + pTemplate[i].ulValueLen = attribute->attrib.ulValueLen; + fort11_FreeAttribute(attribute); + } + + fort11_FreeObject(object); + FORT11_RETURN (CKR_OK); +} + +/* C_SetAttributeValue modifies the value of one or more object attributes */ +PR_PUBLIC_API(CK_RV) C_SetAttributeValue (CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* C_FindObjectsInit initializes a search for token and session objects + * that match a template. */ +PR_PUBLIC_API(CK_RV) C_FindObjectsInit(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount) { + FORT11_ENTER() + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Session *session; + PK11ObjectListElement *objectList = NULL; + PK11ObjectListElement *olp; + PK11SearchResults *search, *freeSearch; + FortezzaSocket *currSocket; + int rv, count, i; + + if (slot == NULL) { + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + + if ((!slot->isLoggedIn) && (slot->needLogin)) + FORT11_RETURN (CKR_USER_NOT_LOGGED_IN); + + session = fort11_SessionFromHandle(hSession, PR_FALSE); + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + currSocket = &fortezzaSockets[slot->slotID-1]; + if (currSocket->personalityList == NULL) { + rv = FetchPersonalityList(currSocket); + if (rv != SOCKET_SUCCESS) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + rv = fort11_BuildCertObjects(currSocket, slot, session); + + if (rv != CKR_OK) { + fort11_FreeSession(session); + FORT11_RETURN (rv); + } + + + } + rv = fort11_searchObjectList(&objectList, slot->tokObjects, + slot->objectLock, pTemplate, ulCount); + if (rv != CKR_OK) { + fort11_FreeObjectList(objectList); + fort11_FreeSession(session); + FORT11_RETURN (rv); + } + + /*copy list to session*/ + + count = 0; + for(olp = objectList; olp != NULL; olp = olp->next) { + count++; + } + + search = (PK11SearchResults *)PORT_Alloc(sizeof(PK11SearchResults)); + if (search != NULL) { + search->handles = (CK_OBJECT_HANDLE *) + PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * count); + if (search->handles != NULL) { + for (i=0; i < count; i++) { + search->handles[i] = objectList->object->handle; + objectList = fort11_FreeObjectListElement(objectList); + } + } else { + PORT_Free(search); + search = NULL; + } + } + if (search == NULL) { + fort11_FreeObjectList(objectList); + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + + /* store the search info */ + search->index = 0; + search->size = count; + if ((freeSearch = session->search) != NULL) { + session->search = NULL; + fort11_FreeSearch(freeSearch); + } + session->search = search; + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); +} + + +/* C_FindObjects continues a search for token and session objects + * that match a template, obtaining additional object handles. */ +PR_PUBLIC_API(CK_RV) C_FindObjects(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE_PTR phObject, + CK_ULONG ulMaxObjectCount, + CK_ULONG_PTR pulObjectCount) { + FORT11_ENTER() + PK11Session *session; + PK11SearchResults *search; + PK11Slot *slot; + int transfer; + unsigned long left; + + *pulObjectCount = 0; + session = fort11_SessionFromHandle(hSession,PR_FALSE); + slot = fort11_SlotFromSessionHandle(hSession); + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + if (session->search == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + search = session->search; + left = session->search->size - session->search->index; + transfer = (ulMaxObjectCount > left) ? left : ulMaxObjectCount; + PORT_Memcpy(phObject,&search->handles[search->index], + transfer*sizeof(CK_OBJECT_HANDLE_PTR)); + search->index += transfer; + if (search->index == search->size) { + session->search = NULL; + fort11_FreeSearch(search); + } + fort11_FreeSession(session); + *pulObjectCount = transfer; + FORT11_RETURN (CKR_OK); +} + +/* C_FindObjectsFinal finishes a search for token and session objects. */ +PR_PUBLIC_API(CK_RV) C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { + FORT11_ENTER() + PK11Session *session; + PK11SearchResults *search; + PK11Slot *slot; + + session = fort11_SessionFromHandle(hSession, PR_FALSE); + slot = fort11_SlotFromSessionHandle(hSession); + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + search = session->search; + session->search = NULL; + if (search == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + fort11_FreeSearch(search); + + /* UnloadPersonalityList(&fortezzaSockets[session->slot->slotID-1]); */ + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); +} + + +/* C_EncryptInit initializes an encryption operation. */ +PR_PUBLIC_API(CK_RV) C_EncryptInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Object *keyObject; + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + FortezzaContext *context; + HSESSION hs = socket->maciSession; + FortezzaKey *fortezzaKey; + CI_IV fortezzaIV; + int ciRV, registerIndex; + + + if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) { + if (session) { + fort11_FreeSession(session); + } + FORT11_RETURN (CKR_MECHANISM_INVALID); + } + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + keyObject = fort11_ObjectFromHandle (hKey, session); + + if (keyObject == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + + ciRV = MACI_Select (hs, slot->slotID); + if (ciRV != CI_OK) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + ciRV = MACI_SetMode(hs, CI_ENCRYPT_TYPE, CI_CBC64_MODE); + if (ciRV != CI_OK) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + /*Load the correct key into a key register*/ + fortezzaKey = (FortezzaKey*)keyObject->objectInfo; + fort11_FreeObject (keyObject); + if (fortezzaKey == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + if (fortezzaKey->keyRegister == KeyNotLoaded) { + registerIndex = LoadKeyIntoRegister (fortezzaKey); + } else { + registerIndex = fortezzaKey->keyRegister; + } + + if (registerIndex == KeyNotLoaded) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + ciRV = MACI_SetKey (hs,registerIndex); + if (ciRV != CI_OK) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + ciRV = MACI_GenerateIV(hs, fortezzaIV); + if (ciRV != CI_OK) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + context = &session->fortezzaContext; + InitContext(context, socket, hKey); + ciRV = SaveState(context, fortezzaIV, session, fortezzaKey, + CI_ENCRYPT_EXT_TYPE, pMechanism->mechanism); + if (ciRV != SOCKET_SUCCESS) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + if (pMechanism->pParameter != NULL && + pMechanism->ulParameterLen >= sizeof(CI_IV)) { + PORT_Memcpy (pMechanism->pParameter, fortezzaIV, sizeof(CI_IV)); + } + + InitCryptoOperation(context, Encrypt); + fort11_FreeSession(session); + + FORT11_RETURN (CKR_OK); +} + +/* C_Encrypt encrypts single-part data. */ +PR_PUBLIC_API(CK_RV) C_Encrypt (CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + FortezzaContext *context; + HSESSION hs; + CK_RV rv; + + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession , PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + context = &session->fortezzaContext; + if (GetCryptoOperation(context) != Encrypt) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED); + } + + *pulEncryptedDataLen = ulDataLen; + if (pEncryptedData == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + + hs = socket->maciSession; + FMUTEX_Lock(socket->registersLock); + MACI_Lock(hs, CI_BLOCK_LOCK_FLAG); + rv = EncryptData (context, pData, ulDataLen, + pEncryptedData, *pulEncryptedDataLen); + MACI_Unlock(hs); + FMUTEX_Unlock(socket->registersLock); + + if (rv != SOCKET_SUCCESS) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + EndCryptoOperation(context, Encrypt); + fort11_FreeSession(session); + + FORT11_RETURN (CKR_OK); +} + + +/* C_EncryptUpdate continues a multiple-part encryption operation. */ +PR_PUBLIC_API(CK_RV) C_EncryptUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + FortezzaContext *context; + int rv; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + context = &session->fortezzaContext; + + if (GetCryptoOperation(context) != Encrypt) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED); + } + + if (pEncryptedPart == NULL) { + *pulEncryptedPartLen = ulPartLen; + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + + if (*pulEncryptedPartLen < ulPartLen) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_BUFFER_TOO_SMALL); + } + + *pulEncryptedPartLen = ulPartLen; + + FMUTEX_Lock(socket->registersLock); + MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG); + rv = EncryptData(context,pPart, ulPartLen, pEncryptedPart, + *pulEncryptedPartLen); + MACI_Unlock(socket->maciSession); + FMUTEX_Unlock(socket->registersLock); + + fort11_FreeSession(session); + if (rv != SOCKET_SUCCESS) { + FORT11_RETURN (CKR_GENERAL_ERROR); + } + FORT11_RETURN (CKR_OK); +} + + +/* C_EncryptFinal finishes a multiple-part encryption operation. */ +PR_PUBLIC_API(CK_RV) C_EncryptFinal(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastEncryptedPart, + CK_ULONG_PTR pulLastEncryptedPartLen){ + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaContext *context; + int rv; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + context = &session->fortezzaContext; + + rv = EndCryptoOperation(context, Encrypt); + fort11_FreeSession(session); + + FORT11_RETURN (CKR_OK); +} +/* C_DecryptInit initializes a decryption operation. */ +PR_PUBLIC_API(CK_RV) C_DecryptInit( CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Object *keyObject; + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + FortezzaContext *context; + HSESSION hs = socket->maciSession; + FortezzaKey *fortezzaKey; + CI_IV fortezzaIV; + int ciRV, registerIndex; + + if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) { + if (session) fort11_FreeSession(session); + FORT11_RETURN (CKR_MECHANISM_INVALID); + } + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + keyObject = fort11_ObjectFromHandle (hKey, session); + + if (keyObject == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + + fortezzaKey = (FortezzaKey*)keyObject->objectInfo; + fort11_FreeObject(keyObject); + + if (fortezzaKey == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + ciRV = MACI_Select (hs, slot->slotID); + if (ciRV != CI_OK) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + ciRV = MACI_SetMode(hs, CI_DECRYPT_TYPE, CI_CBC64_MODE); + if (ciRV != CI_OK) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + FMUTEX_Lock(socket->registersLock); + if (fortezzaKey->keyRegister == KeyNotLoaded) { + registerIndex = LoadKeyIntoRegister(fortezzaKey); + } else { + registerIndex = fortezzaKey->keyRegister; + } + + if (registerIndex == KeyNotLoaded) { + FMUTEX_Unlock(socket->registersLock); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + if (pMechanism->pParameter == NULL || + pMechanism->ulParameterLen < sizeof (CI_IV)) { + FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID); + } + + PORT_Memcpy (fortezzaIV, pMechanism->pParameter, sizeof(CI_IV)); + + ciRV = MACI_SetKey (hs, registerIndex); + if (ciRV != CI_OK) { + FMUTEX_Unlock(socket->registersLock); + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + ciRV = MACI_LoadIV (hs, fortezzaIV); + if (ciRV != CI_OK) { + FMUTEX_Unlock(socket->registersLock); + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + context = &session->fortezzaContext; + InitContext(context, socket, hKey); + ciRV = SaveState (context, fortezzaIV, session, fortezzaKey, + CI_DECRYPT_EXT_TYPE, pMechanism->mechanism); + + FMUTEX_Unlock(socket->registersLock); + + if (ciRV != SOCKET_SUCCESS) { + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + InitCryptoOperation (context, Decrypt); + fort11_FreeSession (session); + + FORT11_RETURN (CKR_OK); +} + +/* C_Decrypt decrypts encrypted data in a single part. */ +PR_PUBLIC_API(CK_RV) C_Decrypt(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + FortezzaContext *context; + HSESSION hs; + CK_RV rv; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + context = &session->fortezzaContext; + + if (GetCryptoOperation(context) != Decrypt) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED); + } + + *pulDataLen = ulEncryptedDataLen; + if (pData == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + + hs = socket->maciSession; + FMUTEX_Lock(socket->registersLock); + MACI_Lock(hs, CI_NULL_FLAG); + rv = DecryptData (context, pEncryptedData, ulEncryptedDataLen, + pData, *pulDataLen); + MACI_Unlock(hs); + FMUTEX_Unlock(socket->registersLock); + if (rv != SOCKET_SUCCESS) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + EndCryptoOperation (context, Decrypt); + fort11_FreeSession(session); + + FORT11_RETURN (CKR_OK); +} + + +/* C_DecryptUpdate continues a multiple-part decryption operation. */ +PR_PUBLIC_API(CK_RV) C_DecryptUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + FortezzaContext *context; + HSESSION hs; + int rv; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession (session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + context = &session->fortezzaContext; + hs = socket->maciSession; + + if (GetCryptoOperation(context) != Decrypt) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED); + } + + if (pPart == NULL) { + *pulPartLen = ulEncryptedPartLen; + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + + *pulPartLen = ulEncryptedPartLen; + + FMUTEX_Lock(socket->registersLock); + MACI_Lock (hs, CI_NULL_FLAG); + rv = DecryptData (context, pEncryptedPart, ulEncryptedPartLen, pPart, + *pulPartLen); + MACI_Unlock(hs); + FMUTEX_Unlock(socket->registersLock); + + fort11_FreeSession(session); + + if (rv != SOCKET_SUCCESS) { + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + FORT11_RETURN (CKR_OK); +} + + +/* C_DecryptFinal finishes a multiple-part decryption operation. */ +PR_PUBLIC_API(CK_RV) C_DecryptFinal(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastPart, + CK_ULONG_PTR pulLastPartLen) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaContext *context; + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + context = &session->fortezzaContext; + EndCryptoOperation (context, Decrypt); + + fort11_FreeSession(session); + + FORT11_RETURN (CKR_OK); +} + + +/* + ************** Crypto Functions: Digest (HASH) ************************ + */ + +/* C_DigestInit initializes a message-digesting operation. */ +PR_PUBLIC_API(CK_RV) C_DigestInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_Digest digests data in a single part. */ +PR_PUBLIC_API(CK_RV) C_Digest(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_DigestUpdate continues a multiple-part message-digesting operation. */ +PR_PUBLIC_API(CK_RV) C_DigestUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_DigestFinal finishes a multiple-part message-digesting operation. */ +PR_PUBLIC_API(CK_RV) C_DigestFinal(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* + ************** Crypto Functions: Sign ************************ + */ + +/* C_SignInit initializes a signature (private key encryption) operation, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature */ +PR_PUBLIC_API(CK_RV) C_SignInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Object *keyObject; + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + FortezzaContext *context; + PK11Attribute *idAttribute; + int personalityIndex; + HSESSION hs = socket->maciSession; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + if (pMechanism->mechanism != CKM_DSA) { + FORT11_RETURN (CKR_MECHANISM_INVALID); + } + + keyObject = fort11_ObjectFromHandle (hKey, session); + + if (keyObject == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + + context = &session->fortezzaContext; + InitContext(context, socket, hKey); + InitCryptoOperation (context, Sign); + fort11_FreeSession(session); + + idAttribute = fort11_FindAttribute(keyObject, CKA_ID); + fort11_FreeObject(keyObject); + + if (idAttribute == NULL) { + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + + personalityIndex = *(int*)(idAttribute->attrib.pValue); + fort11_FreeAttribute(idAttribute); + + MACI_Select (hs, slot->slotID); + if (MACI_SetPersonality (hs,personalityIndex) != CI_OK) { + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + FORT11_RETURN (CKR_OK); +} + + +/* C_Sign signs (encrypts with private key) data in a single part, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature */ +PR_PUBLIC_API(CK_RV) C_Sign(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) { + + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaContext *context; + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + HSESSION hs = socket->maciSession; + PK11Object *keyObject; + PK11Attribute *idAttribute; + int ciRV, personalityIndex; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + + context = &session->fortezzaContext; + if (GetCryptoOperation(context) != Sign) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED); + } + + if (pSignature == NULL) { + *pulSignatureLen = 40; + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + + if (ulDataLen > 20) { + FORT11_RETURN (CKR_DATA_LEN_RANGE); + } + + if (*pulSignatureLen < 40) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_BUFFER_TOO_SMALL); + } + *pulSignatureLen = 40; + + keyObject = fort11_ObjectFromHandle(context->hKey, session); + if (keyObject == NULL) { + fort11_FreeSession(session); + FORT11_RETURN(CKR_GENERAL_ERROR); + } + + idAttribute = fort11_FindAttribute(keyObject, CKA_ID); + fort11_FreeObject(keyObject); + + personalityIndex = *(int*)(idAttribute->attrib.pValue); + fort11_FreeAttribute(idAttribute); + + MACI_Select(hs, slot->slotID); + + MACI_Lock(hs, CI_BLOCK_LOCK_FLAG); + ciRV = MACI_SetPersonality(hs, personalityIndex); + if (ciRV != CI_OK) { + MACI_Unlock(hs); + fort11_FreeSession(session); + FORT11_RETURN(CKR_DEVICE_ERROR); + } + + ciRV = MACI_Sign (hs, pData, pSignature); + if (ciRV != CI_OK) { + MACI_Unlock(hs); + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + MACI_Unlock(hs); + EndCryptoOperation (context, Sign); + fort11_FreeSession(session); + + FORT11_RETURN (CKR_OK); +} + + +/* C_SignUpdate continues a multiple-part signature operation, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature */ +PR_PUBLIC_API(CK_RV) C_SignUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_SignFinal finishes a multiple-part signature operation, + * FORT11_RETURNing the signature. */ +PR_PUBLIC_API(CK_RV) C_SignFinal(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* + ************** Crypto Functions: Sign Recover ************************ + */ +/* C_SignRecoverInit initializes a signature operation, + * where the (digest) data can be recovered from the signature. + * E.g. encryption with the user's private key */ +PR_PUBLIC_API(CK_RV) C_SignRecoverInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_SignRecover signs data in a single operation + * where the (digest) data can be recovered from the signature. + * E.g. encryption with the user's private key */ +PR_PUBLIC_API(CK_RV) C_SignRecover(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* + ************** Crypto Functions: verify ************************ + */ + +/* C_VerifyInit initializes a verification operation, + * where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature (e.g. DSA) */ +PR_PUBLIC_API(CK_RV) C_VerifyInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_Verify verifies a signature in a single-part operation, + * where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature */ +PR_PUBLIC_API(CK_RV) C_Verify(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_VerifyUpdate continues a multiple-part verification operation, + * where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature */ +PR_PUBLIC_API(CK_RV) C_VerifyUpdate( CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_VerifyFinal finishes a multiple-part verification operation, + * checking the signature. */ +PR_PUBLIC_API(CK_RV) C_VerifyFinal(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* + ************** Crypto Functions: Verify Recover ************************ + */ + +/* C_VerifyRecoverInit initializes a signature verification operation, + * where the data is recovered from the signature. + * E.g. Decryption with the user's public key */ +PR_PUBLIC_API(CK_RV) C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) { + /* For functions that don't access globals, we don't have to worry about the + * stack. + */ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_VerifyRecover verifies a signature in a single-part operation, + * where the data is recovered from the signature. + * E.g. Decryption with the user's public key */ +PR_PUBLIC_API(CK_RV) C_VerifyRecover(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* + **************************** Key Functions: ************************ + */ + +#define MAX_KEY_LEN 256 +/* C_GenerateKey generates a secret key, creating a new key object. */ +PR_PUBLIC_API(CK_RV) C_GenerateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + PK11Object *key; + FortezzaKey *newKey; + int i, keyRegister; + CK_ULONG key_length = 0; + CK_RV crv = CKR_OK; + CK_OBJECT_CLASS secretKey = CKO_SECRET_KEY; + CK_BBOOL False = FALSE; + CK_BBOOL cktrue = TRUE; + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + if (pMechanism->mechanism != CKM_SKIPJACK_KEY_GEN) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_MECHANISM_INVALID); + } + + key = fort11_NewObject(slot); + + if (key == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_HOST_MEMORY); + } + + for (i=0; i < (int) ulCount; i++) { + if (pTemplate[i].type == CKA_VALUE_LEN) { + key_length = *(CK_ULONG *)pTemplate[i].pValue; + continue; + } + crv = fort11_AddAttributeType (key, pk11_attr_expand (&pTemplate[i])); + if (crv != CKR_OK) + break; + } + + if (crv != CKR_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (crv); + } + + /* make sure we don't have any class, key_type, or value fields */ + fort11_DeleteAttributeType(key,CKA_CLASS); + fort11_DeleteAttributeType(key,CKA_KEY_TYPE); + fort11_DeleteAttributeType(key,CKA_VALUE); + + if (MAX_KEY_LEN < key_length) { + crv = CKR_TEMPLATE_INCONSISTENT; + } + + if (crv != CKR_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (crv); + } + + if (fort11_AddAttributeType(key, CKA_CLASS,&secretKey, + sizeof(CK_OBJECT_CLASS)) != CKR_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + if (fort11_AddAttributeType(key, CKA_TOKEN, &False, + sizeof(CK_BBOOL)) != CKR_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + if (fort11_isTrue(key,CKA_SENSITIVE)) { + fort11_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue, + sizeof(CK_BBOOL)); + } + if (!fort11_isTrue(key,CKA_EXTRACTABLE)) { + fort11_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue, + sizeof(CK_BBOOL)); + } + + FMUTEX_Lock(socket->registersLock); + + keyRegister = GetBestKeyRegister(socket); + newKey = NewFortezzaKey(socket, MEK, NULL, keyRegister); + + FMUTEX_Unlock(socket->registersLock); + + if (newKey == NULL) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_HOST_MEMORY); + } + + key->objectInfo = (void*)newKey; + key->infoFree = fort11_FreeFortezzaKey; + + FMUTEX_Lock(slot->objectLock); + key->handle = slot->tokenIDCount++; + key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV); + FMUTEX_Unlock(slot->objectLock); + + key->objclass = secretKey; + key->slot = slot; + key->inDB = PR_TRUE; + + fort11_AddObject(session, key); + fort11_FreeSession(session); + SetFortezzaKeyHandle(newKey, key->handle); + *phKey = key->handle; + + FORT11_RETURN (CKR_OK); + +} + + +/* C_GenerateKeyPair generates a public-key/private-key pair, + * creating new key objects. */ +PR_PUBLIC_API(CK_RV) C_GenerateKeyPair + (CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPrivateKey, + CK_OBJECT_HANDLE_PTR phPublicKey) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* C_WrapKey wraps (i.e., encrypts) a key. */ +PR_PUBLIC_API(CK_RV) C_WrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + PK11Object *wrapKey; + PK11Object *srcKey; + FortezzaKey *wrapFortKey; + FortezzaKey *srcFortKey; + int rv; + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + if (!socket->isLoggedIn) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_USER_NOT_LOGGED_IN); + } + + if (pMechanism->mechanism != CKM_SKIPJACK_WRAP) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_MECHANISM_INVALID); + } + + wrapKey = fort11_ObjectFromHandle (hWrappingKey, session); + if ((wrapKey == NULL) || (wrapKey->objectInfo == NULL)) { + if (wrapKey) + fort11_FreeObject(wrapKey); + fort11_FreeSession(session); + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + + srcKey = fort11_ObjectFromHandle (hKey, session); + fort11_FreeSession(session); + if ((srcKey == NULL) || (srcKey->objectInfo == NULL)) { + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + + wrapFortKey = (FortezzaKey*)wrapKey->objectInfo; + fort11_FreeObject(wrapKey); + + srcFortKey = (FortezzaKey*)srcKey->objectInfo; + fort11_FreeObject(srcKey); + + FMUTEX_Lock(socket->registersLock); + if (wrapFortKey->keyRegister == KeyNotLoaded) { + if (LoadKeyIntoRegister(wrapFortKey) == KeyNotLoaded) { + FORT11_RETURN (CKR_DEVICE_ERROR); + } + } + + if (srcFortKey->keyRegister == KeyNotLoaded) { + if (LoadKeyIntoRegister(srcFortKey) == KeyNotLoaded) { + FMUTEX_Unlock(socket->registersLock); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + } + + MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG); + rv = WrapKey (wrapFortKey, srcFortKey, pWrappedKey, *pulWrappedKeyLen); + MACI_Unlock(socket->maciSession); + FMUTEX_Unlock(socket->registersLock); + + if (rv != SOCKET_SUCCESS) { + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + FORT11_RETURN (CKR_OK); +} + + +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ +PR_PUBLIC_API(CK_RV) C_UnwrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + PK11Object *wrapKey; + PK11Object *newKey; + FortezzaKey *fortKey; + FortezzaKey *unwrapFort; + CK_ULONG key_length; + int i, newKeyRegister; + CK_RV crv = CKR_OK; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + if (pMechanism->mechanism != CKM_SKIPJACK_WRAP){ + fort11_FreeSession(session); + FORT11_RETURN (CKR_MECHANISM_INVALID); + } + + if (!socket->isLoggedIn) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_USER_NOT_LOGGED_IN); + } + + wrapKey = fort11_ObjectFromHandle(hUnwrappingKey, session); + if (wrapKey == NULL || wrapKey->objectInfo == NULL) { + if (wrapKey) + fort11_FreeObject(wrapKey); + fort11_FreeSession(session); + FORT11_RETURN (CKR_UNWRAPPING_KEY_HANDLE_INVALID); + } + + fortKey = (FortezzaKey*)wrapKey->objectInfo; + fort11_FreeObject(wrapKey); + + newKey = fort11_NewObject(slot); + if (newKey == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_HOST_MEMORY); + } + + for (i=0; i< (int)ulAttributeCount; i++) { + if (pTemplate[i].type == CKA_VALUE_LEN) { + key_length = *(CK_ULONG*)pTemplate[i].pValue; + continue; + } + crv=fort11_AddAttributeType(newKey,fort11_attr_expand(&pTemplate[i])); + if (crv != CKR_OK) { + break; + } + } + + if (crv != CKR_OK) { + fort11_FreeSession(session); + fort11_FreeObject(newKey); + FORT11_RETURN (crv); + } + + /* make sure we don't have any class, key_type, or value fields */ + if (!fort11_hasAttribute(newKey,CKA_CLASS)) { + fort11_FreeObject(newKey); + fort11_FreeSession(session); + FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE); + } + if (!fort11_hasAttribute(newKey,CKA_KEY_TYPE)) { + fort11_FreeObject(newKey); + fort11_FreeSession(session); + FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE); + } + + FMUTEX_Lock(socket->registersLock); + newKeyRegister = UnwrapKey (pWrappedKey, fortKey); + if (newKeyRegister == KeyNotLoaded) { + /*Couldn't Unwrap the key*/ + fort11_FreeObject(newKey); + fort11_FreeSession(session); + FMUTEX_Unlock(socket->registersLock); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + unwrapFort = NewUnwrappedKey(newKeyRegister, fortKey->id, socket); + FMUTEX_Unlock(socket->registersLock); + + if (unwrapFort == NULL) { + fort11_FreeObject(newKey); + fort11_FreeSession(session); + FORT11_RETURN (CKR_HOST_MEMORY); + } + newKey->objectInfo = unwrapFort; + newKey->infoFree = fort11_FreeFortezzaKey; + + FMUTEX_Lock(slot->objectLock); + newKey->handle = slot->tokenIDCount++; + newKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV); + FMUTEX_Unlock(slot->objectLock); + newKey->objclass = CKO_SECRET_KEY; + newKey->slot = slot; + newKey->inDB = PR_TRUE; + + fort11_AddObject (session, newKey); + fort11_FreeSession(session); + + SetFortezzaKeyHandle(unwrapFort, newKey->handle); + *phKey = newKey->handle; + + FORT11_RETURN (CKR_OK); +} + + +/* C_DeriveKey derives a key from a base key, creating a new key object. */ +PR_PUBLIC_API(CK_RV) C_DeriveKey( CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1]; + PK11Object *key, *sourceKey; + CK_ULONG i; + CK_ULONG key_length = 0; + CK_RV crv = 0; + CK_KEY_TYPE keyType = CKK_SKIPJACK; + CK_OBJECT_CLASS classType = CKO_SECRET_KEY; + CK_BBOOL ckTrue = TRUE; + CK_BBOOL ckFalse = FALSE; + int ciRV; + int personality; + PK11Attribute *att; + + CK_KEA_DERIVE_PARAMS_PTR params; + FortezzaKey *derivedKey; + CreateTEKInfo tekInfo; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + if (pMechanism->mechanism != CKM_KEA_KEY_DERIVE) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_MECHANISM_INVALID); + } + + key = fort11_NewObject (slot); + + if (key == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_HOST_MEMORY); + } + + for (i = 0; i < ulAttributeCount; i++) { + crv = fort11_AddAttributeType (key, fort11_attr_expand(&pTemplate[i])); + if (crv != CKR_OK) { + break; + } + if (pTemplate[i].type == CKA_KEY_TYPE) { + keyType = *(CK_KEY_TYPE*)pTemplate[i].pValue; + } else if (pTemplate[i].type == CKA_VALUE_LEN) { + key_length = *(CK_ULONG*)pTemplate[i].pValue; + } + } + + if (crv != CKR_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (crv); + } + + if (key_length == 0) { + key_length = 12; + } + + classType = CKO_SECRET_KEY; + crv = fort11_forceAttribute (key, CKA_CLASS, &classType, + sizeof(classType)); + if (crv != CKR_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (crv); + } + crv = fort11_forceAttribute (key, CKA_SENSITIVE, &ckTrue, + sizeof(CK_BBOOL)); + if (crv != CKR_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (crv); + } + crv = fort11_forceAttribute (key, CKA_EXTRACTABLE, &ckFalse, + sizeof(CK_BBOOL)); + if (crv != CKR_OK) { + fort11_FreeSession(session); + fort11_FreeObject(key); + FORT11_RETURN (crv); + } + + sourceKey = fort11_ObjectFromHandle (hBaseKey, session); + + if (sourceKey == NULL) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + + att = fort11_FindAttribute(sourceKey,CKA_ID); + fort11_FreeObject(sourceKey); + if (att == NULL) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_KEY_TYPE_INCONSISTENT); + } + personality = *(int *) att->attrib.pValue; + fort11_FreeAttribute(att); + + params = (CK_KEA_DERIVE_PARAMS_PTR)pMechanism->pParameter; + + if (params == NULL) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID); + } + + ciRV = MACI_SetPersonality(socket->maciSession,personality); + if (ciRV != CI_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + /* + * If we're sending, generate our own RA. + */ + if (params->isSender) { + ciRV = MACI_GenerateRa(socket->maciSession,params->pRandomA); + if (ciRV != CI_OK) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + } + PORT_Memcpy (tekInfo.Ra, params->pRandomA, params->ulRandomLen); + PORT_Memcpy (tekInfo.Rb, params->pRandomB, params->ulRandomLen); + tekInfo.randomLen = params->ulRandomLen; + tekInfo.personality = personality; + tekInfo.flag = (params->isSender) ? CI_INITIATOR_FLAG : CI_RECIPIENT_FLAG; + + PORT_Memcpy (tekInfo.pY, params->pPublicData, params->ulPublicDataLen); + tekInfo.YSize = params->ulPublicDataLen; + + FMUTEX_Lock(socket->registersLock); + derivedKey = NewFortezzaKey(socket, TEK, &tekInfo, + GetBestKeyRegister(socket)); + FMUTEX_Unlock(socket->registersLock); + + if (derivedKey == NULL) { + fort11_FreeObject(key); + fort11_FreeSession(session); + FORT11_RETURN (CKR_GENERAL_ERROR); + } + + key->objectInfo = derivedKey; + key->infoFree = fort11_FreeFortezzaKey; + + FMUTEX_Lock(slot->objectLock); + key->handle = slot->tokenIDCount++; + key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV); + FMUTEX_Unlock(slot->objectLock); + key->objclass = classType; + key->slot = slot; + key->inDB = PR_TRUE; + + fort11_AddObject (session, key); + fort11_FreeSession(session); + + SetFortezzaKeyHandle(derivedKey, key->handle); + *phKey = key->handle; + + FORT11_RETURN (CKR_OK); +} + +/* + **************************** Random Functions: ************************ + */ + +/* C_SeedRandom mixes additional seed material into the token's random number + * generator. */ +PR_PUBLIC_API(CK_RV) C_SeedRandom(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSeed, + CK_ULONG ulSeedLen) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_GenerateRandom generates random data. */ +PR_PUBLIC_API(CK_RV) C_GenerateRandom(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pRandomData, + CK_ULONG ulRandomLen) { + FORT11_ENTER() + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE); + CI_RANDOM randomNum; + CK_ULONG randomSize = sizeof (CI_RANDOM); + int ciRV; + CK_ULONG bytesCopied = 0, bytesToCopy; + CK_ULONG bufferSize = 0, bytesRemaining; + + if (session == NULL) { + session = fort11_SessionFromHandle (hSession, PR_TRUE); + fort11_TokenRemoved(slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + fort11_FreeSession(session); + ciRV = MACI_Select(fortezzaSockets[slot->slotID-1].maciSession, + slot->slotID); + if (ciRV != CI_OK) { + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + while (bytesCopied < ulRandomLen) { + bytesRemaining = ulRandomLen - bytesCopied; + if (bufferSize < bytesRemaining) { + ciRV = + MACI_GenerateRandom(fortezzaSockets[slot->slotID-1].maciSession, + randomNum); + if (ciRV != CI_OK) + FORT11_RETURN (CKR_DEVICE_ERROR); + bufferSize = randomSize; + } + bytesToCopy = (bytesRemaining > randomSize) ? randomSize : + bytesRemaining; + + PORT_Memcpy (&pRandomData[bytesCopied], + &randomNum[randomSize-bufferSize], bytesToCopy); + + bytesCopied += bytesToCopy; + bufferSize -= bytesToCopy; + } + + FORT11_RETURN (CKR_OK); +} + + +/* C_GetFunctionStatus obtains an updated status of a function running + * in parallel with an application. */ +PR_PUBLIC_API(CK_RV) C_GetFunctionStatus(CK_SESSION_HANDLE hSession) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_CancelFunction cancels a function running in parallel */ +PR_PUBLIC_API(CK_RV) C_CancelFunction(CK_SESSION_HANDLE hSession) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* C_GetOperationState saves the state of the cryptographic + *operation in a session. */ +PR_PUBLIC_API(CK_RV) C_GetOperationState(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG_PTR pulOperationStateLen) { + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaContext *context; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + if (pOperationState == NULL) { + *pulOperationStateLen = sizeof (FortezzaContext); + fort11_FreeSession(session); + FORT11_RETURN (CKR_OK); + } + + if (*pulOperationStateLen < sizeof (FortezzaContext)) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_BUFFER_TOO_SMALL); + } + + context = &session->fortezzaContext; + fort11_FreeSession(session); + PORT_Memcpy (pOperationState, context, sizeof(FortezzaContext)); + ((FortezzaContext *)pOperationState)->session = NULL; + ((FortezzaContext *)pOperationState)->fortezzaKey = NULL; + *pulOperationStateLen = sizeof(FortezzaContext); + FORT11_RETURN (CKR_OK); +} + + + +/* C_SetOperationState restores the state of the cryptographic operation in a session. */ +PR_PUBLIC_API(CK_RV) C_SetOperationState(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG ulOperationStateLen, + CK_OBJECT_HANDLE hEncryptionKey, + CK_OBJECT_HANDLE hAuthenticationKey){ + FORT11_ENTER() + PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE); + PK11Slot *slot = fort11_SlotFromSessionHandle(hSession); + FortezzaContext *context; + FortezzaContext passedInCxt; + PK11Object *keyObject; + FortezzaKey *fortKey; + + if (session == NULL) { + session = fort11_SessionFromHandle(hSession, PR_TRUE); + fort11_TokenRemoved (slot, session); + fort11_FreeSession(session); + FORT11_RETURN (CKR_SESSION_HANDLE_INVALID); + } + + if (ulOperationStateLen != sizeof(FortezzaContext)) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_SAVED_STATE_INVALID); + } + + PORT_Memcpy(&passedInCxt, pOperationState, sizeof(FortezzaContext)); + if (passedInCxt.fortezzaSocket->slotID != slot->slotID) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_SAVED_STATE_INVALID); + } + passedInCxt.session = NULL; + passedInCxt.fortezzaKey = NULL; + + if (hEncryptionKey != 0) { + keyObject = fort11_ObjectFromHandle(hEncryptionKey, session); + if (keyObject == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_KEY_HANDLE_INVALID); + } + fortKey = (FortezzaKey*)keyObject->objectInfo; + fort11_FreeObject(keyObject); + if (fortKey == NULL) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_SAVED_STATE_INVALID); + } + if (fortKey->keyRegister == KeyNotLoaded) { + if (LoadKeyIntoRegister (fortKey) == KeyNotLoaded) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + } + passedInCxt.fortezzaKey = fortKey; + + } + if (hAuthenticationKey != 0) { + fort11_FreeSession(session); + FORT11_RETURN (CKR_DEVICE_ERROR); + } + + passedInCxt.session = session; + context = &session->fortezzaContext; + fort11_FreeSession (session); + PORT_Memcpy (context, &passedInCxt, sizeof(passedInCxt)); + + FORT11_RETURN (CKR_OK); +} + +/* Dual-function cryptographic operations */ + +/* C_DigestEncryptUpdate continues a multiple-part digesting and + encryption operation. */ +PR_PUBLIC_API(CK_RV) C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen){ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_DecryptDigestUpdate continues a multiple-part decryption and digesting + operation. */ +PR_PUBLIC_API(CK_RV) C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen){ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_SignEncryptUpdate continues a multiple-part signing and encryption + operation. */ +PR_PUBLIC_API(CK_RV) C_SignEncryptUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen){ + return CKR_FUNCTION_NOT_SUPPORTED; +} + + +/* C_DecryptVerifyUpdate continues a multiple-part decryption and verify + operation. */ +PR_PUBLIC_API(CK_RV) C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen){ + return CKR_FUNCTION_NOT_SUPPORTED; +} + +/* C_DigestKey continues a multi-part message-digesting operation, + * by digesting the value of a secret key as part of the data already digested. + */ +PR_PUBLIC_API(CK_RV) C_DigestKey(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hKey) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +PR_PUBLIC_API(CK_RV) C_WaitForSlotEvent(CK_FLAGS flags, + CK_SLOT_ID_PTR pSlot, + CK_VOID_PTR pRserved) { + return CKR_FUNCTION_FAILED; +} + diff --git a/security/nss/lib/fortcrypt/fortsock.h b/security/nss/lib/fortcrypt/fortsock.h new file mode 100644 index 000000000..fd0ba039e --- /dev/null +++ b/security/nss/lib/fortcrypt/fortsock.h @@ -0,0 +1,108 @@ +/* ***** 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 FORSOCK_H_ +#define FORSOCK_H_ + +#include "seccomon.h" +#include "fpkcs11.h" +#include "fpkcs11i.h" +#include "fpkstrs.h" + + +#ifndef prtypes_h___ +typedef enum { PR_FALSE, PR_TRUE }PRBool; +#endif + + +#define SOCKET_SUCCESS 0 +#define SOCKET_FAILURE 1 + +#define KeyNotLoaded -1 +#define NoCryptoType -1 +#define NoCryptoMode -1 +#define NO_MECHANISM 0xFFFFFFFFL + + +/*Get the Fortezza context in here*/ + +int InitSocket (FortezzaSocket *inSocket, int inSlotID); +int FreeSocket (FortezzaSocket *inSocket); + +int FetchPersonalityList (FortezzaSocket *inSocket); +int UnloadPersonalityList(FortezzaSocket *inSocket); + +int LoginToSocket (FortezzaSocket *inSocket, int inUserType, CI_PIN inPin); + +int LogoutFromSocket (FortezzaSocket *inSocket); + +PRBool SocketStateUnchanged(FortezzaSocket* inSocket); + +int GetBestKeyRegister(FortezzaSocket *inSocket); + +FortezzaKey *NewFortezzaKey(FortezzaSocket *inSocket, + FortezzaKeyType inKeyType, + CreateTEKInfo *TEKinfo, + int inKeyRegister); +FortezzaKey *NewUnwrappedKey(int inKeyRegister, int i, + FortezzaSocket *inSocket); + +int LoadKeyIntoRegister (FortezzaKey *inKey); +int SetFortezzaKeyHandle (FortezzaKey *inKey, CK_OBJECT_HANDLE inHandle); +void RemoveKey (FortezzaKey *inKey); + +void InitContext(FortezzaContext *inContext, FortezzaSocket *inSocket, + CK_OBJECT_HANDLE hKey); +int InitCryptoOperation (FortezzaContext *inContext, + CryptoType inCryptoOperation); +int EndCryptoOperation (FortezzaContext *inContext, + CryptoType inCryptoOperation); +CryptoType GetCryptoOperation (FortezzaContext *inContext); +int EncryptData (FortezzaContext *inContext, CK_BYTE_PTR inData, + CK_ULONG inDataLen, CK_BYTE_PTR inDest, + CK_ULONG inDestLen); +int DecryptData (FortezzaContext *inContext, CK_BYTE_PTR inData, + CK_ULONG inDataLen, CK_BYTE_PTR inDest, + CK_ULONG inDestLen); + +int SaveState (FortezzaContext *inContext, CI_IV inIV, + PK11Session *inSession, FortezzaKey *inKey, + int inCryptoType, CK_MECHANISM_TYPE inMechanism); + +int WrapKey (FortezzaKey *wrappingKey, FortezzaKey *srcKey, + CK_BYTE_PTR pDest, CK_ULONG ulDestLen); +int UnwrapKey (CK_BYTE_PTR inWrappedKey, FortezzaKey *inKey); + +#endif /*SOCKET_H_*/ diff --git a/security/nss/lib/fortcrypt/fpkcs11.h b/security/nss/lib/fortcrypt/fpkcs11.h new file mode 100644 index 000000000..abbe4f3fd --- /dev/null +++ b/security/nss/lib/fortcrypt/fpkcs11.h @@ -0,0 +1,173 @@ +/* ***** 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 ***** */ +/* + * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document + * is granted provided that it is identified as "RSA Security In.c Public-Key + * Cryptography Standards (PKCS)" in all material mentioning or referencing + * this document. + */ +/* Define API */ +#ifndef _FPKCS11_H_ +#define _FPKCS11_H_ 1 + +#include "seccomon.h" + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* All the various pkcs11 types and #define'd values are in the file */ +/* pkcs11t.h. CK_PTR should be defined there, too; it's the recipe for */ +/* making pointers. */ +#include "fpkcs11t.h" + +#define __PASTE(x,y) x##y + +/* ================================================================= */ +/* Define the "extern" form of all the entry points */ + +#define CK_EXTERN extern +#define CK_FUNC(name) CK_ENTRY name +#define CK_NEED_ARG_LIST 1 +#define _CK_RV PR_PUBLIC_API(CK_RV) + +/* pkcs11f.h has all the information about the PKCS #11 functions. */ +#include "fpkcs11f.h" + +#undef CK_FUNC +#undef CK_EXTERN +#undef CK_NEED_ARG_LIST +#undef _CK_RV + +/* ================================================================= */ +/* Define the typedef form of all the entry points. */ +/* That is, for each Cryptoki function C_XXX, define a type CK_C_XXX */ +/* which is a pointer to that kind of function. */ + +#define CK_EXTERN typedef +#define CK_FUNC(name) CK_ENTRY (CK_PTR __PASTE(CK_,name)) +#define CK_NEED_ARG_LIST 1 +#define _CK_RV CK_RV + +#include "fpkcs11f.h" + +#undef CK_FUNC +#undef CK_EXTERN +#undef CK_NEED_ARG_LIST +#undef _CK_RV + +/* ================================================================= + * Define structed vector of entry points. + * The CK_FUNCTION_LIST contains a CK_VERSION indicating the PKCS #11 + * version, and then a whole slew of function pointers to the routines + * in the library. This type was declared, but not defined, in + * pkcs11t.h. */ + + +/* These data types are platform/implementation dependent. */ +#if defined(XP_WIN) +#if defined(_WIN32) +#define CK_ENTRY +#define CK_PTR * /* definition for Win32 */ +#define NULL_PTR 0 /* NULL pointer */ +#pragma pack(push, cryptoki, 1) +#else /* win16 */ +#if defined(__WATCOMC__) +#define CK_ENTRY +#define CK_PTR * /* definition for Win16 */ +#define NULL_PTR 0 /* NULL pointer */ +#pragma pack(push, 1) +#else /* not Watcom 16-bit */ +#define CK_ENTRY +#define CK_PTR * /* definition for Win16 */ +#define NULL_PTR 0 /* NULL pointer */ +#pragma pack(1) +#endif +#endif +#else /* not windows */ +#define CK_ENTRY +#define CK_PTR * /* definition for UNIX */ +#define NULL_PTR 0 /* NULL pointer */ +#endif + + +#define CK_EXTERN +#define CK_FUNC(name) __PASTE(CK_,name) name; +#define _CK_RV + +struct CK_FUNCTION_LIST { + + CK_VERSION version; /* PKCS #11 version */ + +/* Pile all the function pointers into it. */ +#include "fpkcs11f.h" + +}; + +#undef CK_FUNC +#undef CK_EXTERN +#undef _CK_RV + + +#if defined(XP_WIN) +#if defined(_WIN32) +#pragma pack(pop, cryptoki) +#else /* win16 */ +#if defined(__WATCOMC__) +#pragma pack(pop) +#else /* not Watcom 16-bit */ +#pragma pack() +#endif +#endif +#endif + + +#undef __PASTE +/* ================================================================= */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/security/nss/lib/fortcrypt/fpkcs11f.h b/security/nss/lib/fortcrypt/fpkcs11f.h new file mode 100644 index 000000000..d115601ff --- /dev/null +++ b/security/nss/lib/fortcrypt/fpkcs11f.h @@ -0,0 +1,956 @@ +/* ***** 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 ***** */ +/* + * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document + * is granted provided that it is identified as "RSA Security In.c Public-Key + * Cryptography Standards (PKCS)" in all material mentioning or referencing + * this document. + */ +/* This function contains pretty much everything about all */ +/* the PKCS #11 function prototypes. */ + +/* General-purpose */ + +/* C_Initialize initializes the PKCS #11 library. */ +CK_EXTERN _CK_RV CK_FUNC(C_Initialize) +#ifdef CK_NEED_ARG_LIST +( + CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ +); +#endif + + +/* C_Finalize indicates that an application is done with the PKCS #11 + * library. */ +CK_EXTERN _CK_RV CK_FUNC(C_Finalize) +#ifdef CK_NEED_ARG_LIST +( + CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ +); +#endif + + +/* C_GetInfo returns general information about PKCS #11. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_INFO_PTR pInfo /* location that receives the information */ +); +#endif + + +/* C_GetFunctionList returns the function list. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetFunctionList) +#ifdef CK_NEED_ARG_LIST +( + CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives ptr to function +list */ +); +#endif + + + +/* Slot and token management */ + +/* C_GetSlotList obtains a list of slots in the system. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetSlotList) +#ifdef CK_NEED_ARG_LIST +( + CK_BBOOL tokenPresent, /* only slots with token present */ + CK_SLOT_ID_PTR pSlotList, /* receives the array of slot IDs */ + CK_ULONG_PTR pulCount /* receives the number of slots */ +); +#endif + + +/* C_GetSlotInfo obtains information about a particular slot in the +system. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetSlotInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* the ID of the slot */ + CK_SLOT_INFO_PTR pInfo /* receives the slot information */ +); +#endif + + +/* C_GetTokenInfo obtains information about a particular token in the + * system. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetTokenInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_TOKEN_INFO_PTR pInfo /* receives the token information */ +); +#endif + + +/* C_GetMechanismList obtains a list of mechanism types supported by + * a token. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetMechanismList) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_MECHANISM_TYPE_PTR pMechanismList, /* receives mech. types array +*/ + CK_ULONG_PTR pulCount /* receives number of mechs. */ +); +#endif + + +/* C_GetMechanismInfo obtains information about a particular mechanism + * possibly supported by a token. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetMechanismInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_MECHANISM_TYPE type, /* type of mechanism */ + CK_MECHANISM_INFO_PTR pInfo /* receives mechanism information */ +); +#endif + + +/* C_InitToken initializes a token. */ +CK_EXTERN _CK_RV CK_FUNC(C_InitToken) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* ID of the token's slot */ + CK_CHAR_PTR pPin, /* the SO's initial PIN */ + CK_ULONG ulPinLen, /* length in bytes of the PIN */ + CK_CHAR_PTR pLabel /* 32-byte token label (blank padded) */ +); +#endif + + +/* C_InitPIN initializes the normal user's PIN. */ +CK_EXTERN _CK_RV CK_FUNC(C_InitPIN) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_CHAR_PTR pPin, /* the normal user's PIN */ + CK_ULONG ulPinLen /* length in bytes of the PIN */ +); +#endif + + +/* C_SetPIN modifies the PIN of user that is currently logged in. */ +CK_EXTERN _CK_RV CK_FUNC(C_SetPIN) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_CHAR_PTR pOldPin, /* the old PIN */ + CK_ULONG ulOldLen, /* length of the old PIN */ + CK_CHAR_PTR pNewPin, /* the new PIN */ + CK_ULONG ulNewLen /* length of the new PIN */ +); +#endif + + + +/* Session management */ + +/* C_OpenSession opens a session between an application and a token. */ +CK_EXTERN _CK_RV CK_FUNC(C_OpenSession) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID, /* the slot's ID */ + CK_FLAGS flags, /* defined in CK_SESSION_INFO */ + CK_VOID_PTR pApplication, /* pointer passed to callback */ + CK_NOTIFY Notify, /* notification callback function +*/ + CK_SESSION_HANDLE_PTR phSession /* receives new session handle */ +); +#endif + + +/* C_CloseSession closes a session between an application and a token. +*/ +CK_EXTERN _CK_RV CK_FUNC(C_CloseSession) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + +/* C_CloseAllSessions closes all sessions with a token. */ +CK_EXTERN _CK_RV CK_FUNC(C_CloseAllSessions) +#ifdef CK_NEED_ARG_LIST +( + CK_SLOT_ID slotID /* the token's slot */ +); +#endif + + +/* C_GetSessionInfo obtains information about the session. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetSessionInfo) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_SESSION_INFO_PTR pInfo /* receives session information */ +); +#endif + + +/* C_GetOperationState obtains the state of the cryptographic operation + * in a session. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetOperationState) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pOperationState, /* location receiving state */ + CK_ULONG_PTR pulOperationStateLen /* location receiving state +length */ +); +#endif + + +/* C_SetOperationState restores the state of the cryptographic operation + * in a session. */ +CK_EXTERN _CK_RV CK_FUNC(C_SetOperationState) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pOperationState, /* the location holding the +state */ + CK_ULONG ulOperationStateLen, /* location holding state +length */ + CK_OBJECT_HANDLE hEncryptionKey, /* handle of en/decryption key +*/ + CK_OBJECT_HANDLE hAuthenticationKey /* handle of sign/verify key */ +); +#endif + + +/* C_Login logs a user into a token. */ +CK_EXTERN _CK_RV CK_FUNC(C_Login) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_USER_TYPE userType, /* the user type */ + CK_CHAR_PTR pPin, /* the user's PIN */ + CK_ULONG ulPinLen /* the length of the PIN */ +); +#endif + + +/* C_Logout logs a user out from a token. */ +CK_EXTERN _CK_RV CK_FUNC(C_Logout) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Object management */ + +/* C_CreateObject creates a new object. */ +CK_EXTERN _CK_RV CK_FUNC(C_CreateObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phObject /* receives new object's handle. */ +); +#endif + + +/* C_CopyObject copies an object, creating a new object for the copy. */ +CK_EXTERN _CK_RV CK_FUNC(C_CopyObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ + CK_ULONG ulCount, /* attributes in template */ + CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ +); +#endif + + +/* C_DestroyObject destroys an object. */ +CK_EXTERN _CK_RV CK_FUNC(C_DestroyObject) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject /* the object's handle */ +); +#endif + + +/* C_GetObjectSize gets the size of an object in bytes. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetObjectSize) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ULONG_PTR pulSize /* receives size of object */ +); +#endif + + +/* C_GetAttributeValue obtains the value of one or more object +attributes. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetAttributeValue) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes, gets values */ + CK_ULONG ulCount /* attributes in template */ +); +#endif + + +/* C_SetAttributeValue modifies the value of one or more object +attributes */ +CK_EXTERN _CK_RV CK_FUNC(C_SetAttributeValue) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hObject, /* the object's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes and values */ + CK_ULONG ulCount /* attributes in template */ +); +#endif + + +/* C_FindObjectsInit initializes a search for token and session objects + * that match a template. */ +CK_EXTERN _CK_RV CK_FUNC(C_FindObjectsInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ + CK_ULONG ulCount /* attributes in search template */ +); +#endif + + +/* C_FindObjects continues a search for token and session objects + * that match a template, obtaining additional object handles. */ +CK_EXTERN _CK_RV CK_FUNC(C_FindObjects) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE_PTR phObject, /* receives object handle array +*/ + CK_ULONG ulMaxObjectCount, /* max handles to be returned +*/ + CK_ULONG_PTR pulObjectCount /* actual number returned */ +); +#endif + + +/* C_FindObjectsFinal finishes a search for token and session objects. +*/ +CK_EXTERN _CK_RV CK_FUNC(C_FindObjectsFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Encryption and decryption */ + +/* C_EncryptInit initializes an encryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_EncryptInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of encryption key */ +); +#endif + + +/* C_Encrypt encrypts single-part data. */ +CK_EXTERN _CK_RV CK_FUNC(C_Encrypt) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the plaintext data */ + CK_ULONG ulDataLen, /* bytes of plaintext data */ + CK_BYTE_PTR pEncryptedData, /* receives encrypted data */ + CK_ULONG_PTR pulEncryptedDataLen /* receives encrypted byte +count */ +); +#endif + + +/* C_EncryptUpdate continues a multiple-part encryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_EncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* bytes of plaintext data */ + CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */ + CK_ULONG_PTR pulEncryptedPartLen /* receives encrypted byte count +*/ +); +#endif + + +/* C_EncryptFinal finishes a multiple-part encryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_EncryptFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pLastEncryptedPart, /* receives encrypted last +part */ + CK_ULONG_PTR pulLastEncryptedPartLen /* receives byte count */ +); +#endif + + +/* C_DecryptInit initializes a decryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_DecryptInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the decryption key */ +); +#endif + + +/* C_Decrypt decrypts encrypted data in a single part. */ +CK_EXTERN _CK_RV CK_FUNC(C_Decrypt) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pEncryptedData, /* input encrypted data */ + CK_ULONG ulEncryptedDataLen, /* count of bytes of input */ + CK_BYTE_PTR pData, /* receives decrypted output */ + CK_ULONG_PTR pulDataLen /* receives decrypted byte count +*/ +); +#endif + + +/* C_DecryptUpdate continues a multiple-part decryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_DecryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pEncryptedPart, /* input encrypted data */ + CK_ULONG ulEncryptedPartLen, /* count of bytes of input */ + CK_BYTE_PTR pPart, /* receives decrypted output */ + CK_ULONG_PTR pulPartLen /* receives decrypted byte +count */ +); +#endif + + +/* C_DecryptFinal finishes a multiple-part decryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_DecryptFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pLastPart, /* receives decrypted output */ + CK_ULONG_PTR pulLastPartLen /* receives decrypted byte count */ +); +#endif + + + +/* Message digesting */ + +/* C_DigestInit initializes a message-digesting operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_DigestInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ +); +#endif + + +/* C_Digest digests data in a single part. */ +CK_EXTERN _CK_RV CK_FUNC(C_Digest) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* data to be digested */ + CK_ULONG ulDataLen, /* bytes of data to be digested */ + CK_BYTE_PTR pDigest, /* receives the message digest */ + CK_ULONG_PTR pulDigestLen /* receives byte length of digest */ +); +#endif + + +/* C_DigestUpdate continues a multiple-part message-digesting operation. +*/ +CK_EXTERN _CK_RV CK_FUNC(C_DigestUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* data to be digested */ + CK_ULONG ulPartLen /* bytes of data to be digested */ +); +#endif + + +/* C_DigestKey continues a multi-part message-digesting operation, by + * digesting the value of a secret key as part of the data already +digested. + */ +CK_EXTERN _CK_RV CK_FUNC(C_DigestKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_OBJECT_HANDLE hKey /* handle of secret key to digest */ +); +#endif + + +/* C_DigestFinal finishes a multiple-part message-digesting operation. +*/ +CK_EXTERN _CK_RV CK_FUNC(C_DigestFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pDigest, /* receives the message digest */ + CK_ULONG_PTR pulDigestLen /* receives byte count of digest */ +); +#endif + + + +/* Signing and MACing */ + +/* C_SignInit initializes a signature (private key encryption) +operation, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature */ +CK_EXTERN _CK_RV CK_FUNC(C_SignInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the signature key */ +); +#endif + + +/* C_Sign signs (encrypts with private key) data in a single part, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature */ +CK_EXTERN _CK_RV CK_FUNC(C_Sign) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data (digest) to be signed +*/ + CK_ULONG ulDataLen, /* count of bytes to be signed */ + CK_BYTE_PTR pSignature, /* receives the signature */ + CK_ULONG_PTR pulSignatureLen /* receives byte count of signature +*/ +); +#endif + + +/* C_SignUpdate continues a multiple-part signature operation, + * where the signature is (will be) an appendix to the data, + * and plaintext cannot be recovered from the signature */ +CK_EXTERN _CK_RV CK_FUNC(C_SignUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* the data (digest) to be signed */ + CK_ULONG ulPartLen /* count of bytes to be signed */ +); +#endif + + +/* C_SignFinal finishes a multiple-part signature operation, + * returning the signature. */ +CK_EXTERN _CK_RV CK_FUNC(C_SignFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* receives the signature */ + CK_ULONG_PTR pulSignatureLen /* receives byte count of signature +*/ +); +#endif + + +/* C_SignRecoverInit initializes a signature operation, + * where the (digest) data can be recovered from the signature. + * E.g. encryption with the user's private key */ +CK_EXTERN _CK_RV CK_FUNC(C_SignRecoverInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the signature key */ +); +#endif + + +/* C_SignRecover signs data in a single operation + * where the (digest) data can be recovered from the signature. + * E.g. encryption with the user's private key */ +CK_EXTERN _CK_RV CK_FUNC(C_SignRecover) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* the data (digest) to be signed +*/ + CK_ULONG ulDataLen, /* count of bytes to be signed */ + CK_BYTE_PTR pSignature, /* receives the signature */ + CK_ULONG_PTR pulSignatureLen /* receives byte count of signature +*/ +); +#endif + + + +/* Verifying signatures and MACs */ + +/* C_VerifyInit initializes a verification operation, + * where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature (e.g. DSA) */ +CK_EXTERN _CK_RV CK_FUNC(C_VerifyInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the verification key */ +); +#endif + + +/* C_Verify verifies a signature in a single-part operation, + * where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature */ +CK_EXTERN _CK_RV CK_FUNC(C_Verify) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pData, /* plaintext data (digest) to +compare */ + CK_ULONG ulDataLen, /* length of data (digest) in bytes +*/ + CK_BYTE_PTR pSignature, /* the signature to be verified */ + CK_ULONG ulSignatureLen /* count of bytes of signature */ +); +#endif + + +/* C_VerifyUpdate continues a multiple-part verification operation, + * where the signature is an appendix to the data, + * and plaintext cannot be recovered from the signature */ +CK_EXTERN _CK_RV CK_FUNC(C_VerifyUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* plaintext data (digest) to compare */ + CK_ULONG ulPartLen /* length of data (digest) in bytes */ +); +#endif + + +/* C_VerifyFinal finishes a multiple-part verification operation, + * checking the signature. */ +CK_EXTERN _CK_RV CK_FUNC(C_VerifyFinal) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* the signature to be verified */ + CK_ULONG ulSignatureLen /* count of bytes of signature */ +); +#endif + + +/* C_VerifyRecoverInit initializes a signature verification operation, + * where the data is recovered from the signature. + * E.g. Decryption with the user's public key */ +CK_EXTERN _CK_RV CK_FUNC(C_VerifyRecoverInit) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ + CK_OBJECT_HANDLE hKey /* handle of the verification key */ +); +#endif + + +/* C_VerifyRecover verifies a signature in a single-part operation, + * where the data is recovered from the signature. + * E.g. Decryption with the user's public key */ +CK_EXTERN _CK_RV CK_FUNC(C_VerifyRecover) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSignature, /* the signature to be verified */ + CK_ULONG ulSignatureLen, /* count of bytes of signature */ + CK_BYTE_PTR pData, /* receives decrypted data (digest) +*/ + CK_ULONG_PTR pulDataLen /* receives byte count of data */ +); +#endif + + + +/* Dual-function cryptographic operations */ + +/* C_DigestEncryptUpdate continues a multiple-part digesting and +encryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_DigestEncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* bytes of plaintext data */ + CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */ + CK_ULONG_PTR pulEncryptedPartLen /* receives encrypted byte +count */ +); +#endif + + +/* C_DecryptDigestUpdate continues a multiple-part decryption and + * digesting operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_DecryptDigestUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pEncryptedPart, /* input encrypted data */ + CK_ULONG ulEncryptedPartLen, /* count of bytes of input */ + CK_BYTE_PTR pPart, /* receives decrypted output */ + CK_ULONG_PTR pulPartLen /* receives decrypted byte +count */ +); +#endif + + +/* C_SignEncryptUpdate continues a multiple-part signing and + * encryption operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_SignEncryptUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pPart, /* the plaintext data */ + CK_ULONG ulPartLen, /* bytes of plaintext data */ + CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */ + CK_ULONG_PTR pulEncryptedPartLen /* receives encrypted byte +count */ +); +#endif + + +/* C_DecryptVerifyUpdate continues a multiple-part decryption and + * verify operation. */ +CK_EXTERN _CK_RV CK_FUNC(C_DecryptVerifyUpdate) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pEncryptedPart, /* input encrypted data */ + CK_ULONG ulEncryptedPartLen, /* count of byes of input */ + CK_BYTE_PTR pPart, /* receives decrypted output */ + CK_ULONG_PTR pulPartLen /* receives decrypted byte +count */ +); +#endif + + + +/* Key management */ + +/* C_GenerateKey generates a secret key, creating a new key object. */ +CK_EXTERN _CK_RV CK_FUNC(C_GenerateKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the key generation mechanism */ + CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */ + CK_ULONG ulCount, /* number of attributes in template +*/ + CK_OBJECT_HANDLE_PTR phKey /* receives handle of new key */ +); +#endif + + +/* C_GenerateKeyPair generates a public-key/private-key pair, + * creating new key objects. */ +CK_EXTERN _CK_RV CK_FUNC(C_GenerateKeyPair) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's +handle */ + CK_MECHANISM_PTR pMechanism, /* the key gen. +mech. */ + CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* pub. attr. +template */ + CK_ULONG ulPublicKeyAttributeCount, /* # of pub. attrs. +*/ + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* priv. attr. +template */ + CK_ULONG ulPrivateKeyAttributeCount, /* # of priv. attrs. +*/ + CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key +handle */ + CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key +handle */ +); +#endif + + +/* C_WrapKey wraps (i.e., encrypts) a key. */ +CK_EXTERN _CK_RV CK_FUNC(C_WrapKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ + CK_OBJECT_HANDLE hWrappingKey, /* handle of the wrapping key */ + CK_OBJECT_HANDLE hKey, /* handle of the key to be wrapped +*/ + CK_BYTE_PTR pWrappedKey, /* receives the wrapped key */ + CK_ULONG_PTR pulWrappedKeyLen /* receives byte size of wrapped +key */ +); +#endif + + +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key +object. */ +CK_EXTERN _CK_RV CK_FUNC(C_UnwrapKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the unwrapping mechanism */ + CK_OBJECT_HANDLE hUnwrappingKey, /* handle of the unwrapping +key */ + CK_BYTE_PTR pWrappedKey, /* the wrapped key */ + CK_ULONG ulWrappedKeyLen, /* bytes length of wrapped key +*/ + CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */ + CK_ULONG ulAttributeCount, /* # of attributes in template +*/ + CK_OBJECT_HANDLE_PTR phKey /* gets handle of recovered +key */ +); +#endif + + +/* C_DeriveKey derives a key from a base key, creating a new key object. +*/ +CK_EXTERN _CK_RV CK_FUNC(C_DeriveKey) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_MECHANISM_PTR pMechanism, /* the key derivation +mechanism */ + CK_OBJECT_HANDLE hBaseKey, /* handle of the base key */ + CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */ + CK_ULONG ulAttributeCount, /* # of attributes in template +*/ + CK_OBJECT_HANDLE_PTR phKey /* gets handle of derived key +*/ +); +#endif + + + +/* Random number generation */ + +/* C_SeedRandom mixes additional seed material into the token's random +number + * generator. */ +CK_EXTERN _CK_RV CK_FUNC(C_SeedRandom) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR pSeed, /* the seed material */ + CK_ULONG ulSeedLen /* count of bytes of seed material */ +); +#endif + + +/* C_GenerateRandom generates random data. */ +CK_EXTERN _CK_RV CK_FUNC(C_GenerateRandom) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_BYTE_PTR RandomData, /* receives the random data */ + CK_ULONG ulRandomLen /* number of bytes to be generated */ +); +#endif + + + +/* Parallel function management */ + +/* C_GetFunctionStatus obtains an updated status of a function running + * in parallel with an application. */ +CK_EXTERN _CK_RV CK_FUNC(C_GetFunctionStatus) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + +/* C_CancelFunction cancels a function running in parallel. */ +CK_EXTERN _CK_RV CK_FUNC(C_CancelFunction) +#ifdef CK_NEED_ARG_LIST +( + CK_SESSION_HANDLE hSession /* the session's handle */ +); +#endif + + + +/* Functions added in for PKCS #11 Version 2.01 or later */ + +/* C_WaitForSlotEvent waits for a slot event (token insertion, + * removal, etc.) to occur. */ +CK_EXTERN _CK_RV CK_FUNC(C_WaitForSlotEvent) +#ifdef CK_NEED_ARG_LIST +( + CK_FLAGS flags, /* blocking/nonblocking flag */ + CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ + CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ +); +#endif diff --git a/security/nss/lib/fortcrypt/fpkcs11i.h b/security/nss/lib/fortcrypt/fpkcs11i.h new file mode 100644 index 000000000..a4fe414a4 --- /dev/null +++ b/security/nss/lib/fortcrypt/fpkcs11i.h @@ -0,0 +1,272 @@ +/* ***** 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 ***** */ +/* + * Internal data structures used by pkcs11.c + */ +#ifndef _FPKCS11I_H_ +#define _FPKCS11I_H_ 1 + +#include "fpkstrs.h" +#ifdef SWFORT +#ifndef RETURN_TYPE +#define RETURN_TYPE int +#endif +#endif +#include "genci.h" + +typedef struct PK11AttributeStr PK11Attribute; +typedef struct PK11ObjectListStr PK11ObjectList; +typedef struct PK11ObjectListElementStr PK11ObjectListElement; +typedef struct PK11ObjectStr PK11Object; +typedef struct PK11SessionStr PK11Session; +typedef struct PK11SlotStr PK11Slot; +typedef struct PK11SessionContextStr PK11SessionContext; +typedef struct PK11SearchResultsStr PK11SearchResults; + +typedef void (*PK11Destroy)(void *, PRBool); +typedef SECStatus (*PK11Cipher)(void *,void *,unsigned int *,unsigned int, + void *, unsigned int); +typedef SECStatus (*PK11Verify)(void *,void *,unsigned int,void *,unsigned int); +typedef void (*PK11Hash)(void *,void *,unsigned int); +typedef void (*PK11End)(void *,void *,unsigned int *,unsigned int); +typedef void (*PK11Free)(void *); + +#define HASH_SIZE 32 +#define SESSION_HASH_SIZE 64 + +/* Value to tell if an attribute is modifiable or not. + * NEVER: attribute is only set on creation. + * ONCOPY: attribute is set on creation and can only be changed on copy. + * SENSITIVE: attribute can only be changed to TRUE. + * ALWAYS: attribute can always be changed. + */ +typedef enum { + PK11_NEVER = 0, + PK11_ONCOPY = 1, + PK11_SENSITIVE = 2, + PK11_ALWAYS = 3 +} PK11ModifyType; + +/* + * Free Status Enum... tell us more information when we think we're + * deleting an object. + */ +typedef enum { + PK11_DestroyFailure, + PK11_Destroyed, + PK11_Busy +} PK11FreeStatus; + +/* + * attribute values of an object. + */ +struct PK11AttributeStr { + PK11Attribute *next; + PK11Attribute *prev; + int refCount; + void *refLock; + /*must be called handle to make pk11queue_find work */ + CK_ATTRIBUTE_TYPE handle; + CK_ATTRIBUTE attrib; +}; + +struct PK11ObjectListStr { + PK11ObjectList *next; + PK11ObjectList *prev; + PK11Object *parent; +}; + +/* + * PKCS 11 crypto object structure + */ +struct PK11ObjectStr { + PK11Object *next; + PK11Object *prev; + PK11ObjectList sessionList; + CK_OBJECT_HANDLE handle; + int refCount; + void *refLock; + void *attributeLock; + PK11Session *session; + PK11Slot *slot; + CK_OBJECT_CLASS objclass; + void *objectInfo; + PK11Free infoFree; + char *label; + PRBool inDB; + PK11Attribute *head[HASH_SIZE]; +}; + +/* + * struct to deal with a temparary list of objects + */ +struct PK11ObjectListElementStr { + PK11ObjectListElement *next; + PK11Object *object; +}; + +/* + * Area to hold Search results + */ +struct PK11SearchResultsStr { + CK_OBJECT_HANDLE *handles; + int size; + int index; +}; + + +/* + * the universal crypto/hash/sign/verify context structure + */ +typedef enum { + PK11_ENCRYPT, + PK11_DECRYPT, + PK11_HASH, + PK11_SIGN, + PK11_SIGN_RECOVER, + PK11_VERIFY, + PK11_VERIFY_RECOVER +} PK11ContextType; + + +struct PK11SessionContextStr { + PK11ContextType type; + PRBool multi; /* is multipart */ + void *cipherInfo; + unsigned int cipherInfoLen; + CK_MECHANISM_TYPE currentMech; + PK11Cipher update; + PK11Hash hashUpdate; + PK11End end; + PK11Destroy destroy; + PK11Verify verify; + unsigned int maxLen; +}; + +/* + * Sessions (have objects) + */ +struct PK11SessionStr { + PK11Session *next; + PK11Session *prev; + CK_SESSION_HANDLE handle; + int refCount; + void *refLock; + void *objectLock; + int objectIDCount; + CK_SESSION_INFO info; + CK_NOTIFY notify; + CK_VOID_PTR appData; + PK11Slot *slot; + PK11SearchResults *search; + PK11SessionContext *context; + PK11ObjectList *objects[1]; + FortezzaContext fortezzaContext; +}; + +/* + * slots (have sessions and objects) + */ +struct PK11SlotStr { + CK_SLOT_ID slotID; + void *sessionLock; + void *objectLock; + SECItem *password; + PRBool hasTokens; + PRBool isLoggedIn; + PRBool ssoLoggedIn; + PRBool needLogin; + PRBool DB_loaded; + int sessionIDCount; + int sessionCount; + int rwSessionCount; + int tokenIDCount; + PK11Object *tokObjects[HASH_SIZE]; + PK11Session *head[SESSION_HASH_SIZE]; +}; + +/* + * session handle modifiers + */ +#define PK11_PRIVATE_KEY_FLAG 0x80000000L + +/* + * object handle modifiers + */ +#define PK11_TOKEN_MASK 0x80000000L +#define PK11_TOKEN_MAGIC 0x80000000L +#define PK11_TOKEN_TYPE_MASK 0x70000000L +#define PK11_TOKEN_TYPE_CERT 0x00000000L +#define PK11_TOKEN_TYPE_PRIV 0x10000000L + +/* how big a password/pin we can deal with */ +#define PK11_MAX_PIN 255 + +/* slot helper macros */ +#define pk11_SlotFromSessionHandle(handle) (((handle) & PK11_PRIVATE_KEY_FLAG)\ + ? &pk11_slot[1] : &pk11_slot[0]) +#define PK11_TOSLOT1(handle) handle &= ~PK11_PRIVATE_KEY_FLAG +#define PK11_TOSLOT2(handle) handle |= PK11_PRIVATE_KEY_FLAG +#define pk11_SlotFromSession(sp) ((sp)->slot) +#define pk11_SlotFromID(id) ((id) == NETSCAPE_SLOT_ID ? \ + &pk11_slot[0] : (((id) == PRIVATE_KEY_SLOT_ID) ? &pk11_slot[1] : NULL)) +#define pk11_isToken(id) (((id) & PK11_TOKEN_MASK) == PK11_TOKEN_MAGIC) + +/* queueing helper macros */ +#define pk11_hash(value,size) ((value) & (size-1))/*size must be a power of 2*/ +#define pk11queue_add(element,id,head,hash_size) \ + { int tmp = pk11_hash(id,hash_size); \ + (element)->next = (head)[tmp]; \ + (element)->prev = NULL; \ + if ((head)[tmp]) (head)[tmp]->prev = (element); \ + (head)[tmp] = (element); } +#define pk11queue_find(element,id,head,hash_size) \ + for( (element) = (head)[pk11_hash(id,hash_size)]; (element) != NULL; \ + (element) = (element)->next) { \ + if ((element)->handle == (id)) { break; } } +#define pk11queue_delete(element,id,head,hash_size) \ + if ((element)->next) (element)->next->prev = (element)->prev; \ + if ((element)->prev) (element)->prev->next = (element)->next; \ + else (head)[pk11_hash(id,hash_size)] = ((element)->next); \ + (element)->next = NULL; \ + (element)->prev = NULL; \ + +/* expand an attribute & secitem structures out */ +#define pk11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen +#define pk11_item_expand(ip) (ip)->data,(ip)->len + +#endif + diff --git a/security/nss/lib/fortcrypt/fpkcs11t.h b/security/nss/lib/fortcrypt/fpkcs11t.h new file mode 100644 index 000000000..8869c4e91 --- /dev/null +++ b/security/nss/lib/fortcrypt/fpkcs11t.h @@ -0,0 +1,1101 @@ +/* ***** 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 ***** */ +/* + * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document + * is granted provided that it is identified as "RSA Security In.c Public-Key + * Cryptography Standards (PKCS)" in all material mentioning or referencing + * this document. + */ +#ifndef _PKCS11T_H_ +#define _PKCS11T_H_ 1 + +/* an unsigned 8-bit value */ +typedef unsigned char CK_BYTE; + +/* an unsigned 8-bit character */ +typedef CK_BYTE CK_CHAR; + +/* a BYTE-sized Boolean flag */ +typedef CK_BYTE CK_BBOOL; + +/* an unsigned value, at least 32 bits long */ +typedef unsigned long int CK_ULONG; + +/* a signed value, the same size as a CK_ULONG */ +/* CK_LONG is new for v2.0 */ +typedef long int CK_LONG; + +/* at least 32 bits, each bit is a Boolean flag */ +typedef CK_ULONG CK_FLAGS; + +/* some special values for certain CK_ULONG variables */ +#define CK_UNAVAILABLE_INFORMATION (~0UL) +#define CK_EFFECTIVELY_INFINITE 0 + +/* these data types are platform/implementation dependent. */ +#if defined(XP_WIN) +#if defined(_WIN32) +#define CK_ENTRY +#define CK_PTR * /* definition for Win32 */ +#define NULL_PTR 0 /* NULL pointer */ +#pragma pack(push, cryptoki, 1) +#else /* win16 */ +#if defined(__WATCOMC__) +#define CK_ENTRY +#define CK_PTR * /* definition for Win16 */ +#define NULL_PTR 0 /* NULL pointer */ +#pragma pack(push, 1) +#else /* not Watcom 16-bit */ +#define CK_ENTRY +#define CK_PTR * /* definition for Win16 */ +#define NULL_PTR 0 /* NULL pointer */ +#pragma pack(1) +#endif +#endif +#else /* not windows */ +#define CK_ENTRY +#define CK_PTR * /* definition for UNIX */ +#define NULL_PTR 0 /* NULL pointer */ +#endif + + +typedef CK_BYTE CK_PTR CK_BYTE_PTR; /* Pointer to a CK_BYTE */ +typedef CK_CHAR CK_PTR CK_CHAR_PTR; /* Pointer to a CK_CHAR */ +typedef CK_ULONG CK_PTR CK_ULONG_PTR; /* Pointer to a CK_ULONG */ +typedef void CK_PTR CK_VOID_PTR; /* Pointer to a void */ +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; /* Pointer to a CK_VOID_PTR */ + +/* The following value is always invalid if used as a session */ +/* handle or object handle */ +#define CK_INVALID_HANDLE 0 + +typedef struct CK_VERSION { + CK_BYTE major; /* integer portion of the version number */ + CK_BYTE minor; /* hundredths portion of the version number */ +} CK_VERSION; + +typedef CK_VERSION CK_PTR CK_VERSION_PTR; /* points to a CK_VERSION */ + + +typedef struct CK_INFO { + CK_VERSION cryptokiVersion; /* PKCS #11 interface version number */ + CK_CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; /* must be zero */ + + /* libraryDescription and libraryVersion are new for v2.0 */ + CK_CHAR libraryDescription[32]; /* blank padded */ + CK_VERSION libraryVersion; /* version of library */ +} CK_INFO; + +typedef CK_INFO CK_PTR CK_INFO_PTR; /* points to a CK_INFO structure */ + + +/* CK_NOTIFICATION enumerates the types of notifications + * that PKCS #11 provides to an application. */ +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG for v2.0 */ +typedef CK_ULONG CK_NOTIFICATION; +#define CKN_SURRENDER 0 + + +typedef CK_ULONG CK_SLOT_ID; + +/* CK_SLOT_ID_PTR points to a CK_SLOT_ID. */ +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; + + +/* CK_SLOT_INFO provides information about a slot. */ +typedef struct CK_SLOT_INFO { + CK_CHAR slotDescription[64]; /* blank padded */ + CK_CHAR manufacturerID[32]; /* blank padded */ + CK_FLAGS flags; + + /* hardwareVersion and firmwareVersion are new for v2.0 */ + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ +} CK_SLOT_INFO; + +/* flags: bits flags that provide capabilities of the slot. + * Bit Flag Mask Meaning + */ +#define CKF_TOKEN_PRESENT 0x00000001 /* a token is present in the slot */ +#define CKF_REMOVABLE_DEVICE 0x00000002 /* reader supports removable devices*/ +#define CKF_HW_SLOT 0x00000004 /* a hardware slot, not a "soft token"*/ + +/* CK_SLOT_INFO_PTR points to a CK_SLOT_INFO. */ +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; + + +/* CK_TOKEN_INFO provides information about a token. */ +typedef struct CK_TOKEN_INFO { + CK_CHAR label[32]; /* blank padded */ + CK_CHAR manufacturerID[32]; /* blank padded */ + CK_CHAR model[16]; /* blank padded */ + CK_CHAR serialNumber[16]; /* blank padded */ + CK_FLAGS flags; /* see below */ + + /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount, + * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been + * changed from CK_USHORT to CK_ULONG for v2.0 */ + CK_ULONG ulMaxSessionCount; /* max open sessions */ + CK_ULONG ulSessionCount; /* sessions currently open */ + CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ + CK_ULONG ulRwSessionCount; /* R/W sessions currently open */ + CK_ULONG ulMaxPinLen; /* in bytes */ + CK_ULONG ulMinPinLen; /* in bytes */ + CK_ULONG ulTotalPublicMemory; /* in bytes */ + CK_ULONG ulFreePublicMemory; /* in bytes */ + CK_ULONG ulTotalPrivateMemory; /* in bytes */ + CK_ULONG ulFreePrivateMemory; /* in bytes */ + + /* hardwareVersion, firmwareVersion, and time are new for v2.0 */ + CK_VERSION hardwareVersion; /* version of hardware */ + CK_VERSION firmwareVersion; /* version of firmware */ + CK_CHAR utcTime[16]; /* time */ +} CK_TOKEN_INFO; + +/* The flags parameter is defined as follows: + * Table 7-2, Token Information Flags + * Bit Flag Mask Meaning + */ +#define CKF_RNG 0x00000001 /* has random number generator */ +#define CKF_WRITE_PROTECTED 0x00000002 /* token is write-protected */ +#define CKF_LOGIN_REQUIRED 0x00000004 /* a user must be logged in */ +#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's PIN is initialized */ + + +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set, then that means */ +/* that *every* time the state of cryptographic operations of a session is */ +/* successfully saved, all keys needed to continue those operations are */ +/* stored in the state. */ +#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020 /* key always saved in saved sessions */ + +/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, then that means that */ +/* the token has some sort of clock. The time on that clock is returned in */ +/* the token info structure. */ +#define CKF_CLOCK_ON_TOKEN 0x00000040 /* token has a clock */ + +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is true, that means */ +/* that there is some way for the user to login without sending a PIN through */ +/* the PKCS #11 library itself. */ +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100 /* token has protected path */ +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true, that + * means that a single session with the token can perform dual + * simultaneous cryptographic operations (digest and encrypt; + * decrypt and digest; sign and encrypt; and decrypt and sign) */ +#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200 /* dual crypto operations */ + +/* CK_TOKEN_INFO_PTR points to a CK_TOKEN_INFO. */ +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; + + +/* CK_SESSION_HANDLE is a PKCS #11-assigned value that identifies a session. */ +typedef CK_ULONG CK_SESSION_HANDLE; + +/* CK_SESSION_HANDLE_PTR points to a CK_SESSION_HANDLE. */ +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; + + +/* CK_USER_TYPE enumerates the types of PKCS #11 users */ +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for v2.0 */ +typedef CK_ULONG CK_USER_TYPE; +/* Security Officer */ +#define CKU_SO 0 +/* Normal user */ +#define CKU_USER 1 + + +/* CK_STATE enumerates the session states */ +/* CK_STATE has been changed from an enum to a CK_ULONG for v2.0 */ +typedef CK_ULONG CK_STATE; +#define CKS_RO_PUBLIC_SESSION 0 +#define CKS_RO_USER_FUNCTIONS 1 +#define CKS_RW_PUBLIC_SESSION 2 +#define CKS_RW_SO_FUNCTIONS 3 +#define CKS_RW_USER_FUNCTIONS 4 + + +/* CK_SESSION_INFO provides information about a session. */ +typedef struct CK_SESSION_INFO { + CK_SLOT_ID slotID; + CK_STATE state; + CK_FLAGS flags; /* see below */ + + /* ulDeviceError was changed from CK_USHORT to CK_ULONG for v2.0 */ + CK_ULONG ulDeviceError; /* device-dependent error code */ +} CK_SESSION_INFO; + +/* The flags are defined in the following table. */ +/* Table 7-3, Session Information Flags */ +/* Bit Flag Mask Meaning + */ +#define CKF_RW_SESSION 0x00000002 /* session is read/write; not R/O */ +#define CKF_SERIAL_SESSION 0x00000004 /* session doesn't support parallel */ + +/* CK_SESSION_INFO_PTR points to a CK_SESSION_INFO. */ +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; + + +/* CK_OBJECT_HANDLE is a token-specific identifier for an object. */ +typedef CK_ULONG CK_OBJECT_HANDLE; + +/* CK_OBJECT_HANDLE_PTR points to a CK_OBJECT_HANDLE. */ +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; + + +/* CK_OBJECT_CLASS is a value that identifies the classes (or types) + * of objects that PKCS #11 recognizes. It is defined as follows: */ +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_OBJECT_CLASS; + +/* The following classes of objects are defined: */ +#define CKO_DATA 0x00000000 +#define CKO_CERTIFICATE 0x00000001 +#define CKO_PUBLIC_KEY 0x00000002 +#define CKO_PRIVATE_KEY 0x00000003 +#define CKO_SECRET_KEY 0x00000004 +#define CKO_VENDOR_DEFINED 0x80000000L + +/* CK_OBJECT_CLASS_PTR points to a CK_OBJECT_CLASS structure. */ +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; + + +/* CK_KEY_TYPE is a value that identifies a key type. */ +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_KEY_TYPE; + +/* the following key types are defined: */ +#define CKK_RSA 0x00000000 +#define CKK_DSA 0x00000001 +#define CKK_DH 0x00000002 + +/* CKK_ECDSA, and CKK_KEA are new for v2.0 */ +#define CKK_ECDSA 0x00000003 +#define CKK_KEA 0x00000005 + +#define CKK_GENERIC_SECRET 0x00000010 +#define CKK_RC2 0x00000011 +#define CKK_RC4 0x00000012 +#define CKK_DES 0x00000013 +#define CKK_DES2 0x00000014 +#define CKK_DES3 0x00000015 + +/* all these key types are new for v2.0 */ +#define CKK_CAST 0x00000016 +#define CKK_CAST3 0x00000017 +#define CKK_CAST5 0x00000018 +#define CKK_RC5 0x00000019 +#define CKK_IDEA 0x0000001A +#define CKK_SKIPJACK 0x0000001B +#define CKK_BATON 0x0000001C +#define CKK_JUNIPER 0x0000001D +#define CKK_CDMF 0x0000001E + +#define CKK_VENDOR_DEFINED 0x80000000L + +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate type. */ +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_CERTIFICATE_TYPE; + +/* The following certificate types are defined: */ +#define CKC_X_509 0x00000000 +#define CKC_VENDOR_DEFINED 0x80000000L + + +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute type. */ +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_ATTRIBUTE_TYPE; + +/* The following attribute types are defined: */ +#define CKA_CLASS 0x00000000 +#define CKA_TOKEN 0x00000001 +#define CKA_PRIVATE 0x00000002 +#define CKA_LABEL 0x00000003 +#define CKA_APPLICATION 0x00000010 +#define CKA_VALUE 0x00000011 +#define CKA_CERTIFICATE_TYPE 0x00000080 +#define CKA_ISSUER 0x00000081 +#define CKA_SERIAL_NUMBER 0x00000082 +#define CKA_KEY_TYPE 0x00000100 +#define CKA_SUBJECT 0x00000101 +#define CKA_ID 0x00000102 +#define CKA_SENSITIVE 0x00000103 +#define CKA_ENCRYPT 0x00000104 +#define CKA_DECRYPT 0x00000105 +#define CKA_WRAP 0x00000106 +#define CKA_UNWRAP 0x00000107 +#define CKA_SIGN 0x00000108 +#define CKA_SIGN_RECOVER 0x00000109 +#define CKA_VERIFY 0x0000010A +#define CKA_VERIFY_RECOVER 0x0000010B +#define CKA_DERIVE 0x0000010C +#define CKA_START_DATE 0x00000110 +#define CKA_END_DATE 0x00000111 +#define CKA_MODULUS 0x00000120 +#define CKA_MODULUS_BITS 0x00000121 +#define CKA_PUBLIC_EXPONENT 0x00000122 +#define CKA_PRIVATE_EXPONENT 0x00000123 +#define CKA_PRIME_1 0x00000124 +#define CKA_PRIME_2 0x00000125 +#define CKA_EXPONENT_1 0x00000126 +#define CKA_EXPONENT_2 0x00000127 +#define CKA_COEFFICIENT 0x00000128 +#define CKA_PRIME 0x00000130 +#define CKA_SUBPRIME 0x00000131 +#define CKA_BASE 0x00000132 +#define CKA_VALUE_BITS 0x00000160 +#define CKA_VALUE_LEN 0x00000161 + +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, */ +/* and CKA_MODIFIABLE are new for v2.0 */ +#define CKA_EXTRACTABLE 0x00000162 +#define CKA_LOCAL 0x00000163 +#define CKA_NEVER_EXTRACTABLE 0x00000164 +#define CKA_ALWAYS_SENSITIVE 0x00000165 +#define CKA_MODIFIABLE 0x00000170 + +#define CKA_VENDOR_DEFINED 0x80000000L + +/* CK_ATTRIBUTE is a structure that includes the type, length and value + * of an attribute. */ +typedef struct CK_ATTRIBUTE { + CK_ATTRIBUTE_TYPE type; + CK_VOID_PTR pValue; + + /* ulValueLen was changed from CK_USHORT to CK_ULONG for v2.0 */ + CK_ULONG ulValueLen; /* in bytes */ +} CK_ATTRIBUTE; + +/* CK_ATTRIBUTE_PTR points to a CK_ATTRIBUTE. */ +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; + + +/* CK_DATE is a structure that defines a date. */ +typedef struct CK_DATE{ + CK_CHAR year[4]; /* the year ("1900" - "9999") */ + CK_CHAR month[2]; /* the month ("01" - "12") */ + CK_CHAR day[2]; /* the day ("01" - "31") */ +} CK_DATE; + + +/* CK_MECHANISM_TYPE is a value that identifies a mechanism type. */ +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_MECHANISM_TYPE; + +/* the following mechanism types are defined: */ +#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000 +#define CKM_RSA_PKCS 0x00000001 +#define CKM_RSA_9796 0x00000002 +#define CKM_RSA_X_509 0x00000003 + +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS are */ +/* new for v2.0. They are mechanisms which hash and sign */ +#define CKM_MD2_RSA_PKCS 0x00000004 +#define CKM_MD5_RSA_PKCS 0x00000005 +#define CKM_SHA1_RSA_PKCS 0x00000006 + +#define CKM_DSA_KEY_PAIR_GEN 0x00000010 +#define CKM_DSA 0x00000011 +#define CKM_DSA_SHA1 0x00000012 +#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020 +#define CKM_DH_PKCS_DERIVE 0x00000021 +#define CKM_RC2_KEY_GEN 0x00000100 +#define CKM_RC2_ECB 0x00000101 +#define CKM_RC2_CBC 0x00000102 +#define CKM_RC2_MAC 0x00000103 + +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new to v2.0 */ +#define CKM_RC2_MAC_GENERAL 0x00000104 +#define CKM_RC2_CBC_PAD 0x00000105 + +#define CKM_RC4_KEY_GEN 0x00000110 +#define CKM_RC4 0x00000111 +#define CKM_DES_KEY_GEN 0x00000120 +#define CKM_DES_ECB 0x00000121 +#define CKM_DES_CBC 0x00000122 +#define CKM_DES_MAC 0x00000123 + +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new to v2.0 */ +#define CKM_DES_MAC_GENERAL 0x00000124 +#define CKM_DES_CBC_PAD 0x00000125 + +#define CKM_DES2_KEY_GEN 0x00000130 +#define CKM_DES3_KEY_GEN 0x00000131 +#define CKM_DES3_ECB 0x00000132 +#define CKM_DES3_CBC 0x00000133 +#define CKM_DES3_MAC 0x00000134 + +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, */ +/* CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, CKM_CDMF_MAC_GENERAL, */ +/* and CKM_CDMF_CBC_PAD are new to v2.0 */ +#define CKM_DES3_MAC_GENERAL 0x00000135 +#define CKM_DES3_CBC_PAD 0x00000136 +#define CKM_CDMF_KEY_GEN 0x00000140 +#define CKM_CDMF_ECB 0x00000141 +#define CKM_CDMF_CBC 0x00000142 +#define CKM_CDMF_MAC 0x00000143 +#define CKM_CDMF_MAC_GENERAL 0x00000144 +#define CKM_CDMF_CBC_PAD 0x00000145 + +#define CKM_MD2 0x00000200 + +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new to v2.0 */ +#define CKM_MD2_HMAC 0x00000201 +#define CKM_MD2_HMAC_GENERAL 0x00000202 + +#define CKM_MD5 0x00000210 + +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new to v2.0 */ +#define CKM_MD5_HMAC 0x00000211 +#define CKM_MD5_HMAC_GENERAL 0x00000212 + +#define CKM_SHA_1 0x00000220 + +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new to v2.0 */ +#define CKM_SHA_1_HMAC 0x00000221 +#define CKM_SHA_1_HMAC_GENERAL 0x00000222 + +/* All the following mechanisms are new to v2.0 */ +#define CKM_CAST_KEY_GEN 0x00000300 +#define CKM_CAST_ECB 0x00000301 +#define CKM_CAST_CBC 0x00000302 +#define CKM_CAST_MAC 0x00000303 +#define CKM_CAST_MAC_GENERAL 0x00000304 +#define CKM_CAST_CBC_PAD 0x00000305 +#define CKM_CAST3_KEY_GEN 0x00000310 +#define CKM_CAST3_ECB 0x00000311 +#define CKM_CAST3_CBC 0x00000312 +#define CKM_CAST3_MAC 0x00000313 +#define CKM_CAST3_MAC_GENERAL 0x00000314 +#define CKM_CAST3_CBC_PAD 0x00000315 +#define CKM_CAST5_KEY_GEN 0x00000320 +#define CKM_CAST5_ECB 0x00000321 +#define CKM_CAST5_CBC 0x00000322 +#define CKM_CAST5_MAC 0x00000323 +#define CKM_CAST5_MAC_GENERAL 0x00000324 +#define CKM_CAST5_CBC_PAD 0x00000325 +#define CKM_RC5_KEY_GEN 0x00000330 +#define CKM_RC5_ECB 0x00000331 +#define CKM_RC5_CBC 0x00000332 +#define CKM_RC5_MAC 0x00000333 +#define CKM_RC5_MAC_GENERAL 0x00000334 +#define CKM_RC5_CBC_PAD 0x00000335 +#define CKM_IDEA_KEY_GEN 0x00000340 +#define CKM_IDEA_ECB 0x00000341 +#define CKM_IDEA_CBC 0x00000342 +#define CKM_IDEA_MAC 0x00000343 +#define CKM_IDEA_MAC_GENERAL 0x00000344 +#define CKM_IDEA_CBC_PAD 0x00000345 +#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350 +#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360 +#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362 +#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363 +#define CKM_XOR_BASE_AND_DATA 0x00000364 +#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365 +#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370 +#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371 +#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372 +#define CKM_SSL3_MD5_MAC 0x00000380 +#define CKM_SSL3_SHA1_MAC 0x00000381 +#define CKM_MD5_KEY_DERIVATION 0x00000390 +#define CKM_MD2_KEY_DERIVATION 0x00000391 +#define CKM_SHA1_KEY_DERIVATION 0x00000392 +#define CKM_PBE_MD2_DES_CBC 0x000003A0 +#define CKM_PBE_MD5_DES_CBC 0x000003A1 +#define CKM_PBE_MD5_CAST_CBC 0x000003A2 +#define CKM_PBE_MD5_CAST3_CBC 0x000003A3 +#define CKM_PBE_MD5_CAST5_CBC 0x000003A4 +#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5 +#define CKM_PBE_SHA1_RC4_128 0x000003A6 +#define CKM_PBE_SHA1_RC4_40 0x000003A7 +#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8 +#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9 +#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA +#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB +#define CKM_KEY_WRAP_LYNKS 0x00000400 +#define CKM_KEY_WRAP_SET_OAEP 0x00000401 + +/* Fortezza mechanisms */ +#define CKM_SKIPJACK_KEY_GEN 0x00001000 +#define CKM_SKIPJACK_ECB64 0x00001001 +#define CKM_SKIPJACK_CBC64 0x00001002 +#define CKM_SKIPJACK_OFB64 0x00001003 +#define CKM_SKIPJACK_CFB64 0x00001004 +#define CKM_SKIPJACK_CFB32 0x00001005 +#define CKM_SKIPJACK_CFB16 0x00001006 +#define CKM_SKIPJACK_CFB8 0x00001007 +#define CKM_SKIPJACK_WRAP 0x00001008 +#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009 +#define CKM_SKIPJACK_RELAYX 0x0000100a +#define CKM_KEA_KEY_PAIR_GEN 0x00001010 +#define CKM_KEA_KEY_DERIVE 0x00001011 +#define CKM_FORTEZZA_TIMESTAMP 0x00001020 +#define CKM_BATON_KEY_GEN 0x00001030 +#define CKM_BATON_ECB128 0x00001031 +#define CKM_BATON_ECB96 0x00001032 +#define CKM_BATON_CBC128 0x00001033 +#define CKM_BATON_COUNTER 0x00001034 +#define CKM_BATON_SHUFFLE 0x00001035 +#define CKM_BATON_WRAP 0x00001036 +#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 +#define CKM_ECDSA 0x00001041 +#define CKM_ECDSA_SHA1 0x00001042 +#define CKM_JUNIPER_KEY_GEN 0x00001060 +#define CKM_JUNIPER_ECB128 0x00001061 +#define CKM_JUNIPER_CBC128 0x00001062 +#define CKM_JUNIPER_COUNTER 0x00001063 +#define CKM_JUNIPER_SHUFFLE 0x00001064 +#define CKM_JUNIPER_WRAP 0x00001065 +#define CKM_FASTHASH 0x00001070 + +#define CKM_VENDOR_DEFINED 0x80000000L + + +/* CK_MECHANISM_TYPE_PTR points to a CK_MECHANISM_TYPE structure. */ +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; + + +/* CK_MECHANISM is a structure that specifies a particular mechanism. */ +typedef struct CK_MECHANISM { + CK_MECHANISM_TYPE mechanism; + CK_VOID_PTR pParameter; + + /* ulParameterLen was changed from CK_USHORT to CK_ULONG for v2.0 */ + CK_ULONG ulParameterLen; /* in bytes */ +} CK_MECHANISM; + +/* CK_MECHANISM_PTR points to a CK_MECHANISM structure. */ +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; + + +/* CK_MECHANISM_INFO provides information about a particular mechanism. */ +typedef struct CK_MECHANISM_INFO { + CK_ULONG ulMinKeySize; + CK_ULONG ulMaxKeySize; + CK_FLAGS flags; +} CK_MECHANISM_INFO; + +/* The flags are defined as follows. + * Table 7-4, Mechanism Information FLags + * Bit Flag Mask Meaning */ +#define CKF_HW 0x00000001 /* performed by HW device; not SW */ + +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, CKG_SIGN_RECOVER, */ +/* CKF_VERIFY, CKF_VERIFY_RECOVER, CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, */ +/* CKF_UNWRAP, and CKF_DERIVE are new for v2.0 */ +#define CKF_ENCRYPT 0x00000100 /* can be used with C_EncryptInit */ +#define CKF_DECRYPT 0x00000200 /* can be used with C_DecryptInit */ +#define CKF_DIGEST 0x00000400 /* can be used with C_DigestInit */ +#define CKF_SIGN 0x00000800 /* can be used with C_SignInit */ +#define CKF_SIGN_RECOVER 0x00001000 /* can use with C_SignRecoverInit */ +#define CKF_VERIFY 0x00002000 /* can be used with C_VerifyInit */ +#define CKF_VERIFY_RECOVER 0x00004000 /* can use w/ C_VerifyRecoverInit */ +#define CKF_GENERATE 0x00008000L /* can be used with C_GenerateKey */ +#define CKF_GENERATE_KEY_PAIR 0x00010000L /* can use with C_GenerateKeyPair */ +#define CKF_WRAP 0x00020000L /* can be used with C_WrapKey */ +#define CKF_UNWRAP 0x00040000L /* can be used with C_UnwrapKey */ +#define CKF_DERIVE 0x00080000L /* can be used with C_DeriveKey */ + +#define CKF_EXTENSION 0x80000000L /* Must be FALSE for this version */ + +/* CK_MECHANISM_INFO_PTR points to a CK_MECHANISM_INFO structure. */ +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; + + +/* CK_RV is a value that identifies the return value of a PKCS #11 function. */ +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */ +typedef CK_ULONG CK_RV; + +#define CKR_OK 0x00000000 +#define CKR_CANCEL 0x00000001 +#define CKR_HOST_MEMORY 0x00000002 +#define CKR_SLOT_ID_INVALID 0x00000003 + +/* CKR_FLAGS_INVALID was removed for v2.0 */ + +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */ +#define CKR_GENERAL_ERROR 0x00000005 +#define CKR_FUNCTION_FAILED 0x00000006 + +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS, + * and CKR_CANT_LOCK are new for v2.01 */ +#define CKR_ARGUMENTS_BAD 0x00000007 +#define CKR_NO_EVENT 0x00000008 +#define CKR_NEED_TO_CREATE_THREADS 0x00000009 +#define CKR_CANT_LOCK 0x0000000A + +#define CKR_ATTRIBUTE_READ_ONLY 0x00000010 +#define CKR_ATTRIBUTE_SENSITIVE 0x00000011 +#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012 +#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013 +#define CKR_DATA_INVALID 0x00000020 +#define CKR_DATA_LEN_RANGE 0x00000021 +#define CKR_DEVICE_ERROR 0x00000030 +#define CKR_DEVICE_MEMORY 0x00000031 +#define CKR_DEVICE_REMOVED 0x00000032 +#define CKR_ENCRYPTED_DATA_INVALID 0x00000040 +#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041 +#define CKR_FUNCTION_CANCELED 0x00000050 +#define CKR_FUNCTION_NOT_PARALLEL 0x00000051 + +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */ +#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054 + +#define CKR_KEY_HANDLE_INVALID 0x00000060 + +/* CKR_KEY_SENSITIVE was removed for v2.0 */ + +#define CKR_KEY_SIZE_RANGE 0x00000062 +#define CKR_KEY_TYPE_INCONSISTENT 0x00000063 + +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED, + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED, + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are + * new for v2.0 */ +#define CKR_KEY_NOT_NEEDED 0x00000064 +#define CKR_KEY_CHANGED 0x00000065 +#define CKR_KEY_NEEDED 0x00000066 +#define CKR_KEY_INDIGESTIBLE 0x00000067 +#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068 +#define CKR_KEY_NOT_WRAPPABLE 0x00000069 +#define CKR_KEY_UNEXTRACTABLE 0x0000006A + +#define CKR_MECHANISM_INVALID 0x00000070 +#define CKR_MECHANISM_PARAM_INVALID 0x00000071 + +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID + * were removed for v2.0 */ +#define CKR_OBJECT_HANDLE_INVALID 0x00000082 +#define CKR_OPERATION_ACTIVE 0x00000090 +#define CKR_OPERATION_NOT_INITIALIZED 0x00000091 +#define CKR_PIN_INCORRECT 0x000000A0 +#define CKR_PIN_INVALID 0x000000A1 +#define CKR_PIN_LEN_RANGE 0x000000A2 + +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */ +#define CKR_PIN_EXPIRED 0x000000A3 +#define CKR_PIN_LOCKED 0x000000A4 + +#define CKR_SESSION_CLOSED 0x000000B0 +#define CKR_SESSION_COUNT 0x000000B1 +#define CKR_SESSION_HANDLE_INVALID 0x000000B3 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4 +#define CKR_SESSION_READ_ONLY 0x000000B5 +#define CKR_SESSION_EXISTS 0x000000B6 + +/* CKR_SESSION_READ_ONLY_EXISTS and CKR_SESSION_READ_WRITE_SO_EXISTS + * are new for v2.0 */ +#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7 +#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8 + +#define CKR_SIGNATURE_INVALID 0x000000C0 +#define CKR_SIGNATURE_LEN_RANGE 0x000000C1 +#define CKR_TEMPLATE_INCOMPLETE 0x000000D0 +#define CKR_TEMPLATE_INCONSISTENT 0x000000D1 +#define CKR_TOKEN_NOT_PRESENT 0x000000E0 +#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1 +#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2 +#define CKR_USER_ALREADY_LOGGED_IN 0x00000100 +#define CKR_USER_NOT_LOGGED_IN 0x00000101 +#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102 +#define CKR_USER_TYPE_INVALID 0x00000103 + +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES + * are new to v2.01 */ +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104 +#define CKR_USER_TOO_MANY_TYPES 0x00000105 + +#define CKR_WRAPPED_KEY_INVALID 0x00000110 +#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112 +#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113 +#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115 +#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120 + +/* These are new to v2.0 */ +#define CKR_RANDOM_NO_RNG 0x00000121 +#define CKR_INSERTION_CALLBACK_SET 0x00000140 +#define CKR_INSERTION_CALLBACK_NOT_SUPPORTED 0x00000141 +#define CKR_BUFFER_TOO_SMALL 0x00000150 +#define CKR_SAVED_STATE_INVALID 0x00000160 +#define CKR_INFORMATION_SENSITIVE 0x00000170 +#define CKR_STATE_UNSAVEABLE 0x00000180 + +/* These are new to v2.01 */ +#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191 +#define CKR_MUTEX_BAD 0x000001A0 +#define CKR_MUTEX_NOT_LOCKED 0x000001A1 + +#define CKR_VENDOR_DEFINED 0x80000000L + + +/* CK_NOTIFY is an application callback that processes events. */ +typedef CK_RV (CK_ENTRY CK_PTR CK_NOTIFY)( + CK_SESSION_HANDLE hSession, /* the session's handle */ + CK_NOTIFICATION event, + CK_VOID_PTR pApplication /* same as passed to C_OpenSession. */ +); + +/* CK_FUNCTION_LIST is going to be a structure holding a PKCS #11 spec */ +/* version and pointers of appropriate types to all the PKCS #11 functions. */ +/* CK_FUNCTION_LIST is new for v2.0 */ +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; + +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; + +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; + +/* CK_CREATEMUTEX is an application callback for creating a mutex */ +typedef CK_RV CK_ENTRY (CK_PTR CK_CREATEMUTEX)( + CK_VOID_PTR_PTR ppMutex /* location to receive pointer to mutex */ +); + + +/* CK_DESTROYMUTEX is an application callback for destroying a mutex */ +typedef CK_RV CK_ENTRY (CK_PTR CK_DESTROYMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_LOCKMUTEX is an application callback for locking a mutex */ +typedef CK_RV CK_ENTRY (CK_PTR CK_LOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_UNLOCKMUTEX is an application callback for unlocking a mutex */ +typedef CK_RV CK_ENTRY (CK_PTR CK_UNLOCKMUTEX)( + CK_VOID_PTR pMutex /* pointer to mutex */ +); + + +/* CK_C_INITIALIZE_ARGS provides the optional arguments to C_Initialize +*/ +typedef struct CK_C_INITIALIZE_ARGS { + CK_CREATEMUTEX CreateMutex; + CK_DESTROYMUTEX DestroyMutex; + CK_LOCKMUTEX LockMutex; + CK_UNLOCKMUTEX UnlockMutex; + CK_FLAGS flags; + CK_VOID_PTR pReserved; +} CK_C_INITIALIZE_ARGS; + +/* flags: bit flags that provide capabilities of the slot + * Bit Flag Mask Meaning + */ +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001 /* library may not + * spawn its own + * threads */ +#define CKF_OS_LOCKING_OK 0x00000002 /* library can use + * native operating + * system thread + * synchronization */ + +/* CK_C_INITIALIZE_ARGS_PTR is a pointer to a CK_C_INITIALIZE_ARGS */ +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; + + +/* additional flags for parameters to functions */ + +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ +#define CKF_DONT_BLOCK 1 + +/* CK_KEA_DERIVE_PARAMS provides the parameters to the CKM_KEA_DERIVE + * mechanism. */ +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */ +typedef struct CK_KEA_DERIVE_PARAMS { + CK_BBOOL isSender; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pRandomB; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; +} CK_KEA_DERIVE_PARAMS; + +/* CK_KEA_DERIVE_PARAMS_PTR points to a CK_KEA_DERIVE_PARAMS. */ +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; + + +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and CKM_RC2_MAC */ +/* mechanisms. An instance of CK_RC2_PARAMS just holds the effective keysize. */ +typedef CK_ULONG CK_RC2_PARAMS; + + +/* CK_RC2_PARAMS_PTR points to a CK_RC2_PARAMS. */ +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; + + +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC mechanism. */ +typedef struct CK_RC2_CBC_PARAMS { + /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for v2.0 */ + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + + CK_BYTE iv[8]; /* IV for CBC mode */ +} CK_RC2_CBC_PARAMS; + +/* CK_RC2_CBC_PARAMS_PTR points to a CK_RC2_CBC_PARAMS. */ +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; + +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the */ +/* CKM_RC2_MAC_GENERAL mechanism. */ +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */ +typedef struct CK_RC2_MAC_GENERAL_PARAMS { + CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ +} CK_RC2_MAC_GENERAL_PARAMS; + +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR CK_RC2_MAC_GENERAL_PARAMS_PTR; + + +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and CKM_RC5_MAC */ +/* mechanisms. */ +/* CK_RC5_PARAMS is new for v2.0 */ +typedef struct CK_RC5_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ +} CK_RC5_PARAMS; + +/* CK_RC5_PARAMS_PTR points to a CK_RC5_PARAMS. */ +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; + + +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC mechanism. */ +/* CK_RC5_CBC_PARAMS is new for v2.0 */ +typedef struct CK_RC5_CBC_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_BYTE_PTR pIv; /* pointer to IV */ + CK_ULONG ulIvLen; /* length of IV in bytes */ +} CK_RC5_CBC_PARAMS; + +/* CK_RC5_CBC_PARAMS_PTR points to a CK_RC5_CBC_PARAMS. */ +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; + + +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the */ +/* CKM_RC5_MAC_GENERAL mechanism. */ +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */ +typedef struct CK_RC5_MAC_GENERAL_PARAMS { + CK_ULONG ulWordsize; /* wordsize in bits */ + CK_ULONG ulRounds; /* number of rounds */ + CK_ULONG ulMacLength; /* Length of MAC in bytes */ +} CK_RC5_MAC_GENERAL_PARAMS; + +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR CK_RC5_MAC_GENERAL_PARAMS_PTR; + + +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block ciphers' */ +/* MAC_GENERAL mechanisms. Its value is the length of the MAC. */ +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */ +typedef CK_ULONG CK_MAC_GENERAL_PARAMS; + +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; + + +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */ +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { + CK_ULONG ulPasswordLen; + CK_BYTE_PTR pPassword; + CK_ULONG ulPublicDataLen; + CK_BYTE_PTR pPublicData; + CK_ULONG ulPAndGLen; + CK_ULONG ulQLen; + CK_ULONG ulRandomLen; + CK_BYTE_PTR pRandomA; + CK_BYTE_PTR pPrimeP; + CK_BYTE_PTR pBaseG; + CK_BYTE_PTR pSubprimeQ; +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS; + +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR points to a + * CK_SKIPJACK_PRIVATE_WRAP_PARAMS */ +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ + CK_SKIPJACK_PRIVATE_WRAP_PTR; + + +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the + * CKM_SKIPJACK_RELAYX mechanism */ +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */ +typedef struct CK_SKIPJACK_RELAYX_PARAMS { + CK_ULONG ulOldWrappedXLen; + CK_BYTE_PTR pOldWrappedX; + CK_ULONG ulOldPasswordLen; + CK_BYTE_PTR pOldPassword; + CK_ULONG ulOldPublicDataLen; + CK_BYTE_PTR pOldPublicData; + CK_ULONG ulOldRandomLen; + CK_BYTE_PTR pOldRandomA; + CK_ULONG ulNewPasswordLen; + CK_BYTE_PTR pNewPassword; + CK_ULONG ulNewPublicDataLen; + CK_BYTE_PTR pNewPublicData; + CK_ULONG ulNewRandomLen; + CK_BYTE_PTR pNewRandomA; +} CK_SKIPJACK_RELAYX_PARAMS; + +/* CK_SKIPJACK_RELAYX_PARAMS_PTR points to a CK_SKIPJACK_RELAYX_PARAMS +*/ +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR CK_SKIPJACK_RELAYX_PARAMS_PTR; + +typedef struct CK_PBE_PARAMS { + CK_CHAR_PTR pInitVector; + CK_CHAR_PTR pPassword; + CK_ULONG ulPasswordLen; + CK_CHAR_PTR pSalt; + CK_ULONG ulSaltLen; + CK_ULONG ulIteration; +} CK_PBE_PARAMS; + +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; + + +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the */ +/* CKM_KEY_WRAP_SET_OAEP mechanism. */ +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */ +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { + CK_BYTE bBC; /* block contents byte */ + CK_BYTE_PTR pX; /* extra data */ + CK_ULONG ulXLen; /* length of extra data in bytes */ +} CK_KEY_WRAP_SET_OAEP_PARAMS; + +/* CK_KEY_WRAP_SET_OAEP_PARAMS_PTR points to a CK_KEY_WRAP_SET_OAEP_PARAMS. */ +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; + +/* CK_BATON_PARAMS provides the parameters to the CKM_BATON_ECB128, */ +/* CKM_BATON_ECB96, CKM_BATON_CBC128, CKM_BATON_COUNTER, and */ +/* CKM_BATON_SHUFFLE mechanisms. */ +/* CK_BATON_PARAMS is new for v2.0 */ +typedef struct CK_BATON_PARAMS { + CK_BYTE iv[24]; +} CK_BATON_PARAMS; + +/* CK_BATON_PARAMS_PTR points to a CK_BATON_PARAMS. */ +typedef CK_BATON_PARAMS CK_PTR CK_BATON_PARAMS_PTR; + + +typedef struct CK_SSL3_RANDOM_DATA { + CK_BYTE_PTR pClientRandom; + CK_ULONG ulClientRandomLen; + CK_BYTE_PTR pServerRandom; + CK_ULONG ulServerRandomLen; +} CK_SSL3_RANDOM_DATA; + + +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { + CK_SSL3_RANDOM_DATA RandomInfo; + CK_VERSION_PTR pVersion; +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS; + +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ + CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; + + +typedef struct CK_SSL3_KEY_MAT_OUT { + CK_OBJECT_HANDLE hClientMacSecret; + CK_OBJECT_HANDLE hServerMacSecret; + CK_OBJECT_HANDLE hClientKey; + CK_OBJECT_HANDLE hServerKey; + CK_BYTE_PTR pIVClient; + CK_BYTE_PTR pIVServer; +} CK_SSL3_KEY_MAT_OUT; + +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; + + +typedef struct CK_SSL3_KEY_MAT_PARAMS { + CK_ULONG ulMacSizeInBits; + CK_ULONG ulKeySizeInBits; + CK_ULONG ulIVSizeInBits; + CK_BBOOL bIsExport; + CK_SSL3_RANDOM_DATA RandomInfo; + CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; +} CK_SSL3_KEY_MAT_PARAMS; + +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; + +/* The CK_DERIVATION_STRING_DATA is used for bunches of Deriviation + * Mechanisms. */ +typedef struct CK_KEY_DERIVATION_STRING_DATA { + CK_BYTE_PTR pData; + CK_ULONG ulLen; +} CK_KEY_DERIVATION_STRING_DATA; +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR CK_KEY_DERIVATION_STRING_DATA_PTR; + +/* The CK_EXTRACT_PARAMS is used for the CKM_EXTRACT_KEY_FROM_KEY mechanism. */ +/* CK_EXTRACT_PARAMS is new for v2.0 */ +typedef CK_ULONG CK_EXTRACT_PARAMS; + +/* CK_EXTRACT_PARAMS_PTR points to a CK_EXTRACT_PARAMS. */ +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; + + +/* Do not attempt to use these. They are only used by NETSCAPE's internal + * PKCS #11 interface. Most of these are place holders for other mechanism + * and will change in the future. + */ +#define CKM_NETSCAPE_PBE_KEY_GEN 0x80000001L +#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L +#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L +#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L +#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L +#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L +#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L +#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L +#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L +#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L + +/* define used to pass in the database key for DSA private keys */ +#define CKA_NETSCAPE_DB 0xD5A0DB00L +#define CKA_NETSCAPE_TRUST 0x80000001L + +#if defined(XP_WIN) +#if defined(_WIN32) +#pragma pack(pop, cryptoki) +#else /* win16 */ +#if defined(__WATCOMC__) +#pragma pack(pop) +#else /* not Watcom 16-bit */ +#pragma pack() +#endif +#endif +#endif + +#endif diff --git a/security/nss/lib/fortcrypt/fpkmem.h b/security/nss/lib/fortcrypt/fpkmem.h new file mode 100644 index 000000000..ac95147fc --- /dev/null +++ b/security/nss/lib/fortcrypt/fpkmem.h @@ -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 ***** */ +#ifndef _FPKMEM_H_ +#define _FPKMEM_H_ + +#define PORT_Free free +#define PORT_Alloc malloc + +#define PORT_Memcmp memcmp +#define PORT_Memcpy memcpy + +#define NUM_SLOTS 32 + +#if !defined (XP_UNIX) && !defined (_WINDOWS) && !defined (XP_OS2) && !defined (XP_BEOS) +#define XP_MAC 1 /*Make sure we get this define in for Mac builds*/ +#endif + +#endif /*_FPKMEM_H_*/ diff --git a/security/nss/lib/fortcrypt/fpkstrs.h b/security/nss/lib/fortcrypt/fpkstrs.h new file mode 100644 index 000000000..ea8da8601 --- /dev/null +++ b/security/nss/lib/fortcrypt/fpkstrs.h @@ -0,0 +1,125 @@ +/* ***** 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 _context_h_ +#define _context_h_ + +#ifdef SWFORT +#ifndef RETURN_TYPE +#define RETURN_TYPE int +#endif +#endif +#include "cryptint.h" +#include "genci.h" +#include "maci.h" + +typedef enum {NOKEY, TEK, MEK, UNWRAP, Ks} FortezzaKeyType; +typedef enum {Encrypt, Decrypt, Sign, None} CryptoType; + +typedef struct FortezzaKeyStr *FortezzaKeyPtr; +typedef struct FortezzaSocketStr *FortezzaSocketPtr; +typedef struct FortezzaKeyStr FortezzaKey; +typedef unsigned char FortezzaMEK[12]; + + +typedef struct CreateTEKInfoStr { + CI_RA Ra; + CI_RB Rb; + unsigned long randomLen; + int personality; + int flag; /*Either CI_INITIATOR_FLAG or CI_RECIPIENT_FLAG*/ + CI_Y pY; + unsigned int YSize; +} CreateTEKInfo; + +typedef struct FortezzaTEKStr { + CI_RA Ra; /*All the parameters necessary to create a TEK */ + CI_RB Rb; + unsigned long randomLen; + CI_Y pY; + int flags; + int registerIndex; + unsigned int ySize; +} FortezzaTEK; + +struct FortezzaKeyStr { + FortezzaKeyPtr next, prev; + CK_OBJECT_HANDLE keyHandle; + int keyRegister; + FortezzaKeyType keyType; + FortezzaSocketPtr keySocket; + unsigned long id; + unsigned long hitCount; + union { + FortezzaTEK tek; + FortezzaMEK mek; + } keyData; +}; + +typedef struct FortezzaSocketStr { + PRBool isOpen; + PRBool isLoggedIn; + PRBool hasLoggedIn; + PRBool personalitiesLoaded; + unsigned long slotID; + unsigned long hitCount; + HSESSION maciSession; + CI_SERIAL_NUMBER openCardSerial; + CI_STATE openCardState; + CI_PERSON *personalityList; + int numPersonalities; + int numKeyRegisters; + FortezzaKey **keyRegisters; /*Array of pointers to keys in registers*/ + FortezzaKey *keys; /*Linked list of all the keys*/ + void *registersLock; +} FortezzaSocket; + +typedef struct PK11SessionStr *PK11SessionPtr; + +typedef struct FortezzaConstextStr { + FortezzaKey *fortezzaKey; + FortezzaSocket *fortezzaSocket; + PK11SessionPtr session; + CryptoType cryptoOperation; + CK_MECHANISM_TYPE mechanism; + CI_SAVE_DATA cardState; + CI_IV cardIV; + unsigned long userRamSize; + CK_OBJECT_HANDLE hKey; +} FortezzaContext; + + + +#endif /*_context_h_*/ diff --git a/security/nss/lib/fortcrypt/genci.h b/security/nss/lib/fortcrypt/genci.h new file mode 100644 index 000000000..1e3bdac24 --- /dev/null +++ b/security/nss/lib/fortcrypt/genci.h @@ -0,0 +1,148 @@ +/* ***** 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 ***** */ +/* + * the following header file switches between MACI and CI based on + * compile options. That lest the rest of the source code operate + * without change, even if it only suports CI_ calls, not MACI_ calls + */ +#ifndef _GENCI_H_ +#define _GENCI_H_ 1 +#include "seccomon.h" + +#if defined (XP_UNIX) || defined (XP_WIN32) || defined (XP_OS2) || defined (XP_BEOS) + +/* + * On unix, NT, Windows '95, and OS/2 we use full maci + */ +#include "maci.h" + +#define MACI_SEL(x) + +/* + * for sec-for.c + */ +#define CI_Initialize MACI_Initialize +#define CI_Terminate() { HSESSION hs;\ + MACI_GetSessionID(&hs);\ + MACI_Terminate(hs); } + +#else + +/* + * On Mac we use the original CI_LIB + */ +#include "cryptint.h" + +/* + * MACI specific values not defined for CI lib + */ +#define MACI_SESSION_EXCEEDED (-53) + +#ifndef HSESSION_DEFINE +typedef unsigned int HSESSION; +#define HSESSION_DEFINE +#endif + +/* + * Map MACI_ calls to CI_ calls. NOTE: this assumes the proper CI_Select + * calls are issued in the CI_ case + */ +#define MACI_ChangePIN(s,pin,old,new) CI_ChangePIN(pin,old,new) +#define MACI_CheckPIN(s,type,pin) CI_CheckPIN(type,pin) +#define MACI_Close(s,flag,socket) CI_Close(flag,socket) +#define MACI_Decrypt(s,size,in,out) CI_Decrypt(size,in,out) +#define MACI_DeleteCertificate(s,cert) CI_DeleteCertificate(cert) +#define MACI_DeleteKey(s,index) CI_DeleteKey(index) +#define MACI_Encrypt(s,size,in,out) CI_Encrypt(size,in,out) +#define MACI_ExtractX(s,cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g) \ + CI_ExtractX(cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g) +#define MACI_FirmwareUpdate(s,flags,Cksum,len,size,data) \ + CI_FirmwareUpdate(flags,Cksum,len,size,data) +#define MACI_GenerateIV(s,iv) CI_GenerateIV(iv) +#define MACI_GenerateMEK(s,index,res) CI_GenerateMEK(index,res) +#define MACI_GenerateRa(s,Ra) CI_GenerateRa(Ra) +#define MACI_GenerateRandom(s,ran) CI_GenerateRandom(ran) +#define MACI_GenerateTEK(s,flag,index,Ra,Rb,size,Y) \ + CI_GenerateTEK(flag,index,Ra,Rb,size,Y) +#define MACI_GenerateX(s,cert,type,pgSize,qSize,p,q,g,ySize,y) \ + CI_GenerateX(cert,type,pgSize,qSize,p,q,g,ySize,y) +#define MACI_GetCertificate(s,cert,val) CI_GetCertificate(cert,val) +#define MACI_GetConfiguration(s,config) CI_GetConfiguration(config) +#define MACI_GetHash(s,size,data,val) CI_GetHash(size,data,val) +#define MACI_GetPersonalityList(s,cnt,list) CI_GetPersonalityList(cnt,list) +#define MACI_GetSessionID(s) CI_OK +#define MACI_GetState(s,state) CI_GetState(state) +#define MACI_GetStatus(s,status) CI_GetStatus(status) +#define MACI_GetTime(s,time) CI_GetTime(time) +#define MACI_Hash(s,size,data) CI_Hash(size,data) +#define MACI_Initialize(count) CI_Initialize(count) +#define MACI_InitializeHash(s) CI_InitializeHash() +#define MACI_InstallX(s,cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g) \ + CI_InstallX(cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g) +#define MACI_LoadCertificate(s,cert,label,data,res) \ + CI_LoadCertificate(cert,label,data,res) +#define MACI_LoadDSAParameters(s,pgSize,qSize,p,q,g) \ + CI_LoadDSAParameters(pgSize,qSize,p,q,g) +#define MACI_LoadInitValues(s,seed,Ks) CI_LoadInitValues(seed,Ks) +#define MACI_LoadIV(s,iv) CI_LoadIV(iv) +#define MACI_LoadX(s,cert,type,pgSize,qSize,p,q,g,x,ySize,y) \ + CI_LoadX(cert,type,pgSize,qSize,p,q,g,x,ySize,y) +#define MACI_Lock(s,flags) CI_Lock(flags) +#define MACI_Open(s,flags,index) CI_Open(flags,index) +#define MACI_RelayX(s,oPass,oSize,oY,oRa,oX,nPass,nSize,nY,nRa,nX) \ + CI_RelayX(oPass,oSize,oY,oRa,oX,nPass,nSize,nY,nRa,nX) +#define MACI_Reset(s) CI_Reset() +#define MACI_Restore(s,type,data) CI_Restore(type,data) +#define MACI_Save(s,type,data) CI_Save(type,data) +#define MACI_Select(s,socket) CI_Select(socket) +#define MACI_SetConfiguration(s,typ,sz,d) CI_SetConfiguration(typ,sz,d) +#define MACI_SetKey(s,key) CI_SetKey(key) +#define MACI_SetMode(s,type,mode) CI_SetMode(type,mode) +#define MACI_SetPersonality(s,index) CI_SetPersonality(index) +#define MACI_SetTime(s,time) CI_SetTime(time) +#define MACI_Sign(s,hash,sig) CI_Sign(hash,sig) +#define MACI_Terminate(s) CI_Terminate() +#define MACI_TimeStamp(s,val,sig,time) CI_TimeStamp(val,sig,time) +#define MACI_Unlock(s) CI_Unlock() +#define MACI_UnwrapKey(s,targ,wrap,key) CI_UnwrapKey(targ,wrap,key) +#define MACI_VerifySignature(s,h,siz,y,sig) CI_VerifySignature(h,siz,y,sig) +#define MACI_VerifyTimeStamp(s,hash,sig,tim) CI_VerityTimeStap(hash,sig,tim) +#define MACI_WrapKey(s,src,wrap,key) CI_WrapKey(src,wrap,key) +#define MACI_Zeroize(s) CI_Zeroize() + +#define MACI_SEL(x) CI_Select(x) +#endif /* ! XP_UNIX */ +#endif /* _GENCI_H_ */ diff --git a/security/nss/lib/fortcrypt/globinst.htm b/security/nss/lib/fortcrypt/globinst.htm new file mode 100644 index 000000000..3ecb23c89 --- /dev/null +++ b/security/nss/lib/fortcrypt/globinst.htm @@ -0,0 +1,143 @@ +<HTML> +<-- + - ***** 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 ***** --> +<SCRIPT> + + +// ---------------------- Configuration variables ---------------- +var pkcs11jar="fortpk11.jar"; +//var pkcs11base="file://d|/dogbert/ns/dist/"; +pkcs11base=""; + +var comm_platforms = pk_init_array ( + "Win32", "Win16", "Mac68k", "MacPPC", + "AIX4.1", "HP-UXA.09", "HP-UXB.10", + "SunOS4.1.3_U1", "SunOS5.4", "SunOS5.5.1" ); +var directories = pk_init_array ( + "win32", "win16", "none", "macppc", + "aix", "hpux", "hpux", + "sunos", "sol24", + "sol251" ); + +function mapPlatform(InPlat) +{ + for (i=0; i < comm_platforms.length; i++) { + if (InPlat == comm_platforms[i]) { + return directories[i]; + } + } + return InPlat; +} + + +function pk_init_array() +{ + var numArgs = pk_init_array.arguments.length; + var a = new Array(numArgs); + + for (var i = 0; i < numArgs; i++) { + a[i] = pk_init_array.arguments[i]; + } + return a; +} + +function getPlatform() { + return navigator.platform; +// var string = navigator.appVersion; +// start = string.indexOf("(",0); +// if (start == -1) { +// return "unknown"; +// } +// end = string.indexOf(";",start); +// if (end == -1) { +// end = string.indexOf(")",start); +// } +// if (end == -1) { +// end = string.length; +// } +// platform = string.substring(start+1,end); +// return platform; +} + +function getURLPath() { + var string = window.location.href; + end = string.lastIndexOf("/"); + if (end == -1) { + end = string.length-1; + } + return string.substring(0,end+1); +} + + + +plat=getPlatform(); +platDir = mapPlatform(plat); +if (pkcs11base == "") pkcs11base=getURLPath(); + +if (plat == "MacPPC") { + pkcs11jar= "macinst.htm" +} + +function DoInstall(url) { + window.location.href = url; +} + +function DoCancel() { + // set window.location.href to your home page if you wish + //alert('Cancel Installation?'); + history.back(); +} + +// ------ Change the following for your own Message -------- +document.write("<CENTER><H1>Netscape Fortezza PKCS #11 Module Installer</H1>"); +document.write("</CENTER>"); +document.write("<Table><TR><TD>"); +document.write("<DD><p><IMG SRC=about:logo WIDTH=90 Height=77 NAME=LITRONIC></TD>"); +document.write("<TD VAlign=Center><i> Netscape Fortezza PKCS #11 Modules require Litronic's MACI drivers to be installed on your platform."); +document.write(" If you haven't already installed theLitronic MACI drivers, please to do so now.</I>"); +document.write("</TD></TR></Table>"); +// ----- end of generic message section -------- +document.write("<p>Netscape has detected you are installing on <b>"+plat+"</b>.<br>"); +document.write("Installing: <b>"+pkcs11base+platDir+"/"+pkcs11jar+"</b><br>"); +document.write("<FORM>"); +document.write("<CENTER><Table><TR><TD><Input Type=Button name=install value='Install Now' onclick=DoInstall("+ "\"" +pkcs11base+platDir+"/"+pkcs11jar+"\""+")>"); +document.write("</TD><TD><Input type=Button name=cancel value=Cancel Onclick=DoCancel()>"); +document.write("</TD></TR></Table></CENTER>"); +document.write("</FORM>"); +document.close(); +</SCRIPT> +</HTML> diff --git a/security/nss/lib/fortcrypt/handinst.htm b/security/nss/lib/fortcrypt/handinst.htm new file mode 100644 index 000000000..82fa213e0 --- /dev/null +++ b/security/nss/lib/fortcrypt/handinst.htm @@ -0,0 +1,184 @@ +<HTML> +<TITLE>Generic PKCS #11 Installer</TITLE> +<-- + - ***** 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 ***** --> +<SCRIPT> +// Crypto Mechanism Flags +PKCS11_MECH_RSA_FLAG = 0x1<<0; +PKCS11_MECH_DSA_FLAG = 0x1<<1; +PKCS11_MECH_RC2_FLAG = 0x1<<2; +PKCS11_MECH_RC4_FLAG = 0x1<<3; +PKCS11_MECH_DES_FLAG = 0x1<<4; +PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman +PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards +PKCS11_MECH_RC5_FLAG = 0x1<<7; +PKCS11_MECH_SHA1_FLAG = 0x1<<8; +PKCS11_MECH_MD5_FLAG = 0x1<<9; +PKCS11_MECH_MD2_FLAG = 0x1<<10; +PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator +PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in +PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default + +// Important: +// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should always be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which mechanisms should be turned on by +pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG; + + +// Ciphers that support SSL or S/MIME +PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0; + +// Important: +// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should ALWAYS be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which SSL ciphers are supported +pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG; + + +// Return values of pkcs11.addmodule() & pkcs11.delmodule() +// success codes +JS_OK_ADD_MODULE = 3 // Successfully added a module +JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module +JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module + +// failure codes +JS_ERR_OTHER = -1 // Other errors than the followings +JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action +JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments +JS_ERR_DEL_MODULE = -4 // Error deleting a module +JS_ERR_ADD_MODULE = -5 // Error adding a module +JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid +JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad +JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid +JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid + +var new_window; +var has_new_window = 0; + +function HandleCipher(checkBox) { + if (checkBox.checked) { + pkcs11MechanismFlags |= checkBox.value; + } else { + pkcs11MechanismFlags &= ~checkBox.value; + } +} + +function HandleSSL(checkBox) { + if (checkBox.checked) { + pkcs11CipherFlags |= checkBox.value; + } else { + pkcs11CipherFlags &= ~checkBox.value; + } +} + +function colonize(string) { + len = string.length; + end = len -1; + + if (len == 0) return string; + + + for (i=0; i < len; i++) { + if (string.charAt(i) == "/") { + if (i == 0) { + new_string = ":" + string.substring(1,len); + } else if (i == end) { + new_string = string.substring(0,i)+':'; + } else { + new_string = string.substring(0,i)+':'+ + string.substring(i+1,len); + } + string = new_string; + } + } + + if (string.charAt(0) == ":") string = string.substring(1,len); + return string; +} + +function DoInstall(name,module) { + if ((navigator.platform == "MacPPC") + || (navigator.platform == "Mac68K")) { + module = colonize(module); + } + result = pkcs11.addmodule(name, module, + pkcs11MechanismFlags, pkcs11CipherFlags); + if ( result < 0) { + window.alert("New module setup failed. Error code: " + result); + } + if (has_new_window) new_window.close(); +} + +default_name = "Netscape FORTEZZA Module" + +default_module = "D:/dogbert/ns/dist/WIN32_D.OBJ/bin/fort32.dll" +document.writeln("<FORM name=instform target=_self> <H2>PKCS #11 Installer</H2>"); +document.writeln(" Module name: <Input Type=Text Name=modName value=\""+default_name+"\" size=50 required><br>"); +document.writeln(" Module Library: <Input Type=FILE required Name=module><p>"); +document.writeln("<hr><TABLE><TR><TD>"); +document.writeln("<Input type=Checkbox name=RSA value="+PKCS11_MECH_RSA_FLAG+" onclick=HandleCipher(document.instform.RSA)> RSA<br>"); +document.writeln("<Input type=Checkbox name=DSA value="+PKCS11_MECH_DSA_FLAG+" onclick=HandleCipher(document.instform.DSA)> DSA<br>"); +document.writeln("<Input type=Checkbox name=RC2 value="+PKCS11_MECH_RC2_FLAG+" onclick=HandleCipher(document.instform.RC2)> RC2<br>"); +document.writeln("<Input type=Checkbox name=RC4 value="+PKCS11_MECH_RC4_FLAG+" onclick=HandleCipher(document.instform.RC4)> RC4<br>"); +document.writeln("</TD><TD>"); +document.writeln("<Input type=Checkbox name=DES value="+PKCS11_MECH_DES_FLAG+" onclick=HandleCipher(document.instform.DES)> DES<br>"); +document.writeln("<Input type=Checkbox name=DH value="+PKCS11_MECH_DH_FLAG+" onclick=HandleCipher(document.instform.DH)> DH<br>"); +document.writeln("<Input type=Checkbox name=SKIPJACK value="+PKCS11_MECH_SKIPJACK_FLAG+" onclick=HandleCipher(document.instform.SKIPJACK)> SKIPJACK<br>"); +document.writeln("<Input type=Checkbox name=RC5 value="+PKCS11_MECH_RC5_FLAG+" onclick=HandleCipher(document.instform.RC5)> RC5<br>"); +document.writeln("</TD><TD>"); +document.writeln("<Input type=Checkbox name=SHA1 value="+PKCS11_MECH_SHA1_FLAG+" onclick=HandleCipher(document.instform.SHA1)> SHA1<br>"); +document.writeln("<Input type=Checkbox name=MD5 value="+PKCS11_MECH_MD5_FLAG+" onclick=HandleCipher(document.instform.MD5)> MD5<br>"); +document.writeln("<Input type=Checkbox name=MD2 value="+PKCS11_MECH_MD2_FLAG+" onclick=HandleCipher(document.instform.MD2)> MD2<br>"); +document.writeln("</TD><TD>"); +document.writeln("<Input type=Checkbox name=Random value="+PKCS11_MECH_RANDOM_FLAG+" CHECKED onclick=HandleCipher(document.instform.Random)> Random Number Generation<br>"); +document.writeln("<Input type=Checkbox name=readCert value="+PKCS11_PUB_READABLE_CERT_FLAG+" onclick=HandleCipher(document.instform.ReadCert)> Public Readable Certificates<br>"); +document.writeln("<Input type=Checkbox name=Disable value="+PKCS11_DISABLE_FLAG+" onclick=HandleCipher(document.instform.Disable)> Disable<br>"); +document.writeln("</TD></TR></TABLE>"); +document.writeln("<hr>"); +document.writeln("<Input type=Checkbox name=fortssl value="+ PKCS11_CIPHER_FORTEZZA_FLAG +" checked onclick=HandleSSL(document.instform.fortssl)> Enable FORTEZZA menus<br>"); +document.writeln("<hr>"); +document.write("<Input type=submit Name=Install Value=Install onclick=DoInstall("); +document.writeln( "document.instform.modName.value,document.instform.module.value) >"); +document.writeln("</FORM>"); +</SCRIPT> diff --git a/security/nss/lib/fortcrypt/homeinst.htm b/security/nss/lib/fortcrypt/homeinst.htm new file mode 100644 index 000000000..6b4516a09 --- /dev/null +++ b/security/nss/lib/fortcrypt/homeinst.htm @@ -0,0 +1,215 @@ +<HTML> +<-- + - ***** 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 ***** --> +<SCRIPT> + + +// ---------------------- Configuration variables ---------------- +var pkcs11jar="bin/fortWIN32.jar"; +var pkcs11base="ftp://sweetlou/products/client/dogbert/new"; +//pkcs11base=""; +win_file = "libfort.jar" +unix = "libfort-v404b9." +mac_file = "macinst.htm" + + +var winDates = pk_init_array ( + "oct_02a_404", "oct_01a_404" ); + +var unixDates = pk_init_array ( + "current", "Oct_02", "Oct_O1"); + + +var comm_platforms = pk_init_array ( + "Win32", "Win16", "Mac68k", "MacPPC", + "AIX4.1", "HP-UXA.09", "HP-UXB.10", + "SunOS4.1.3_U1", "SunOS5.4", "SunOS5.5.1", + "BSD_3861.1","BSD_3862.1", "FreeBSD2", "IRIX5.3", "IRIX6.2", + "LinuxELF1.2","LinusELF2.0","NCR4.0","NEC4.2","OSF1V3","SCOOS5.0", + "SINIX-N5.42","SunOS5.4_i86pc","UNIXWARE2.1", + "OS23.0","OS24.0"); +var isSupport = pk_init_array ( 1, 1, 0, 1, + 1, 1, 1, + 1, 1, 1, 1, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, + 0, 0 ); +var directories = pk_init_array ( + "32bit/fortezza", "16bit/fortezza", "", "404-fortezza-items", + "aix4", "hpux", "hpux10", + "sunos4", "sol24", "sol251", + // not really supported + "bsdi", "bsdi2", "freebsd", "irix53", "irix62", + "linux12","linux20","ncr","nec","osf132","sco", + "sinix","solx86","unixware", + "" ,"" ); +var files = pk_init_array ( + win_file, win_file, mac_file, mac_file, + unix+"rs6000-ibm-aix4.jar",unix+"hppa1.1-hp-hpux9.jar", + unix+"hppa1.1-hp-hpux10.jar", + unix+"sparc-sun-sunos4.1.3_U1.jar",unix+"sparc-sun-solaris2.4.jar", + unix+"sparc-sun-solaris2.5.1.jar", + unix+"x86-bsdi-bsd.jar",unix+"x86-bsdi-bsd2.jar", + unix+"x86-unknown-freebsd.jar", + unix+"mips-sgi-irix5.3.jar",unix+"mips-sgi-irix6.2.jar", + unix+"x86-unknown-linix1.2.jar",unix+"x86-unknown-linix2.0.jar", + unix+"x86-ncr-sysv5.jar",unix+"mips-nec-uxv4.2.jar", + unix+"alpha-dec-osf3.2.jar",unix+"x86-sco-opensv5.0.2", + unix+"mips-sni-reliantunix.jar",unix+"x86-sun-solaris2.4.jar", + unix+"x86-sco-unixware2.1.jar", + win_file, win_file ); + +function isSupported(InPlat) +{ + for (i=0; i < comm_platforms.length; i++) { + if (InPlat == comm_platforms[i]) { + return isSupport[i]; + } + } + return 0; +} + +function mapPlatform(InPlat) +{ + for (i=0; i < comm_platforms.length; i++) { + if (InPlat == comm_platforms[i]) { + return directories[i]; + } + } + return InPlat; +} + +function mapFile(InPlat) +{ + for (i=0; i < comm_platforms.length; i++) { + if (InPlat == comm_platforms[i]) { + return files[i]; + } + } + return unix+"unknown-unknown-unknown.jar"; +} + +function mapDate(platform) { + if ((platform == "MacPPC") || (platform == "Mac68K")) { + return ""; + } else if ((platform == "Win32") || (platform == "Win16")) { + return "/oct_2a_404"; + } else if ((platform == "OS23.0") || (platform == "OS24.0")) { + return ""; + } + return "/current/signed"; +} +function mapBaseDir(platform) { + if ((platform == "MacPPC") || (platform == "Mac68K")) { + return "mac"; + } else if ((platform == "Win32") || (platform == "Win16")) { + return "windows" + } else if ((platform == "OS23.0") || (platform == "OS24.0")) { + return "os2"; + } + return "unix/Fortezza"; +} + +function pk_init_array() +{ + var numArgs = pk_init_array.arguments.length; + var a = new Array(numArgs); + + for (var i = 0; i < numArgs; i++) { + a[i] = pk_init_array.arguments[i]; + } + return a; +} + +function getPlatform() { + return navigator.platform; +} + +function getURLPath() { + var string = window.location.href; + end = string.lastIndexOf("/"); + if (end == -1) { + end = string.length-1; + } + return string.substring(0,end+1); +} + + + +plat=getPlatform(); +platDir = mapPlatform(plat); +platFile = mapFile(plat); +platBase = mapBaseDir(plat); +platDate = mapDate(plat); +if (pkcs11base == "") pkcs11base=getURLPath(); +pkcs11loc=pkcs11base+"/"+platBase+"/"+platDir + platDate + "/" + platFile; + + + +function DoInstall(url) { + window.location.href = url; +} + +function DoCancel() { + // set window.location.href to your home page if you wish + //alert('Cancel Installation?'); + history.back(); +} + +// ------ Change the following for your own Message -------- +document.write("<CENTER><H1>Netscape Fortezza PKCS #11 Module Installer</H1>"); +document.write("</CENTER>"); +document.write("<Table><TR><TD>"); +document.write("<DD><p><IMG SRC=litronic.gif WIDTH=110 Height=63 NAME=LITRONIC></TD>"); +document.write("<TD VAlign=Center><i> Netscape Fortezza PKCS #11 Modules require Litronic's MACI drivers to be installed on your platform."); +document.write(" If you haven't already installed theLitronic MACI drivers, please to do so now.</I>"); +document.write("</TD></TR></Table>"); +// ----- end of generic message section -------- +document.write("<p>Netscape has detected you are installing on <b>"+plat+"</b>.<br>"); +if (!isSupported(plat)) { + document.write("<b>This platform is currently not suppported for FORTEZZA</b><br>"); +} +document.write("Installing: <b>"+pkcs11loc+"</b><br>"); +document.write("<FORM>"); +document.write("<CENTER><Table><TR><TD><Input Type=Button name=install value='Install Now' onclick=DoInstall("+ "\"" +pkcs11loc+"\""+")>"); +document.write("</TD><TD><Input type=Button name=cancel value=Cancel Onclick=DoCancel()>"); +document.write("</TD></TR></Table></CENTER>"); +document.write("</FORM>"); +document.close(); +</SCRIPT> +</HTML> diff --git a/security/nss/lib/fortcrypt/inst.js b/security/nss/lib/fortcrypt/inst.js new file mode 100644 index 000000000..68c532578 --- /dev/null +++ b/security/nss/lib/fortcrypt/inst.js @@ -0,0 +1,272 @@ +/* ***** 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 ***** */ + +//////////////////////////////////////////////////////////////////////////////////////// +// Crypto Mechanism Flags +PKCS11_MECH_RSA_FLAG = 0x1<<0; +PKCS11_MECH_DSA_FLAG = 0x1<<1; +PKCS11_MECH_RC2_FLAG = 0x1<<2; +PKCS11_MECH_RC4_FLAG = 0x1<<3; +PKCS11_MECH_DES_FLAG = 0x1<<4; +PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman +PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards +PKCS11_MECH_RC5_FLAG = 0x1<<7; +PKCS11_MECH_SHA1_FLAG = 0x1<<8; +PKCS11_MECH_MD5_FLAG = 0x1<<9; +PKCS11_MECH_MD2_FLAG = 0x1<<10; +PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator +PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in +PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default + +// Important: +// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should always be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which mechanisms should be turned on by +var pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG; + +//////////////////////////////////////////////////////////////////////////////////////// +// Ciphers that support SSL or S/MIME +PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0; + +// Important: +// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should ALWAYS be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which SSL ciphers are supported +var pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG; + +//////////////////////////////////////////////////////////////////////////////////////// +// Return values of pkcs11.addmodule() & pkcs11.delmodule() +// success codes +JS_OK_ADD_MODULE = 3; // Successfully added a module +JS_OK_DEL_EXTERNAL_MODULE = 2; // Successfully deleted ext. module +JS_OK_DEL_INTERNAL_MODULE = 1; // Successfully deleted int. module + +// failure codes +JS_ERR_OTHER = -1; // Other errors than the followings +JS_ERR_USER_CANCEL_ACTION = -2; // User abort an action +JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3; // Calling a method w/ incorrect # of arguments +JS_ERR_DEL_MODULE = -4; // Error deleting a module +JS_ERR_ADD_MODULE = -5; // Error adding a module +JS_ERR_BAD_MODULE_NAME = -6; // The module name is invalid +JS_ERR_BAD_DLL_NAME = -7; // The DLL name is bad +JS_ERR_BAD_MECHANISM_FLAGS = -8; // The mechanism flags are invalid +JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9; // The SSL, S/MIME cipher flags are invalid +JS_ERR_ADD_MODULE_DULICATE =-10; // Module with the same name already installed + +//////////////////////////////////////////////////////////////////////////////////////// +// Find out which library is to be installed depending on the platform + +// pathname seperator is platform specific +var sep = "/"; +var vendor = "netscape"; +var moduleName = "not_supported"; +var plat = navigator.platform; + +var dir = "pkcs11/" + vendor + "/" + plat + "/"; +if (plat == "Win16") { + dir = "pkcs11/"; +} + +bAbort = false; +if (plat == "Win32") { + moduleName = "fort32.dll"; + sep = "\\"; +} else if (plat == "Win16") { + moduleName = "FORT16.DLL"; + sep = "\\"; +} else if (plat == "MacPPC") { + moduleName = "FortPK11Lib"; + sep = ":"; +} else if (plat == "AIX4.1") { + moduleName = "libfort_shr.a"; +} else if (plat == "SunOS4.1.3_U1") { + moduleName = "libfort.so.1.0"; +} else if ((plat == "SunOS5.4") || (plat == "SunOS5.5.1")){ + moduleName = "libfort.so"; +} else if ((plat == "HP-UXA.09") || (plat == "HP-UXB.10")){ + moduleName = "libfort.sl"; +} else if (plat == "IRIX6.2"){ + // The module only works on 6.3, but Communicator returns 6.2 even when + // running 6.3. So in order to prevent the user from thinking + // the module actually works on 6.2, we will force the name to + // say 6.3 instead of 6.2. In the even the user tries to install + // on 6.2, the user will see 6.3 instead. If they don't get it that + // it's not going to work at this point in time, then the entire install + // process wil just fail miserably, and that is OK. + plat = "IRIX6.3"; + moduleName = "libfort.so"; +} else { + window.alert("Sorry, platform "+plat+" is not supported."); + bAbort = true; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// Installation Begins... +if (!bAbort) { +if (confirm("This script will install a security module. \nIt may over-write older files having the same name. \nDo you want to continue?")) { + // Step 1. Create a version object and a software update object + vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0); + su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module"); + // "Fortezza ... Module" is the logical name of the bundle + + //////////////////////////////////////// + // Step 2. Start the install process + bAbort = false; + err = su.StartInstall("NSfortezza", // NSfortezza is the component folder (logical) + vi, + netscape.softupdate.SoftwareUpdate.FULL_INSTALL); + + bAbort = (err!=0); + + if (err == 0) { + //////////////////////////////////////// + // Step 3. Find out the physical location of the Program dir + Folder = su.GetFolder("Program"); + + //////////////////////////////////////// + // Step 4. Install the files. Unpack them and list where they go + + err = su.AddSubcomponent("FortezzaLibrary_"+plat, //component name (logical) + vi, // version info + moduleName, // source file in JAR (physical) + Folder, // target folder (physical) + dir + moduleName, // target path & filename (physical) + true); // forces update + if (err != 0) { + if (err == -200) { + errmsg = "Bad Package Name."; + } else if (err == -201) { + errmsg = "Unexpected error."; + } else if (err == -203) { + errmsg = "Installation script was signed by more than one certificate."; + } else if (err == -204) { + errmsg = "Installation script was not signed." + } else if (err == -205) { + errmsg = "The file to be installed is not signed." + } else if (err == -206) { + errmsg = "The file to be installed is not present, or it was signed with a different certificate than the one used to sign the install script."; + } else if (err == -207) { + errmsg = "JAR archive has not been opened." + } else if (err == -208) { + errmsg = "Bad arguments to AddSubcomponent( )." + } else if (err == -209) { + errmsg = "Illegal relative path( )." + } else if (err == -210) { + errmsg = "User cancelled installation." + } else if (err == -211) { + errmsg = "A problem occurred with the StartInstall( )." + } else { + errmsg = "Unknown error"; + } + window.alert("Error adding sub-component: "+"("+err+")"+errmsg); + //window.alert("Aborting, Folder="+Folder+" module="+dir+moduleName); + bAbort = true; + } + } + + //////////////////////////////////////// + // Step 5. Unless there was a problem, move files to final location + // and update the Client Version Registry + if (bAbort) { + su.AbortInstall(); + } else { + err = su.FinalizeInstall(); + + if (err != 0) { + + if (err == -900) { + errmsg = "Restart the computer, and install again."; + } else if (err == -201) { + errmsg = "Unexpected error."; + } else if (err == -202) { + errmsg = "Access denied. Make sure you have the permissions to write to the disk."; + } else if (err == -203) { + errmsg = "Installation script was signed by more than one certificate."; + } else if (err == -204) { + errmsg = "Installation script was not signed." + } else if (err == -205) { + errmsg = "The file to be installed is not signed." + } else if (err == -206) { + errmsg = "The file to be installed is not present, or it was signed with a different certificate than the one used to sign the install script." + } else if (err == -207) { + errmsg = "JAR archive has not been opened." + } else if (err == -208) { + errmsg = "Bad arguments to AddSubcomponent( )." + } else if (err == -209) { + errmsg = "Illegal relative path( )." + } else if (err == -210) { + errmsg = "User cancelled installation." + } else if (err == -211) { + errmsg = "A problem occurred with the StartInstall( )." + } else { + errmsg = "\nIf you have FORTEZZA module already installed, try deleting it first."; + } + window.alert("Error Finalizing Install: "+"("+err+")"+errmsg); + //window.alert("Aborting, Folder="+Folder+" module="+dir+moduleName); + + } else { + + // Platform specific full path + if (plat=="Win16") { + fullpath = Folder + "pkcs11" + sep + moduleName; + } else { + fullpath = Folder + "pkcs11" + sep + vendor + sep + plat + sep + moduleName; + } + + //////////////////////////////////////// + // Step 6: Call pkcs11.addmodule() to register the newly downloaded module + moduleCommonName = "Netscape FORTEZZA Module " + plat; + result = pkcs11.addmodule(moduleCommonName, + fullpath, + pkcs11MechanismFlags, + pkcs11CipherFlags); + if (result == -10) { + window.alert("New module was copied to destination, \nbut setup failed because a module " + +"with the same name has been installed. \nTry deleting the module " + + moduleCommonName +" first.") + } else if (result < 0) { + window.alert("New module was copied to destination, but setup failed. Error code: " + result); + } + } + } +} +} diff --git a/security/nss/lib/fortcrypt/inst_PPC.js b/security/nss/lib/fortcrypt/inst_PPC.js new file mode 100644 index 000000000..a98e176df --- /dev/null +++ b/security/nss/lib/fortcrypt/inst_PPC.js @@ -0,0 +1,138 @@ +/* ***** 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 ***** */ + +// Crypto Mechanism Flags +PKCS11_MECH_RSA_FLAG = 0x1<<0; +PKCS11_MECH_DSA_FLAG = 0x1<<1; +PKCS11_MECH_RC2_FLAG = 0x1<<2; +PKCS11_MECH_RC4_FLAG = 0x1<<3; +PKCS11_MECH_DES_FLAG = 0x1<<4; +PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman +PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards +PKCS11_MECH_RC5_FLAG = 0x1<<7; +PKCS11_MECH_SHA1_FLAG = 0x1<<8; +PKCS11_MECH_MD5_FLAG = 0x1<<9; +PKCS11_MECH_MD2_FLAG = 0x1<<10; +PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator +PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in +PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default + +// Important: +// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should always be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which mechanisms should be turned on by +pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG; + + +// Ciphers that support SSL or S/MIME +PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0; + +// Important: +// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should ALWAYS be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which SSL ciphers are supported +pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG; + + +// Return values of pkcs11.addmodule() & pkcs11.delmodule() +// success codes +JS_OK_ADD_MODULE = 3 // Successfully added a module +JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module +JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module + +// failure codes +JS_ERR_OTHER = -1 // Other errors than the followings +JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action +JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments +JS_ERR_DEL_MODULE = -4 // Error deleting a module +JS_ERR_ADD_MODULE = -5 // Error adding a module +JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid +JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad +JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid +JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid + + +if (confirm("This script will install and configure a security module, do you want to continue?")) { + // Step 1. Create a version object and a software update object + vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0); + su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module"); + // "Fortezza ... Module" is the logical name of the bundle + + // Step 2. Start the install process + bAbort = false; + err = su.StartInstall("NSfortezza", vi, netscape.softupdate.SoftwareUpdate.FULL_INSTALL); + // nsfortezza is the component folder (logical) + bAbort = bAbort || (err !=0); + + if (err == 0) { + + // Step 3. Find out the physical location of the Program dir + Folder = su.GetFolder("Program"); + + // Step 4. Install the files. Unpack them and list where they go + err = su.AddSubcomponent("FortezzaCardDLL", //component name (logical) + vi, // version info + "FortPK11Lib", // source file in JAR (physical) + Folder, // target folder (physical) + "FortPK11Lib", // target path & filename (physical) + this.force); // forces update + bAbort = bAbort || (err !=0); + } + + // Step 5. Unless there was a problem, move files to final location + // and update the Client Version Registry + if (bAbort) { + window.alert("Installation Aborted"); + su.AbortInstall(); + } else { + err = su.FinalizeInstall(); + window.alert("Files have been installed.\nContinue to setup the newly isntalled module..."); + // Add Module + compFolder = su.GetComponentFolder("NSfortezza/FortezzaCardDLL") + "/FortPK11Lib"; + result = pkcs11.addmodule("Netscape FORTEZZA Module", compFolder, pkcs11MechanismFlags, pkcs11CipherFlags); + if ( result < 0) { + window.alert("New module setup failed. Error code: " + result); + } else { + window.alert("New module setup completed."); + } + } +} diff --git a/security/nss/lib/fortcrypt/install.js b/security/nss/lib/fortcrypt/install.js new file mode 100644 index 000000000..d36e76b0f --- /dev/null +++ b/security/nss/lib/fortcrypt/install.js @@ -0,0 +1,138 @@ +/* ***** 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 ***** */ + +// Crypto Mechanism Flags +PKCS11_MECH_RSA_FLAG = 0x1<<0; +PKCS11_MECH_DSA_FLAG = 0x1<<1; +PKCS11_MECH_RC2_FLAG = 0x1<<2; +PKCS11_MECH_RC4_FLAG = 0x1<<3; +PKCS11_MECH_DES_FLAG = 0x1<<4; +PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman +PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards +PKCS11_MECH_RC5_FLAG = 0x1<<7; +PKCS11_MECH_SHA1_FLAG = 0x1<<8; +PKCS11_MECH_MD5_FLAG = 0x1<<9; +PKCS11_MECH_MD2_FLAG = 0x1<<10; +PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator +PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in +PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default + +// Important: +// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should always be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which mechanisms should be turned on by +pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG; + + +// Ciphers that support SSL or S/MIME +PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0; + +// Important: +// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should ALWAYS be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which SSL ciphers are supported +pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG; + + +// Return values of pkcs11.addmodule() & pkcs11.delmodule() +// success codes +JS_OK_ADD_MODULE = 3 // Successfully added a module +JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module +JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module + +// failure codes +JS_ERR_OTHER = -1 // Other errors than the followings +JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action +JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments +JS_ERR_DEL_MODULE = -4 // Error deleting a module +JS_ERR_ADD_MODULE = -5 // Error adding a module +JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid +JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad +JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid +JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid + + +if (confirm("This script will install and configure a security module, do you want to continue?")) { + // Step 1. Create a version object and a software update object + vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0); + su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module"); + // "Fortezza ... Module" is the logical name of the bundle + + // Step 2. Start the install process + bAbort = false; + err = su.StartInstall("NSfortezza", vi, netscape.softupdate.SoftwareUpdate.FULL_INSTALL); + // nsfortezza is the component folder (logical) + bAbort = bAbort || (err !=0); + + if (err == 0) { + + // Step 3. Find out the physical location of the Program dir + Folder = su.GetFolder("Program"); + + // Step 4. Install the files. Unpack them and list where they go + err = su.AddSubcomponent("FortezzaCardDLL", //component name (logical) + vi, // version info + "DUMMY_DLL", // source file in JAR (physical) + Folder, // target folder (physical) + "DUMMY_DLL", // target path & filename (physical) + this.force); // forces update + bAbort = bAbort || (err !=0); + } + + // Step 5. Unless there was a problem, move files to final location + // and update the Client Version Registry + if (bAbort) { + window.alert("Installation Aborted"); + su.AbortInstall(); + } else { + err = su.FinalizeInstall(); + window.alert("Files have been installed.\nContinue to setup the newly isntalled module..."); + // Add Module + compFolder = su.GetComponentFolder("NSfortezza/FortezzaCardDLL") + "/DUMMY_DLL"; + result = pkcs11.addmodule("Netscape FORTEZZA Module", compFolder, pkcs11MechanismFlags, pkcs11CipherFlags); + if ( result < 0) { + window.alert("New module setup failed. Error code: " + result); + } else { + window.alert("New module setup completed."); + } + } +} diff --git a/security/nss/lib/fortcrypt/maci.c b/security/nss/lib/fortcrypt/maci.c new file mode 100644 index 000000000..5135f08bf --- /dev/null +++ b/security/nss/lib/fortcrypt/maci.c @@ -0,0 +1,904 @@ +/* ***** 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 "seccomon.h" + +#if defined( _WIN32 ) || defined( __WIN32__ ) +#define RETURN_TYPE extern __declspec( dllexport ) int _cdecl +#endif /* Windows */ +#include "maci.h" + + +RETURN_TYPE +MACI_ChangePIN PROTO_LIST( ( + HSESSION hSession, + int PINType, + CI_PIN CI_FAR pOldPIN, + CI_PIN CI_FAR pNewPIN ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_CheckPIN PROTO_LIST( ( + HSESSION hSession, + int PINType, + CI_PIN CI_FAR pPIN ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Close PROTO_LIST( ( + HSESSION hSession, + unsigned int Flags, + int SocketIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Decrypt PROTO_LIST( ( + HSESSION hSession, + unsigned int CipherSize, + CI_DATA pCipher, + CI_DATA pPlain ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_DeleteCertificate PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_DeleteKey PROTO_LIST( ( + HSESSION hSession, + int RegisterIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Encrypt PROTO_LIST( ( + HSESSION hSession, + unsigned int PlainSize, + CI_DATA pPlain, + CI_DATA pCipher ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_ExtractX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_FirmwareUpdate PROTO_LIST( ( + HSESSION hSession, + unsigned long Flags, + long Cksum, + unsigned int CksumLength, + unsigned int DataSize, + CI_DATA pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GenerateIV PROTO_LIST( ( + HSESSION hSession, + CI_IV CI_FAR pIV ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GenerateMEK PROTO_LIST( ( + HSESSION hSession, + int RegisterIndex, + int Reserved ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GenerateRa PROTO_LIST( ( + HSESSION hSession, + CI_RA CI_FAR pRa ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GenerateRandom PROTO_LIST( ( + HSESSION hSession, + CI_RANDOM CI_FAR pRandom ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GenerateTEK PROTO_LIST( ( + HSESSION hSession, + int Flags, + int RegisterIndex, + CI_RA CI_FAR pRa, + CI_RB CI_FAR pRb, + unsigned int YSize, + CI_Y CI_FAR pY ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GenerateX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + unsigned int YSize, + CI_Y CI_FAR pY ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetCertificate PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + CI_CERTIFICATE CI_FAR pCertificate ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetConfiguration PROTO_LIST( ( + HSESSION hSession, + CI_CONFIG_PTR pConfiguration ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetHash PROTO_LIST( ( + HSESSION hSession, + unsigned int DataSize, + CI_DATA pData, + CI_HASHVALUE CI_FAR pHashValue ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetPersonalityList PROTO_LIST( ( + HSESSION hSession, + int EntryCount, + CI_PERSON CI_FAR pPersonalityList[] ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetSessionID PROTO_LIST( ( + HSESSION *hSession ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetState PROTO_LIST( ( + HSESSION hSession, + CI_STATE_PTR pState ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetStatus PROTO_LIST( ( + HSESSION hSession, + CI_STATUS_PTR pStatus ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_GetTime PROTO_LIST( ( + HSESSION hSession, + CI_TIME CI_FAR pTime ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Hash PROTO_LIST( ( + HSESSION hSession, + unsigned int DataSize, + CI_DATA pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Initialize PROTO_LIST( ( + int CI_FAR *SocketCount ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_InitializeHash PROTO_LIST( ( + HSESSION hSession ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_InstallX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pWrappedX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_LoadCertificate PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + CI_CERT_STR CI_FAR pCertLabel, + CI_CERTIFICATE CI_FAR pCertificate, + long Reserved ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_LoadDSAParameters PROTO_LIST( ( + HSESSION hSession, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_LoadInitValues PROTO_LIST( ( + HSESSION hSession, + CI_RANDSEED CI_FAR pRandSeed, + CI_KS CI_FAR pKs ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_LoadIV PROTO_LIST( ( + HSESSION hSession, + CI_IV CI_FAR pIV ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_LoadX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + CI_X CI_FAR pX, + unsigned int YSize, + CI_Y CI_FAR pY ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Lock PROTO_LIST( ( + HSESSION hSession, + int Flags ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Open PROTO_LIST( ( + HSESSION hSession, + unsigned int Flags, + int SocketIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_RelayX PROTO_LIST( ( + HSESSION hSession, + CI_PASSWORD CI_FAR pOldPassword, + unsigned int OldYSize, + CI_Y CI_FAR pOldY, + CI_RA CI_FAR pOldRa, + CI_WRAPPED_X CI_FAR pOldWrappedX, + CI_PASSWORD CI_FAR pNewPassword, + unsigned int NewYSize, + CI_Y CI_FAR pNewY, + CI_RA CI_FAR pNewRa, + CI_WRAPPED_X CI_FAR pNewWrappedX ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Reset PROTO_LIST( ( + HSESSION hSession ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Restore PROTO_LIST( ( + HSESSION hSession, + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Save PROTO_LIST( ( + HSESSION hSession, + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Select PROTO_LIST( ( + HSESSION hSession, + int SocketIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_SetConfiguration PROTO_LIST( ( + HSESSION hSession, + int Type, + unsigned int DataSize, + CI_DATA pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_SetKey PROTO_LIST( ( + HSESSION hSession, + int RegisterIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_SetMode PROTO_LIST( ( + HSESSION hSession, + int CryptoType, + int CryptoMode ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_SetPersonality PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_SetTime PROTO_LIST( ( + HSESSION hSession, + CI_TIME CI_FAR pTime ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Sign PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Terminate PROTO_LIST( ( + HSESSION hSession ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_TimeStamp PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Unlock PROTO_LIST( ( + HSESSION hSession) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_UnwrapKey PROTO_LIST( ( + HSESSION hSession, + int UnwrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_VerifySignature PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_SIGNATURE CI_FAR pSignature ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_VerifyTimeStamp PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_WrapKey PROTO_LIST( ( + HSESSION hSession, + int WrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ) { + return CI_ERROR; +} + +RETURN_TYPE +MACI_Zeroize PROTO_LIST( ( + HSESSION hSession ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_ChangePIN PROTO_LIST( ( + int PINType, + CI_PIN CI_FAR pOldPIN, + CI_PIN CI_FAR pNewPIN ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_CheckPIN PROTO_LIST( ( + int PINType, + CI_PIN CI_FAR pPIN ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Close PROTO_LIST( ( + unsigned int Flags, + int SocketIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Decrypt PROTO_LIST( ( + unsigned int CipherSize, + CI_DATA pCipher, + CI_DATA pPlain ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_DeleteCertificate PROTO_LIST( ( + int CertificateIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_DeleteKey PROTO_LIST( ( + int RegisterIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Encrypt PROTO_LIST( ( + unsigned int PlainSize, + CI_DATA pPlain, + CI_DATA pCipher ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_ExtractX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_FirmwareUpdate PROTO_LIST( ( + unsigned long Flags, + long Cksum, + unsigned int CksumLength, + unsigned int DataSize, + CI_DATA pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GenerateIV PROTO_LIST( ( + CI_IV CI_FAR pIV ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GenerateMEK PROTO_LIST( ( + int RegisterIndex, + int Reserved ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GenerateRa PROTO_LIST( ( + CI_RA CI_FAR pRa ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GenerateRandom PROTO_LIST( ( + CI_RANDOM CI_FAR pRandom ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GenerateTEK PROTO_LIST( ( + int Flags, + int RegisterIndex, + CI_RA CI_FAR pRa, + CI_RB CI_FAR pRb, + unsigned int YSize, + CI_Y CI_FAR pY ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GenerateX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + unsigned int YSize, + CI_Y CI_FAR pY ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GetCertificate PROTO_LIST( ( + int CertificateIndex, + CI_CERTIFICATE CI_FAR pCertificate ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GetConfiguration PROTO_LIST( ( + CI_CONFIG_PTR pConfiguration ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GetHash PROTO_LIST( ( + unsigned int DataSize, + CI_DATA pData, + CI_HASHVALUE CI_FAR pHashValue ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GetPersonalityList PROTO_LIST( ( + int EntryCount, + CI_PERSON CI_FAR pPersonalityList[] ) ) { + return CI_ERROR; +} + + +RETURN_TYPE +CI_GetState PROTO_LIST( ( + CI_STATE_PTR pState ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GetStatus PROTO_LIST( ( + CI_STATUS_PTR pStatus ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_GetTime PROTO_LIST( ( + CI_TIME CI_FAR pTime ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Hash PROTO_LIST( ( + unsigned int DataSize, + CI_DATA pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Initialize PROTO_LIST( ( + int CI_FAR *SocketCount ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_InitializeHash PROTO_LIST( () ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_InstallX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pWrappedX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_LoadCertificate PROTO_LIST( ( + int CertificateIndex, + CI_CERT_STR CI_FAR pCertLabel, + CI_CERTIFICATE CI_FAR pCertificate, + long Reserved ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_LoadDSAParameters PROTO_LIST( ( + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_LoadInitValues PROTO_LIST( ( + CI_RANDSEED CI_FAR pRandSeed, + CI_KS CI_FAR pKs ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_LoadIV PROTO_LIST( ( + CI_IV CI_FAR pIV ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_LoadX PROTO_LIST( ( + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + CI_X CI_FAR pX, + unsigned int YSize, + CI_Y CI_FAR pY ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Lock PROTO_LIST( ( + int Flags ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Open PROTO_LIST( ( + unsigned int Flags, + int SocketIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_RelayX PROTO_LIST( ( + CI_PASSWORD CI_FAR pOldPassword, + unsigned int OldYSize, + CI_Y CI_FAR pOldY, + CI_RA CI_FAR pOldRa, + CI_WRAPPED_X CI_FAR pOldWrappedX, + CI_PASSWORD CI_FAR pNewPassword, + unsigned int NewYSize, + CI_Y CI_FAR pNewY, + CI_RA CI_FAR pNewRa, + CI_WRAPPED_X CI_FAR pNewWrappedX ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Reset PROTO_LIST( ( ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Restore PROTO_LIST( ( + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Save PROTO_LIST( ( + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Select PROTO_LIST( ( + int SocketIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_SetConfiguration PROTO_LIST( ( + int Type, + unsigned int DataSize, + CI_DATA pData ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_SetKey PROTO_LIST( ( + int RegisterIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_SetMode PROTO_LIST( ( + int CryptoType, + int CryptoMode ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_SetPersonality PROTO_LIST( ( + int CertificateIndex ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_SetTime PROTO_LIST( ( + CI_TIME CI_FAR pTime ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Sign PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Terminate PROTO_LIST( ( ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_TimeStamp PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_Unlock PROTO_LIST( () ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_UnwrapKey PROTO_LIST( ( + int UnwrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_VerifySignature PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_SIGNATURE CI_FAR pSignature ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_VerifyTimeStamp PROTO_LIST( ( + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ) { + return CI_ERROR; +} + +RETURN_TYPE +CI_WrapKey PROTO_LIST( ( + int WrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ) { + return CI_ERROR; +} + diff --git a/security/nss/lib/fortcrypt/maci.h b/security/nss/lib/fortcrypt/maci.h new file mode 100644 index 000000000..f4a6fa260 --- /dev/null +++ b/security/nss/lib/fortcrypt/maci.h @@ -0,0 +1,779 @@ +/* ***** 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 ***** */ +/* @(#)maci.h 1.27\t05 Jan 1996 */ +/***************************************************************************** + Definitive Fortezza header file. + Application Level Interface to Fortezza MACI Library. + + Version for CI Library 1.52 + January 5, 1996 + + + NOTICE: Fortezza Export Policy + + The Fortezza Cryptologic Interface (CI) Library (both source and + object) and Fortezza CI Library based applications are defense + articles, as defined in the International Traffic In Arms + Regulations (ITAR), and are subject to export controls under the + ITAR and the Arms Export Control Act. Any export to any country + of (a) the Fortezza CI Library, related documentation, and + technical data, or (b) your cryptographic application, process, + or service that is the direct product of, or contains the + Fortezza CI Library must comply with the requirements of the ITAR. + If you or your customer intends to engage in such export, contact + the United States Department of State, Office of Defense Trade + Controls for specific guidance. + + + ****************************************************************************/ +#ifndef __MACI_H +#define __MACI_H + +#if __cplusplus__ || __cplusplus +extern "C" +{ +#endif /* C++ */ + + +#ifndef __CRYPTINT_H + +#ifndef PROTO_LIST +#ifdef _K_AND_R_ +#define PROTO_LIST(list) () +#else +#define PROTO_LIST(list) list +#endif /*_K_AND_R_ */ +#endif /* PROTO_LIST */ + + +#ifndef RETURN_TYPE +#if defined( _WIN32 ) || defined( __WIN32__ ) +#define RETURN_TYPE extern __declspec( dllimport ) int _cdecl +#elif defined( _WINDOWS ) || defined( _Windows ) +#define RETURN_TYPE extern int _far _pascal +#else +#define RETURN_TYPE extern int +#endif /* Windows */ +#endif /* RETURN_TYPE */ + +/* MS Visual C++ defines _MSDOS and _WINDOWS */ +/* Borland C/C++ defines __MSDOS__ and _Windows */ +#if (defined( _WINDOWS ) || defined( _Windows )) && \ + !(defined( _WIN32 ) || defined( __WIN32__ )) +#define CI_FAR _far +#else +#define CI_FAR +#endif /* MS DOS or Windows */ + + +/***************************************************************************** + Constants + ****************************************************************************/ +#define CI_LIB_VERSION_VAL 0x0152 /* Version 1.52 */ + +#define CI_CERT_SIZE 2048 +#define CI_CERT_FLAGS_SIZE 16 +#define CI_CERT_NAME_SIZE 32 +#define CI_CHALLENGE_SIZE 20 + +#define CI_G_SIZE 128 + +#define CI_HASHVALUE_SIZE 20 + +#define CI_IV_SIZE 24 + +#define CI_KEY_SIZE 12 +#define CI_KS_SIZE 10 + +#define CI_NAME_SIZE 32 + +#define CI_PASSWORD_SIZE 24 +#define CI_PIN_SIZE 12 +#define CI_P_SIZE 128 + +#define CI_Q_SIZE 20 + +#define CI_R_SIZE 40 +#define CI_RANDOM_NO_SIZE 20 +#define CI_RANDOM_SEED_SIZE 8 +#define CI_RA_SIZE 128 +#define CI_RB_SIZE 128 +#define CI_REG_FLAGS_SIZE 4 + +#define CI_S_SIZE 40 +#define CI_SAVE_DATA_SIZE 28 +#define CI_SERIAL_NUMBER_SIZE 8 +#define CI_SIGNATURE_SIZE 40 +#define CI_STATUS_FLAGS_SIZE 4 + +#define CI_TIME_SIZE 16 +#define CI_TIMESTAMP_SIZE 16 + +#define CI_WRAPPED_X_SIZE 24 + +#define CI_Y_SIZE 128 + +#define CI_X_SIZE 20 + + +/* Miscellaneous */ +#define CI_NULL_FLAG 0 +#define CI_POWER_DOWN_FLAG 2 +#define CI_NO_LOG_OFF_FLAG 4 +#define CI_INITIATOR_FLAG 0 +#define CI_RECIPIENT_FLAG 1 + +#define CI_BLOCK_LOCK_FLAG 1 +#define CI_SSO_LOGGED_ON 0x40 +#define CI_USER_LOGGED_ON 0x00 +#define CI_FAST_MODE 0x10 +#define CI_SLOW_MODE 0x00 +#define CI_WORST_CASE_MODE 0x40 +#define CI_TYPICAL_CASE_MODE 0x00 + +/* Card Public Key Algorithms Types */ +#define CI_DSA_TYPE 0xA +#define CI_KEA_TYPE 0x5 +#define CI_DSA_KEA_TYPE 0xF + +/* Fortezza Pin Types */ +#define CI_SSO_PIN 0x25 +#define CI_USER_PIN 0x2A + +/* Crypto Types */ +#define CI_ENCRYPT_TYPE 0 +#define CI_DECRYPT_TYPE 1 +#define CI_HASH_TYPE 2 + +/* Save and Restore Types */ +#define CI_ENCRYPT_INT_TYPE 0x00 /* Internal Encryption */ +#define CI_ENCRYPT_EXT_TYPE 0x10 /* External Encryption */ +#define CI_DECRYPT_INT_TYPE 0x01 /* Internal Decryption */ +#define CI_DECRYPT_EXT_TYPE 0x11 /* External Decryption */ +#define CI_HASH_INT_TYPE 0x02 /* Internal Hash */ +#define CI_HASH_EXT_TYPE 0x12 /* External Hash */ +#define CI_TYPE_EXT_FLAG 0x10 /* Used to differentiate */ + +/* Configuration types */ +#define CI_SET_SPEED_TYPE 1 +#define CI_SET_TIMING_TYPE 2 + +/* Lock States */ +#define CI_SOCKET_UNLOCKED 0 +#define CI_HOLD_LOCK 1 +#define CI_SOCKET_LOCKED 2 + +/* Fortezza Crypto Types Modes */ +#define CI_ECB64_MODE 0 +#define CI_CBC64_MODE 1 +#define CI_OFB64_MODE 2 +#define CI_CFB64_MODE 3 +#define CI_CFB32_MODE 4 +#define CI_CFB16_MODE 5 +#define CI_CFB8_MODE 6 + +/* Card States */ +#define CI_POWER_UP 0 +#define CI_UNINITIALIZED 1 +#define CI_INITIALIZED 2 +#define CI_SSO_INITIALIZED 3 +#define CI_LAW_INITIALIZED 4 +#define CI_USER_INITIALIZED 5 +#define CI_STANDBY 6 +#define CI_READY 7 +#define CI_ZEROIZE 8 +#define CI_INTERNAL_FAILURE (-1) + +/* Flags for Firmware Update. */ +#if !defined( _K_AND_R_ ) + +#define CI_NOT_LAST_BLOCK_FLAG 0x00000000UL +#define CI_LAST_BLOCK_FLAG 0x80000000UL +#define CI_DESTRUCTIVE_FLAG 0x000000FFUL +#define CI_NONDESTRUCTIVE_FLAG 0x0000FF00UL + +#else + +#define CI_NOT_LAST_BLOCK_FLAG 0x00000000L +#define CI_LAST_BLOCK_FLAG 0x80000000L +#define CI_DESTRUCTIVE_FLAG 0x000000FFL +#define CI_NONDESTRUCTIVE_FLAG 0x0000FF00L + +#endif /* _K_AND_R_ */ + +/**************************************************************************** + Fortezza Library Return Codes + ***************************************************************************/ + +/* Card Responses */ +#define CI_OK 0 +#define CI_FAIL 1 +#define CI_CHECKWORD_FAIL 2 +#define CI_INV_TYPE 3 +#define CI_INV_MODE 4 +#define CI_INV_KEY_INDEX 5 +#define CI_INV_CERT_INDEX 6 +#define CI_INV_SIZE 7 +#define CI_INV_HEADER 8 +#define CI_INV_STATE 9 +#define CI_EXEC_FAIL 10 +#define CI_NO_KEY 11 +#define CI_NO_IV 12 +#define CI_NO_X 13 + +#define CI_NO_SAVE 15 +#define CI_REG_IN_USE 16 +#define CI_INV_COMMAND 17 +#define CI_INV_POINTER 18 +#define CI_BAD_CLOCK 19 +#define CI_NO_DSA_PARMS 20 + +/* Library Errors */ +#define CI_ERROR (-1) +#define CI_LIB_NOT_INIT (-2) +#define CI_CARD_NOT_READY (-3) +#define CI_CARD_IN_USE (-4) +#define CI_TIME_OUT (-5) +#define CI_OUT_OF_MEMORY (-6) +#define CI_NULL_PTR (-7) +#define CI_BAD_SIZE (-8) +#define CI_NO_DECRYPT (-9) +#define CI_NO_ENCRYPT (-10) +#define CI_NO_EXECUTE (-11) +#define CI_BAD_PARAMETER (-12) +#define CI_OUT_OF_RESOURCES (-13) + +#define CI_NO_CARD (-20) +#define CI_NO_DRIVER (-21) +#define CI_NO_CRDSRV (-22) +#define CI_NO_SCTSRV (-23) + +#define CI_BAD_CARD (-30) +#define CI_BAD_IOCTL (-31) +#define CI_BAD_READ (-32) +#define CI_BAD_SEEK (-33) +#define CI_BAD_WRITE (-34) +#define CI_BAD_FLUSH (-35) +#define CI_BAD_IOSEEK (-36) +#define CI_BAD_ADDR (-37) + +#define CI_INV_SOCKET_INDEX (-40) +#define CI_SOCKET_IN_USE (-41) +#define CI_NO_SOCKET (-42) +#define CI_SOCKET_NOT_OPENED (-43) +#define CI_BAD_TUPLES (-44) +#define CI_NOT_A_CRYPTO_CARD (-45) + +#define CI_INVALID_FUNCTION (-50) +#define CI_LIB_ALRDY_INIT (-51) +#define CI_SRVR_ERROR (-52) +#define MACI_SESSION_EXCEEDED (-53) + + +/***************************************************************************** + Data Structures + ****************************************************************************/ + + +typedef unsigned char CI_CERTIFICATE[CI_CERT_SIZE]; + +typedef unsigned char CI_CERT_FLAGS[CI_CERT_FLAGS_SIZE]; + +typedef unsigned char CI_CERT_STR[CI_CERT_NAME_SIZE+4]; + +typedef unsigned char CI_FAR *CI_DATA; + +typedef unsigned char CI_G[CI_G_SIZE]; + +typedef unsigned char CI_HASHVALUE[CI_HASHVALUE_SIZE]; + +typedef unsigned char CI_IV[CI_IV_SIZE]; + +typedef unsigned char CI_KEY[CI_KEY_SIZE]; + +typedef unsigned char CI_KS[CI_KS_SIZE]; + +typedef unsigned char CI_P[CI_P_SIZE]; + +typedef unsigned char CI_PASSWORD[CI_PASSWORD_SIZE + 4]; + +typedef unsigned char CI_PIN[CI_PIN_SIZE + 4]; + +typedef unsigned char CI_Q[CI_Q_SIZE]; + +typedef unsigned char CI_RA[CI_RA_SIZE]; + +typedef unsigned char CI_RB[CI_RB_SIZE]; + +typedef unsigned char CI_RANDOM[CI_RANDOM_NO_SIZE]; + +typedef unsigned char CI_RANDSEED[CI_RANDOM_SEED_SIZE]; + +typedef unsigned char CI_REG_FLAGS[CI_REG_FLAGS_SIZE]; + +typedef unsigned char CI_SIGNATURE[CI_SIGNATURE_SIZE]; + +typedef unsigned char CI_SAVE_DATA[CI_SAVE_DATA_SIZE]; + +typedef unsigned char CI_SERIAL_NUMBER[CI_SERIAL_NUMBER_SIZE]; + +typedef unsigned int CI_STATE, CI_FAR *CI_STATE_PTR; + +typedef unsigned char CI_TIME[CI_TIME_SIZE]; + +typedef unsigned char CI_TIMESTAMP[CI_TIMESTAMP_SIZE]; + +typedef unsigned char CI_WRAPPED_X[CI_WRAPPED_X_SIZE]; + +typedef unsigned char CI_Y[CI_Y_SIZE]; + +typedef unsigned char CI_X[CI_X_SIZE]; + +typedef struct { + int LibraryVersion; /* CI Library version */ + int ManufacturerVersion; /* Card's hardware version */ + char ManufacturerName[CI_NAME_SIZE+4]; /* Card manufacturer's name*/ + char ProductName[CI_NAME_SIZE+4]; /* Card's product name */ + char ProcessorType[CI_NAME_SIZE+4]; /* Card's processor type */ + unsigned long UserRAMSize; /* Amount of User RAM in bytes */ + unsigned long LargestBlockSize; /* Largest block of data to pass in */ + int KeyRegisterCount; /* Number of key registers */ + int CertificateCount; /* Maximum number of personalities (# certs-1) */ + int CryptoCardFlag; /* A flag that if non-zero indicates that there is + a Crypto-Card in the socket. If this value is + zero then there is NOT a Crypto-Card in the + sockets. */ + int ICDVersion; /* The ICD compliance level */ + int ManufacturerSWVer; /* The Manufacturer's Software Version */ + int DriverVersion; /* Driver Version */ +} CI_CONFIG, CI_FAR *CI_CONFIG_PTR; + +typedef struct { + int CertificateIndex; /* Index from 1 to CertificateCount */ + CI_CERT_STR CertLabel; /* The certificate label */ +} CI_PERSON, CI_FAR *CI_PERSON_PTR; + +typedef struct { + int CurrentSocket; /* The currently selected socket */ + int LockState; /* Lock status of the current socket */ + CI_SERIAL_NUMBER SerialNumber; /* Serial number of the Crypto Engine chip */ + CI_STATE CurrentState; /* State of The Card */ + int DecryptionMode; /* Decryption mode of The Card */ + int EncryptionMode; /* Encryption mode of The Card */ + int CurrentPersonality; /* Index of the current personality */ + int KeyRegisterCount; /* No. of Key Register on The Card */ + CI_REG_FLAGS KeyRegisterFlags; /* Bit Masks indicating Key Register use */ + int CertificateCount; /* No. of Certificates on The Card */ + CI_CERT_FLAGS CertificateFlags; /* Bit Mask indicating certificate use */ + unsigned char Flags[CI_STATUS_FLAGS_SIZE]; + /* Flag[0] : bit 6 for Condition mode */ + /* bit 4 for Clock mode */ +} CI_STATUS, CI_FAR *CI_STATUS_PTR; + +#endif + +/* Session constants */ +#ifndef HSESSION_DEFINE +typedef unsigned int HSESSION; +#define HSESSION_DEFINE +#endif +#define MAXSESSION 100 + +/***************************************************************************** + Function Call Prototypes + ****************************************************************************/ + +RETURN_TYPE +MACI_ChangePIN PROTO_LIST( ( + HSESSION hSession, + int PINType, + CI_PIN CI_FAR pOldPIN, + CI_PIN CI_FAR pNewPIN ) ); + +RETURN_TYPE +MACI_CheckPIN PROTO_LIST( ( + HSESSION hSession, + int PINType, + CI_PIN CI_FAR pPIN ) ); + +RETURN_TYPE +MACI_Close PROTO_LIST( ( + HSESSION hSession, + unsigned int Flags, + int SocketIndex ) ); + +RETURN_TYPE +MACI_Decrypt PROTO_LIST( ( + HSESSION hSession, + unsigned int CipherSize, + CI_DATA pCipher, + CI_DATA pPlain ) ); + +RETURN_TYPE +MACI_DeleteCertificate PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex ) ); + +RETURN_TYPE +MACI_DeleteKey PROTO_LIST( ( + HSESSION hSession, + int RegisterIndex ) ); + +RETURN_TYPE +MACI_Encrypt PROTO_LIST( ( + HSESSION hSession, + unsigned int PlainSize, + CI_DATA pPlain, + CI_DATA pCipher ) ); + +RETURN_TYPE +MACI_ExtractX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ); + +RETURN_TYPE +MACI_FirmwareUpdate PROTO_LIST( ( + HSESSION hSession, + unsigned long Flags, + long Cksum, + unsigned int CksumLength, + unsigned int DataSize, + CI_DATA pData ) ); + +RETURN_TYPE +MACI_GenerateIV PROTO_LIST( ( + HSESSION hSession, + CI_IV CI_FAR pIV ) ); + +RETURN_TYPE +MACI_GenerateMEK PROTO_LIST( ( + HSESSION hSession, + int RegisterIndex, + int Reserved ) ); + +RETURN_TYPE +MACI_GenerateRa PROTO_LIST( ( + HSESSION hSession, + CI_RA CI_FAR pRa ) ); + +RETURN_TYPE +MACI_GenerateRandom PROTO_LIST( ( + HSESSION hSession, + CI_RANDOM CI_FAR pRandom ) ); + +RETURN_TYPE +MACI_GenerateTEK PROTO_LIST( ( + HSESSION hSession, + int Flags, + int RegisterIndex, + CI_RA CI_FAR pRa, + CI_RB CI_FAR pRb, + unsigned int YSize, + CI_Y CI_FAR pY ) ); + +RETURN_TYPE +MACI_GenerateX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + unsigned int YSize, + CI_Y CI_FAR pY ) ); + +RETURN_TYPE +MACI_GetCertificate PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + CI_CERTIFICATE CI_FAR pCertificate ) ); + +RETURN_TYPE +MACI_GetConfiguration PROTO_LIST( ( + HSESSION hSession, + CI_CONFIG_PTR pConfiguration ) ); + +RETURN_TYPE +MACI_GetHash PROTO_LIST( ( + HSESSION hSession, + unsigned int DataSize, + CI_DATA pData, + CI_HASHVALUE CI_FAR pHashValue ) ); + +RETURN_TYPE +MACI_GetPersonalityList PROTO_LIST( ( + HSESSION hSession, + int EntryCount, + CI_PERSON CI_FAR pPersonalityList[] ) ); + +RETURN_TYPE +MACI_GetSessionID PROTO_LIST( ( + HSESSION *hSession ) ); + +RETURN_TYPE +MACI_GetState PROTO_LIST( ( + HSESSION hSession, + CI_STATE_PTR pState ) ); + +RETURN_TYPE +MACI_GetStatus PROTO_LIST( ( + HSESSION hSession, + CI_STATUS_PTR pStatus ) ); + +RETURN_TYPE +MACI_GetTime PROTO_LIST( ( + HSESSION hSession, + CI_TIME CI_FAR pTime ) ); + +RETURN_TYPE +MACI_Hash PROTO_LIST( ( + HSESSION hSession, + unsigned int DataSize, + CI_DATA pData ) ); + +RETURN_TYPE +MACI_Initialize PROTO_LIST( ( + int CI_FAR *SocketCount ) ); + +RETURN_TYPE +MACI_InitializeHash PROTO_LIST( ( + HSESSION hSession ) ); + +RETURN_TYPE +MACI_InstallX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + CI_PASSWORD CI_FAR pPassword, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_WRAPPED_X CI_FAR pWrappedX, + CI_RA CI_FAR pRa, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ); + +RETURN_TYPE +MACI_LoadCertificate PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + CI_CERT_STR CI_FAR pCertLabel, + CI_CERTIFICATE CI_FAR pCertificate, + long Reserved ) ); + +RETURN_TYPE +MACI_LoadDSAParameters PROTO_LIST( ( + HSESSION hSession, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG ) ); + +RETURN_TYPE +MACI_LoadInitValues PROTO_LIST( ( + HSESSION hSession, + CI_RANDSEED CI_FAR pRandSeed, + CI_KS CI_FAR pKs ) ); + +RETURN_TYPE +MACI_LoadIV PROTO_LIST( ( + HSESSION hSession, + CI_IV CI_FAR pIV ) ); + +RETURN_TYPE +MACI_LoadX PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex, + int AlgorithmType, + unsigned int PandGSize, + unsigned int QSize, + CI_P CI_FAR pP, + CI_Q CI_FAR pQ, + CI_G CI_FAR pG, + CI_X CI_FAR pX, + unsigned int YSize, + CI_Y CI_FAR pY ) ); + +RETURN_TYPE +MACI_Lock PROTO_LIST( ( + HSESSION hSession, + int Flags ) ); + +RETURN_TYPE +MACI_Open PROTO_LIST( ( + HSESSION hSession, + unsigned int Flags, + int SocketIndex ) ); + +RETURN_TYPE +MACI_RelayX PROTO_LIST( ( + HSESSION hSession, + CI_PASSWORD CI_FAR pOldPassword, + unsigned int OldYSize, + CI_Y CI_FAR pOldY, + CI_RA CI_FAR pOldRa, + CI_WRAPPED_X CI_FAR pOldWrappedX, + CI_PASSWORD CI_FAR pNewPassword, + unsigned int NewYSize, + CI_Y CI_FAR pNewY, + CI_RA CI_FAR pNewRa, + CI_WRAPPED_X CI_FAR pNewWrappedX ) ); + +RETURN_TYPE +MACI_Reset PROTO_LIST( ( + HSESSION hSession ) ); + +RETURN_TYPE +MACI_Restore PROTO_LIST( ( + HSESSION hSession, + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ); + +RETURN_TYPE +MACI_Save PROTO_LIST( ( + HSESSION hSession, + int CryptoType, + CI_SAVE_DATA CI_FAR pData ) ); + +RETURN_TYPE +MACI_Select PROTO_LIST( ( + HSESSION hSession, + int SocketIndex ) ); + +RETURN_TYPE +MACI_SetConfiguration PROTO_LIST( ( + HSESSION hSession, + int Type, + unsigned int DataSize, + CI_DATA pData ) ); + +RETURN_TYPE +MACI_SetKey PROTO_LIST( ( + HSESSION hSession, + int RegisterIndex ) ); + +RETURN_TYPE +MACI_SetMode PROTO_LIST( ( + HSESSION hSession, + int CryptoType, + int CryptoMode ) ); + +RETURN_TYPE +MACI_SetPersonality PROTO_LIST( ( + HSESSION hSession, + int CertificateIndex ) ); + +RETURN_TYPE +MACI_SetTime PROTO_LIST( ( + HSESSION hSession, + CI_TIME CI_FAR pTime ) ); + +RETURN_TYPE +MACI_Sign PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature ) ); + +RETURN_TYPE +MACI_Terminate PROTO_LIST( ( + HSESSION hSession ) ); + +RETURN_TYPE +MACI_TimeStamp PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ); + +RETURN_TYPE +MACI_Unlock PROTO_LIST( ( + HSESSION hSession) ); + +RETURN_TYPE +MACI_UnwrapKey PROTO_LIST( ( + HSESSION hSession, + int UnwrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ); + +RETURN_TYPE +MACI_VerifySignature PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + unsigned int YSize, + CI_Y CI_FAR pY, + CI_SIGNATURE CI_FAR pSignature ) ); + +RETURN_TYPE +MACI_VerifyTimeStamp PROTO_LIST( ( + HSESSION hSession, + CI_HASHVALUE CI_FAR pHashValue, + CI_SIGNATURE CI_FAR pSignature, + CI_TIMESTAMP CI_FAR pTimeStamp ) ); + +RETURN_TYPE +MACI_WrapKey PROTO_LIST( ( + HSESSION hSession, + int WrapIndex, + int KeyIndex, + CI_KEY CI_FAR pKey ) ); + +RETURN_TYPE +MACI_Zeroize PROTO_LIST( ( + HSESSION hSession ) ); + +#if __cplusplus__ || __cplusplus +} +#endif /* C++ */ + +#endif /* CRYPTINT_H */ + diff --git a/security/nss/lib/fortcrypt/macinst.htm b/security/nss/lib/fortcrypt/macinst.htm new file mode 100644 index 000000000..6a63408e6 --- /dev/null +++ b/security/nss/lib/fortcrypt/macinst.htm @@ -0,0 +1,152 @@ +<HTML> +<-- + - ***** 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 ***** --> +<TITLE>MAC Installer</TITLE> + +<SCRIPT> +// Crypto Mechanism Flags +PKCS11_MECH_RSA_FLAG = 0x1<<0; +PKCS11_MECH_DSA_FLAG = 0x1<<1; +PKCS11_MECH_RC2_FLAG = 0x1<<2; +PKCS11_MECH_RC4_FLAG = 0x1<<3; +PKCS11_MECH_DES_FLAG = 0x1<<4; +PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman +PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards +PKCS11_MECH_RC5_FLAG = 0x1<<7; +PKCS11_MECH_SHA1_FLAG = 0x1<<8; +PKCS11_MECH_MD5_FLAG = 0x1<<9; +PKCS11_MECH_MD2_FLAG = 0x1<<10; +PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator +PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in +PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default + +// Important: +// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should always be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which mechanisms should be turned on by +pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG; + + +// Ciphers that support SSL or S/MIME +PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0; + +// Important: +// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should ALWAYS be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which SSL ciphers are supported +pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG; + + +// Return values of pkcs11.addmodule() & pkcs11.delmodule() +// success codes +JS_OK_ADD_MODULE = 3 // Successfully added a module +JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module +JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module + +// failure codes +JS_ERR_OTHER = -1 // Other errors than the followings +JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action +JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments +JS_ERR_DEL_MODULE = -4 // Error deleting a module +JS_ERR_ADD_MODULE = -5 // Error adding a module +JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid +JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad +JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid +JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid + +var new_window; +var has_new_window = 0; + +function colonize(string) { + len = string.length; + end = len -1; + + if (len == 0) return string; + + + for (i=0; i < len; i++) { + if (string.charAt(i) == "/") { + if (i == 0) { + new_string = ":" + string.substring(1,len); + } else if (i == end) { + new_string = string.substring(0,i)+':'; + } else { + new_string = string.substring(0,i)+':'+ + string.substring(i+1,len); + } + string = new_string; + } + } + + if (string.charAt(0) == ":") string = string.substring(1,len); + return string; +} + +function DoInstall(module) { + module = colonize(module); + result = pkcs11.addmodule("Netscape FORTEZZA Module", module, pkcs11MechanismFlags, pkcs11CipherFlags); + if ( result < 0) { + window.alert("New module setup failed. Error code: " + result); + } + if (has_new_window) new_window.close(); +} + +function DoUnpack(name) { + new_window = open(name,"unpacking","toolbar=no,location=no,status=yes,scrollbar=no,width=50,height=50"); + has_new_window = 1; +} + +filename=navigator.platform+".hqx" + +default_module = "D:/dogbert/ns/dist/WIN32_D.OBJ/bin/fort32.dll" +document.writeln("<FORM name=instform target=_self> <H2>Mac Fortezza Installer</H2>"); +document.writeln("<I>You must first unpack the <b>"+filename+"</b> file."); +document.writeln(" Do that by clicking on button below.</i><p>"); +document.writeln("<Input type=button value=Unpack name=unpack onclick=DoUnpack(\""+filename+"\"); ><p>"); +document.writeln("<I>Then move <b>FortPK11Lib</b> to an appropriate directory "); +document.writeln(" enter that directory below, then click the Install button.</i><p>"); +document.writeln(" Module Name: <Input Type=FILE Name=module><p>"); +document.write("<Input type=submit Name=Install Value=Install onclick=DoInstall("); +document.writeln( "document.instform.module.value) >"); +document.writeln("</FORM>"); +</SCRIPT> diff --git a/security/nss/lib/fortcrypt/manifest.mn b/security/nss/lib/fortcrypt/manifest.mn new file mode 100644 index 000000000..78e8bd82b --- /dev/null +++ b/security/nss/lib/fortcrypt/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 +LIBRARY_NAME = fort +#LIBRARY_VERSION = 32 + +DIRS = swfort + +CSRCS = forsock.c \ + fortpk11.c \ + fmutex.c \ + $(NULL) + +EXPORTS = +PRIVATE_EXPORTS = maci.h cryptint.h + +REQUIRES = dbm + diff --git a/security/nss/lib/fortcrypt/replace.c b/security/nss/lib/fortcrypt/replace.c new file mode 100644 index 000000000..e0c99b1b5 --- /dev/null +++ b/security/nss/lib/fortcrypt/replace.c @@ -0,0 +1,104 @@ +/* ***** 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> + +int main(int argc, char* argv[]) { + FILE *templ; + FILE *target; + unsigned char buffer[81]; + unsigned char *find, *replace; + int matchcount = 0; + int ch; + int len; + + buffer[0] = '\0'; + + if (argc != 5) { + fprintf(stderr, "usuage: replace template.js searchstring replacestring target.js \n"); + return 1; + } + + templ = fopen(argv[1], "r"); + if (!templ) { + fprintf(stderr, "Cannot open template script %s\n", argv[1]); + return 2; + } + + find = (unsigned char*) argv[2]; + replace = (unsigned char*) argv[3]; + + target = fopen(argv[4], "w"); + if (!target) { + fclose(templ); + fprintf(stderr, "Cannot write to target script %s\n", argv[4]); + return 3; + } + + for (len = 0; find[len]!='\0'; len++); + + if (len > 80) { + fprintf(stderr, "length of searchstring exceeds 80 chars"); + return 4; + } + + /* get a char from templ */ + while ((int)(ch=fgetc(templ)) != EOF) { + if ((unsigned char)ch == find[matchcount]) { + /* if it matches find[matchcount], + * then store one more char in buffer, + * increase match count, and checks if + * the whole word has been found */ + buffer[matchcount] = (unsigned char) ch; + buffer[++matchcount] = '\0'; + + if (matchcount == len) { + matchcount = 0; + fprintf(target, "%s", replace); + } + } else { + /* reset matchcount, flush buffer */ + if (matchcount > 0) { + fprintf(target, "%s", buffer); + matchcount = 0; + } + fputc(ch, target); + } + } + fclose(templ); + fclose(target); + return 0; +} diff --git a/security/nss/lib/fortcrypt/secmodjar.html b/security/nss/lib/fortcrypt/secmodjar.html new file mode 100644 index 000000000..9ebe1a0df --- /dev/null +++ b/security/nss/lib/fortcrypt/secmodjar.html @@ -0,0 +1,445 @@ +<HTML> +<-- + - ***** 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 ***** --> +<HEAD> + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> + <META NAME="Author" CONTENT="Hoi-Sheung Wilson So"> + <META NAME="GENERATOR" CONTENT="Mozilla/4.02 [en] (WinNT; I) [Netscape]"> + <TITLE>How to Package Your Security Module for use with SmartUpdate</TITLE> +</HEAD> +<BODY> +<FONT SIZE=+2>Using +JAR Installation Manager Technology to Install Your PKCS11 Security Module</FONT> + +<P>Table of contents +<BR><A HREF="#intro">I. Introduction</A> +<BR><A HREF="#procedure">II. How to Create a Security Module JAR</A> +<BR><A HREF="#samplescript">III. Sample Installer Script</A> +<BR><A HREF="#reference">IV. Programmers' Reference</A> +<BR><A HREF="#copyright">VI. Copyright Notice</A> +<BR><A NAME="intro"></A><FONT SIZE=+1>I. Introduction</FONT> +<BR>This docuemnt describes how to prepare your security module so that +users can download it from the Internet, verify its integrity, and install +by only pointing and clicking mouses. The packaged module is a signed +JAR archive. This JAR archive contains a dynamically-linked library which +implements the Security Module and a pice of installer script (.js) that +registers and configures the newly installed module. SmartUpdate +allows users to download JAR archinve that has been signed digitally by +the software vendor. SmartUpdate then decompresses the JAR file, +verify the signature and validity of the files packaged into the archive. +If the signature is valid, SmartUpdate will run the installer script found +in the archive. The installer script will instruct SmartUpdate to +move the downloaded security module library to a specified location. +Next, the script will register the module with Navigator, and configure +it. + +<P>This document does not describe how SmartUpdate works. For more +information about SmartUpdate, check out <A HREF="http://developer.netscape.com/library/documentation/communicator/jarman/index.htm">JAR +Installation Manager</A>. + +<P><A NAME="procedure"></A><FONT SIZE=+1>II. How to Create a Security Module +JAR</FONT> +<OL> +<LI> +Obtain a copy of PKCS#11: Cryptographic Token Interface Standard Version +2.00, published by <A HREF="http://www.rsa.com">RSA Laboratories</A>, Redwood +City, California.</LI> + +<LI> +Implement a PKCS#11 library according to PKCS#11 standards.</LI> + +<LI> +Write a installer script that will register the module with Navigator.</LI> + +<LI> +Use either JAR Packager or command line tool to package the library and +the script in a signed JAR archive.</LI> + +<LI> +Publish the JAR file on the web, and notify users to install/upgrade their +library.</LI> +</OL> +<A NAME="samplescript"></A><FONT SIZE=+1>III. Sample Installer Script</FONT> + +<P>Functions of the following installer script: +<BR>1. Start SmartUpdate and declares the version and the name of the module +to be installed. +<BR>2. Extract a library called DUMMY_DLL from the JAR archive and install +it under the Netscape Program folder. +<BR>3. Register the installed module by calling pkcs11.addmodule( ) method +with information about the capabilities of the module. +<BR>4. Check to see if pkcs11.addmodule( ) has been successful, and display +appropriate messages. + +<P><TT>// Crypto Mechanism Flags</TT> +<BR><TT>PKCS11_MECH_RSA_FLAG += 0x1<<0;</TT> +<BR><TT>PKCS11_MECH_DSA_FLAG += 0x1<<1;</TT> +<BR><TT>PKCS11_MECH_RC2_FLAG += 0x1<<2;</TT> +<BR><TT>PKCS11_MECH_RC4_FLAG += 0x1<<3;</TT> +<BR><TT>PKCS11_MECH_DES_FLAG += 0x1<<4;</TT> +<BR><TT>PKCS11_MECH_DH_FLAG += 0x1<<5; //Diffie-Hellman</TT> +<BR><TT>PKCS11_MECH_SKIPJACK_FLAG = +0x1<<6; //SKIPJACK algorithm as in Fortezza cards</TT> +<BR><TT>PKCS11_MECH_RC5_FLAG += 0x1<<7;</TT> +<BR><TT>PKCS11_MECH_SHA1_FLAG += 0x1<<8;</TT> +<BR><TT>PKCS11_MECH_MD5_FLAG += 0x1<<9;</TT> +<BR><TT>PKCS11_MECH_MD2_FLAG += 0x1<<10;</TT> +<BR><TT>PKCS11_MECH_RANDOM_FLAG += 0x1<<27; //Random number generator</TT> +<BR><TT>PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored +certs can be read off the token w/o logging in</TT> +<BR><TT>PKCS11_DISABLE_FLAG += 0x1<<30; //tell Navigator to disable this slot by default</TT> + +<P><TT>// Important:</TT> +<BR><TT>// 0x1<<11, 0x1<<12, ... , 0x1<<26, and 0x1<<31 +are reserved</TT> +<BR><TT>// for internal use in Navigator.</TT> +<BR><TT>// Therefore, these bits should always be set to 0; otherwise,</TT> +<BR><TT>// Navigator might exhibit unpredictable behavior.</TT> + +<P><TT>// These flags indicate which mechanisms should be turned on by</TT> +<BR><TT>pkcs11MechanismFlags = PKCS11_MECH_DSA_FLAG | PKCS11_MECH_SKIPJACK_FLAG +| PKCS11_MECH_RANDOM_FLAG;</TT> +<BR><TT> </TT> + +<P><TT>// Ciphers that support SSL or S/MIME</TT> +<BR><TT>PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;</TT> + +<P><TT>// Important:</TT> +<BR><TT>// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, +and 0x1<<31 are reserved</TT> +<BR><TT>// for internal use in Navigator.</TT> +<BR><TT>// Therefore, these bits should ALWAYS be set to 0; otherwise,</TT> +<BR><TT>// Navigator might exhibit unpredictable behavior.</TT> + +<P><TT>// These flags indicate which SSL ciphers are supported</TT> +<BR><TT>pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;</TT> +<BR><TT> </TT> + +<P><TT>// Return values of pkcs11.addmodule() & pkcs11.delmodule()</TT> +<BR><TT>// success codes</TT> +<BR><TT>JS_OK_ADD_MODULE += 3 // Successfully added a module</TT> +<BR><TT>JS_OK_DEL_EXTERNAL_MODULE += 2 // Successfully deleted ext. module</TT> +<BR><TT>JS_OK_DEL_INTERNAL_MODULE += 1 // Successfully deleted int. module</TT> + +<P><TT>// failure codes</TT> +<BR><TT>JS_ERR_OTHER += -1 // Other errors than the followings</TT> +<BR><TT>JS_ERR_USER_CANCEL_ACTION += -2 // User abort an action</TT> +<BR><TT>JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect +# of arguments</TT> +<BR><TT>JS_ERR_DEL_MODULE += -4 // Error deleting a module</TT> +<BR><TT>JS_ERR_ADD_MODULE += -5 // Error adding a module</TT> +<BR><TT>JS_ERR_BAD_MODULE_NAME += -6 // The module name is invalid</TT> +<BR><TT>JS_ERR_BAD_DLL_NAME += -7 // The DLL name is bad</TT> +<BR><TT>JS_ERR_BAD_MECHANISM_FLAGS += -8 // The mechanism flags are invalid</TT> +<BR><TT>JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME +cipher flags are invalid</TT> +<BR> + +<P><TT>if (confirm("This script will install and configure a security module, +do you want to continue?")) {</TT> +<BR><TT> // Step 1. Create a version object and a software update +object</TT> +<BR><TT> vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0);</TT> +<BR><TT> su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza +Card PKCS#11 Module");</TT> +<BR><TT> +// "Fortezza ... Module" is the logical name of the bundle</TT> + +<P><TT> // Step 2. Start the install process</TT> +<BR><TT> bAbort = false;</TT> +<BR><TT> err = su.StartInstall("litronic", vi, netscape.softupdate.SoftwareUpdate.FULL_INSTALL);</TT> +<BR><TT> +// litronic is the component folder (logical)</TT> +<BR><TT> bAbort = bAbort || (err +!=0);</TT> + +<P><TT> if (err == 0) {</TT> + +<P><TT> // Step 3. Find out the physical location of +the Program dir</TT> +<BR><TT> Folder = su.GetFolder("Program");</TT> + +<P><TT> // Step 4. Install the files. Unpack them and +list where they go</TT> +<BR><TT> err = su.AddSubcomponent("FortezzaCardDLL", +//component name (logical)</TT> +<BR><TT> +vi, // version info</TT> +<BR><TT> +"DUMMY_DLL", // source file in JAR (physical)</TT> +<BR><TT> +Folder, // target folder (physical)</TT> +<BR><TT> +"DUMMY_DLL", // target path & filename (physical)</TT> +<BR><TT> +this.force); // forces update</TT> +<BR><TT> bAbort = bAbort || (err !=0);</TT> +<BR><TT> }</TT> + +<P><TT> // Step 5. Unless there was a problem, move files to final +location</TT> +<BR><TT> // and update the Client Version Registry</TT> +<BR><TT> if (bAbort) {</TT> +<BR><TT> window.alert("Installation Aborted");</TT> +<BR><TT> su.AbortInstall();</TT> +<BR><TT> } else {</TT> +<BR><TT> err = su.FinalizeInstall();</TT> +<BR><TT> window.alert("Files have been installed.\nContinue +to setup the newly isntalled module...");</TT> +<BR><TT> // Add Module</TT> +<BR><TT> compFolder = su.GetComponentFolder("litronic/FortezzaCardDLL") ++ "/DUMMY_DLL";</TT> +<BR><TT> result = pkcs11.addmodule("Fortezza", compFolder, +pkcs11MechanismFlags, pkcs11CipherFlags);</TT> +<BR><TT> if +( result < 0) {</TT> +<BR><TT> +window.alert("New module setup failed. Error code: " + result);</TT> +<BR><TT> } +else {</TT> +<BR><TT> +window.alert("New module setup completed.");</TT> +<BR><TT> }</TT> +<BR><TT> }</TT> +<BR><TT>}</TT> + +<P><A NAME="reference"></A><FONT SIZE=+1>IV. Appendix A: Programmers' Refernce</FONT> +<UL> +<LI> +<A HREF="#delmodule">pkcs11.addmodule( )</A></LI> + +<LI> +<A HREF="#delmodule">pkcs11.delmodule( )</A></LI> +</UL> + +<HR ALIGN=LEFT WIDTH="70%"> +<BR><A NAME="addmodule"></A>Name +<BR><TT>addmodule</TT> +<BR>Adds a PKCS#11 security module to the security module database, and +notifies Communicator which cryptographic mechanisms should be turned on +by default, and which SSL or S/MIME ciphers are supported. For security +reasons, it will pop up a dialog box to ask the user to confirm this action. +It might pop up other dialog boxes if necessary. + +<P>Method of +<BR><TT>pkcs11</TT> + +<P>Syntax +<BR><TT>int pkcs11.addmodule( string ModuleName,</TT> +<BR><TT> +string LibraryFullPath,</TT> +<BR><TT> +int CryptoMechanismFlags,</TT> +<BR><TT> +int CipherFlags);</TT> +<BR> +<BR>Parameters +<TABLE BORDER WIDTH="90%" > +<TR> +<TD><TT>ModuleName</TT></TD> + +<TD>Name of the module</TD> +</TR> + +<TR> +<TD><TT>LibraryFullPath</TT></TD> + +<TD>The filename of the library prepended with its full path</TD> +</TR> + +<TR> +<TD><TT>CryptoMechanismFlags</TT></TD> + +<TD>A bit vector indicating all cryptographic mechanisms should be turned +on by default (See below)</TD> +</TR> + +<TR> +<TD><TT>CipherFlags</TT></TD> + +<TD>A bit vector indicating all SSL or S/MIME cipher functions supported +by the module (Seel below)</TD> +</TR> +</TABLE> +Cryptographic Mechanism Flags +<BR><TT>PKCS11_MECH_RSA_FLAG += 0x1<<0;</TT> +<BR><TT>PKCS11_MECH_DSA_FLAG += 0x1<<1;</TT> +<BR><TT>PKCS11_MECH_RC2_FLAG += 0x1<<2;</TT> +<BR><TT>PKCS11_MECH_RC4_FLAG += 0x1<<3;</TT> +<BR><TT>PKCS11_MECH_DES_FLAG += 0x1<<4;</TT> +<BR><TT>PKCS11_MECH_DH_FLAG += 0x1<<5; //Diffie-Hellman</TT> +<BR><TT>PKCS11_MECH_SKIPJACK_FLAG = +0x1<<6; //SKIPJACK algorithm as in Fortezza cards</TT> +<BR><TT>PKCS11_MECH_RC5_FLAG += 0x1<<7;</TT> +<BR><TT>PKCS11_MECH_SHA1_FLAG += 0x1<<8;</TT> +<BR><TT>PKCS11_MECH_MD5_FLAG += 0x1<<9;</TT> +<BR><TT>PKCS11_MECH_MD2_FLAG += 0x1<<10;</TT> +<BR><TT>PKCS11_MECH_RANDOM_FLAG += 0x1<<27; //Random number generator</TT> +<BR><TT>PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored +certs can be read off the token w/o logging in</TT> +<BR><TT>PKCS11_DISABLE_FLAG += 0x1<<30; //tell Navigator to disable this slot by default</TT> + +<P>Supported SSL or S/MIME Ciphers +<BR><TT>PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;</TT> + +<P>Important for CryptoMechanismFlags: +<BR><TT>0x1<<11</TT>, <TT>0x1<<12</TT>, ... , <TT>0x1<<26</TT>, +<TT>0x1<<29, </TT>and <TT>0x1<<31</TT> are reserved for internal +use in Navigator. +<BR>Therefore, these bits should always be set to 0; otherwise, Navigator +might exhibit unpredictable behavior. + +<P>Important for CipherFlags: +<BR><TT>0x1<<1</TT>, <TT>0x1<<2</TT>, ... , <TT>0x1<<31</TT> +are reserved for internal use in Navigator. +<BR>Therefore, these bits should ALWAYS be set to 0; otherwise, Navigator +might exhibit unpredictable behavior. + +<P>Example of CryptoMechanismFlags and CipherFlags: +<BR><TT>pkcs11MechanismFlags = PKCS11_MECH_DSA_FLAG | PKCS11_MECH_SKIPJACK_FLAG +| PKCS11_MECH_RANDOM_FLAG;</TT> +<BR><TT>pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;</TT> +<BR><TT> </TT> +<BR>Return Values: +<BR><TT>// Return values of pkcs11.addmod()</TT> +<BR><TT>// success codes</TT> +<BR><TT>JS_OK_ADD_MODULE += 3 // Successfully added a module</TT> + +<P><TT>// failure codes</TT> +<BR><TT>JS_ERR_OTHER += -1 // Other errors than the followings</TT> +<BR><TT>JS_ERR_USER_CANCEL_ACTION += -2 // User abort an action</TT> +<BR><TT>JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect +# of arguments</TT> +<BR><TT>JS_ERR_ADD_MODULE += -5 // Error adding a module</TT> +<BR><TT>JS_ERR_BAD_MODULE_NAME += -6 // The module name is invalid</TT> +<BR><TT>JS_ERR_BAD_DLL_NAME += -7 // The DLL name is bad</TT> +<BR><TT>JS_ERR_BAD_MECHANISM_FLAGS += -8 // The mechanism flags are invalid</TT> +<BR><TT>JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME +cipher flags are invalid</TT> +<BR> +<HR ALIGN=LEFT WIDTH="70%"> +<BR><A NAME="delmodule"></A>Name +<BR><TT>delmodule</TT> +<BR>Deletes a PKCS#11 security module from the module database, but does +not physically remove the file. For security reasons, it will pop +up a dialog box to ask the user to confirm this action. It might +pop up other dialog boxes if necessary. + +<P>Method of +<BR><TT>pkcs11</TT> + +<P>Syntax +<BR><TT>int pkcs11.delmodule( string ModuleName);</TT> +<BR> +<BR>Parameters +<TABLE BORDER WIDTH="90%" > +<TR> +<TD><TT>ModuleName</TT></TD> + +<TD>Name of the module</TD> +</TR> +</TABLE> +<TT> </TT> +<BR>Return Values: +<BR><TT>// Return values of pkcs11.addmod() & pkcs11.delmod()</TT> +<BR><TT>// success codes</TT> +<BR><TT>JS_OK_DEL_EXTERNAL_MODULE += 2 // Successfully deleted ext. module</TT> +<BR><TT>JS_OK_DEL_INTERNAL_MODULE += 1 // Successfully deleted int. module</TT> + +<P><TT>// failure codes</TT> +<BR><TT>JS_ERR_OTHER += -1 // Other errors than the followings</TT> +<BR><TT>JS_ERR_USER_CANCEL_ACTION += -2 // User abort an action</TT> +<BR><TT>JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect +# of arguments</TT> +<BR><TT>JS_ERR_DEL_MODULE += -4 // Error deleting a module</TT> +<BR><TT>JS_ERR_BAD_MODULE_NAME += -6 // The module name is invalid</TT> + +<P><A NAME="copyright"></A><FONT SIZE=+1>VI. Copyright Notice</FONT> +<BR> + +<P><FONT SIZE=+4>XXX Don't know what to put here!!!</FONT> + +<P>Last modified 9/26/97 +</BODY> +</HTML> diff --git a/security/nss/lib/fortcrypt/swfort/Makefile b/security/nss/lib/fortcrypt/swfort/Makefile new file mode 100644 index 000000000..171641e78 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/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). # +####################################################################### + +include config.mk + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + +$(OBJDIR)/nslib.c: nsmap.h swflib.c + @$(MAKE_OBJDIR) + rm -f $@ + cat $+ > $@ + +export:: private_export + + diff --git a/security/nss/lib/fortcrypt/swfort/config.mk b/security/nss/lib/fortcrypt/swfort/config.mk new file mode 100644 index 000000000..665828c63 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/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/lib/fortcrypt/swfort/manifest.mn b/security/nss/lib/fortcrypt/swfort/manifest.mn new file mode 100644 index 000000000..d70d6b2ed --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/manifest.mn @@ -0,0 +1,56 @@ +# +# ***** 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 +LIBRARY_NAME = swfci +#LIBRARY_VERSION = 12 + +BUILT_CSRCS = nslib.c \ + $(NULL) + +CSRCS = swfalg.c \ + swfparse.c \ + swflib.c \ + swfutl.c \ + $(NULL) +DIRS = pkcs11 + +EXPORTS = swfort.h swfortt.h +PRIVATE_EXPORTS = swforti.h swfortti.h + +REQUIRES = dbm nspr diff --git a/security/nss/lib/fortcrypt/swfort/nsmap.h b/security/nss/lib/fortcrypt/swfort/nsmap.h new file mode 100644 index 000000000..e582c2eb1 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/nsmap.h @@ -0,0 +1,89 @@ +/* ***** 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 ***** */ +#define MACI_ChangePIN NSCI_ChangePIN +#define MACI_CheckPIN NSCI_CheckPIN +#define MACI_Close NSCI_Close +#define MACI_Decrypt NSCI_Decrypt +#define MACI_DeleteCertificate NSCI_DeleteCertificate +#define MACI_DeleteKey NSCI_DeleteKey +#define MACI_Encrypt NSCI_Encrypt +#define MACI_ExtractX NSCI_ExtractX +#define MACI_FirmwareUpdate NSCI_FirmwareUpdate +#define MACI_GenerateIV NSCI_GenerateIV +#define MACI_GenerateMEK NSCI_GenerateMEK +#define MACI_GenerateRa NSCI_GenerateRa +#define MACI_GenerateRandom NSCI_GenerateRandom +#define MACI_GenerateTEK NSCI_GenerateTEK +#define MACI_GenerateX NSCI_GenerateX +#define MACI_GetCertificate NSCI_GetCertificate +#define MACI_GetConfiguration NSCI_GetConfiguration +#define MACI_GetHash NSCI_GetHash +#define MACI_GetPersonalityList NSCI_GetPersonalityList +#define MACI_GetSessionID NSCI_GetSessionID +#define MACI_GetState NSCI_GetState +#define MACI_GetStatus NSCI_GetStatus +#define MACI_GetTime NSCI_GetTime +#define MACI_Hash NSCI_Hash +#define MACI_Initialize NSCI_Initialize +#define MACI_InitializeHash NSCI_InitializeHash +#define MACI_InstallX NSCI_InstallX +#define MACI_LoadCertificate NSCI_LoadCertificate +#define MACI_LoadDSAParameters NSCI_LoadDSAParameters +#define MACI_LoadInitValues NSCI_LoadInitValues +#define MACI_LoadIV NSCI_LoadIV +#define MACI_LoadX NSCI_LoadX +#define MACI_Lock NSCI_Lock +#define MACI_Open NSCI_Open +#define MACI_RelayX NSCI_RelayX +#define MACI_Reset NSCI_Reset +#define MACI_Restore NSCI_Restore +#define MACI_Save NSCI_Save +#define MACI_Select NSCI_Select +#define MACI_SetConfiguration NSCI_SetConfiguration +#define MACI_SetKey NSCI_SetKey +#define MACI_SetMode NSCI_SetMode +#define MACI_SetPersonality NSCI_SetPersonality +#define MACI_SetTime NSCI_SetTime +#define MACI_Sign NSCI_Sign +#define MACI_Terminate NSCI_Terminate +#define MACI_TimeStamp NSCI_TimeStamp +#define MACI_Unlock NSCI_Unlock +#define MACI_UnwrapKey NSCI_UnwrapKey +#define MACI_VerifySignature NSCI_VerifySignature +#define MACI_VerifyTimeStamp NSCI_VerityTimeStap +#define MACI_WrapKey NSCI_WrapKey +#define MACI_Zeroize NSCI_Zeroize + diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/.cvsignore b/security/nss/lib/fortcrypt/swfort/pkcs11/.cvsignore new file mode 100644 index 000000000..6532d294d --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/.cvsignore @@ -0,0 +1,15 @@ +forsock.c +cryptint.h +fmutex.h +fortsock.h +fpkcs11.h +fpkcs11f.h +fpkcs11i.h +fpkcs11t.h +fpkmem.h +fpkstrs.h +genci.h +maci.h +fortpk11.c +fmutex.c + diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile b/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile new file mode 100644 index 000000000..e168fe3d2 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile @@ -0,0 +1,179 @@ +#! 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 ***** + +include manifest.mn +include $(CORE_DEPTH)/coreconf/config.mk +include config.mk + +CRYPTO_LIB = $(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) +#SWCILI = ../$(OBJDIR)/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) + +# can't do this in manifest.mn because OS_TARGET isn't defined there. +ifeq (,$(filter-out WIN%,$(OS_TARGET))) + +ifdef MOZILLA_SECURITY_BUILD +CRYPTO_LIB = $(DIST)/lib/crypto.lib +endif +ifdef MOZILLA_BSAFE_BUILD +CRYPTO_LIB += $(DIST)/lib/bsafe$(BSAFEVER).lib +CRYPTO_LIB += $(DIST)/lib/freebl.lib +endif + +# Link with the real NSPR DLLs for MinGW because the NSPR stubs in +# stub.c can't resolve the references to the _imp__PR_XXX symbols. +# This is merely an expedient hack and not the right solution. +ifdef NS_USE_GCC +EXTRA_LIBS = \ + $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX) \ + $(CRYPTO_LIB) \ + $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \ + -L$(DIST)/lib \ + -lplc4 \ + -lplds4 \ + -lnspr4 \ + -lwsock32 \ + -lwinmm \ + $(NULL) +else # ! NS_USE_GCC +EXTRA_LIBS = \ + $(DIST)/lib/swfci.lib \ + $(DIST)/lib/softokn.lib \ + $(CRYPTO_LIB) \ + $(DIST)/lib/secutil.lib \ + $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4_s.lib \ + $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4_s.lib \ + wsock32.lib \ + winmm.lib \ + $(NULL) +endif # NS_USE_GCC + +else + +ifdef MOZILLA_SECURITY_BUILD +CRYPTO_LIB = $(DIST)/lib/$(LIB_PREFIX)crypto.$(LIB_SUFFIX) +endif +ifdef MOZILLA_BSAFE_BUILD +CRYPTO_LIB += $(DIST)/lib/$(LIB_PREFIX)bsafe.$(LIB_SUFFIX) +CRYPTO_LIB += $(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) +endif + +EXTRA_LIBS += \ + $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX) \ + $(CRYPTO_LIB) \ + $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)plc4.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)plds4.$(LIB_SUFFIX) \ + $(NULL) + +endif + +INST_JS = inst.js +LIBCI_JAR = $(OBJDIR)/lib$(LIBRARY_NAME).jar +LIBCI_JAR_SRC = $(INST_JS) pk11inst $(SHARED_LIBRARY) + +ifneq ($(OS_TARGET), WIN16) +TARGETS : $(LIBCI_JAR) +endif + +ifeq ($(OS_TARGET), WIN16) +# note that rules.mk is not included below for WIN16 +all: + @echo Skipping fortcrypt directory for 16-bit windows builds + +all_platforms alltags clean clobber clobber_all realclean: all + +boot export install libs program release: all + +endif + +#$(SHARED_LIBRARY): $(SWCILIB) + +# +# The following rules packages the shared library into a JAR, +# ready to be signed +# +$(OBJDIR)/replace: replace.c + $(CC) -o $@ $< + +# ZIP options: +# -5 means medium compression +# -q means quiet +# -j means do not store tree structure, all files go into one dir +# +$(LIBCI_JAR): $(LIBCI_JAR_SRC) + @echo +++ building $@ from $(LIBCI_JAR_SRC) + @rm -f $@ + zip -5qj $@ $(LIBCI_JAR_SRC) + +$(LIBSWCI_JAR): $(LIBSWCI_JAR_SRC) + @echo +++ building $@ from $(LIBSWCI_JAR_SRC) + @rm -f $@ + zip -5qj $@ $(LIBSWCI_JAR_SRC) + + +MD_FILES += $(LIBCI_JAR) $(LIBSWCI_JAR) + +# coreconf doesn't build the AIX shared library for FORTEZZA, +# so I'm going to override their shared library command and build the shared +# library the way config used to. +# + + +ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1) +DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry +EXTRA_DSO_LDOPTS = -lc +MKSHLIB = xlC $(DSO_LDOPTS) + +$(SHARED_LIBRARY): $(OBJS) + @$(MAKE_OBJDIR) + rm -f $@ + $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS) + chmod +x $@ + +endif + +ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2) +LD += -G +endif + +ifneq ($(OS_TARGET), WIN16) +include $(CORE_DEPTH)/coreconf/rules.mk +endif + diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/config.mk b/security/nss/lib/fortcrypt/swfort/pkcs11/config.mk new file mode 100644 index 000000000..389e17e9b --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/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 shared libraries +# are specifed as dependencies within rules.mk. +# + +TARGETS = $(SHARED_LIBRARY) $(SHARED_SW_LIBRARY) $(LIBCI_JAR) $(LIBCI_SW_JAR) +LIBRARY = +IMPORT_LIBRARY = +PROGRAM = + diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/inst.js b/security/nss/lib/fortcrypt/swfort/pkcs11/inst.js new file mode 100644 index 000000000..1eaf79af2 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/inst.js @@ -0,0 +1,193 @@ +/* ***** 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 ***** */ + +//////////////////////////////////////////////////////////////////////////////////////// +// Crypto Mechanism Flags +PKCS11_MECH_RSA_FLAG = 0x1<<0; +PKCS11_MECH_DSA_FLAG = 0x1<<1; +PKCS11_MECH_RC2_FLAG = 0x1<<2; +PKCS11_MECH_RC4_FLAG = 0x1<<3; +PKCS11_MECH_DES_FLAG = 0x1<<4; +PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman +PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards +PKCS11_MECH_RC5_FLAG = 0x1<<7; +PKCS11_MECH_SHA1_FLAG = 0x1<<8; +PKCS11_MECH_MD5_FLAG = 0x1<<9; +PKCS11_MECH_MD2_FLAG = 0x1<<10; +PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator +PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in +PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default + +// Important: +// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should always be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which mechanisms should be turned on by +var pkcs11MechanismFlags = 0; + +//////////////////////////////////////////////////////////////////////////////////////// +// Ciphers that support SSL or S/MIME +PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0; + +// Important: +// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved +// for internal use in Navigator. +// Therefore, these bits should ALWAYS be set to 0; otherwise, +// Navigator might exhibit unpredictable behavior. + +// These flags indicate which SSL ciphers are supported +var pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG; + +//////////////////////////////////////////////////////////////////////////////////////// +// Return values of pkcs11.addmodule() & pkcs11.delmodule() +// success codes +JS_OK_ADD_MODULE = 3; // Successfully added a module +JS_OK_DEL_EXTERNAL_MODULE = 2; // Successfully deleted ext. module +JS_OK_DEL_INTERNAL_MODULE = 1; // Successfully deleted int. module + +// failure codes +JS_ERR_OTHER = -1; // Other errors than the followings +JS_ERR_USER_CANCEL_ACTION = -2; // User abort an action +JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3; // Calling a method w/ incorrect # of arguments +JS_ERR_DEL_MODULE = -4; // Error deleting a module +JS_ERR_ADD_MODULE = -5; // Error adding a module +JS_ERR_BAD_MODULE_NAME = -6; // The module name is invalid +JS_ERR_BAD_DLL_NAME = -7; // The DLL name is bad +JS_ERR_BAD_MECHANISM_FLAGS = -8; // The mechanism flags are invalid +JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9; // The SSL, S/MIME cipher flags are invalid + + +//////////////////////////////////////////////////////////////////////////////////////// +// Find out which library is to be installed depending on the platform + +// pathname seperator is platform specific +var sep = "/"; +var vendor = "netscape"; +var moduleName = "not_supported"; + +// platform-independent relative path +var dir = "pkcs11/" + vendor + "/"; + +var plat = navigator.platform; + +bAbort = false; +progName = "instinit"; +if (plat == "Win32") { + moduleName = "swft32.dll"; + // progName = "instinit.exe"; + sep = "\\"; +} else if (plat == "AIX4.1") { + moduleName = "libswft.so"; +} else if (plat == "SunOS4.1.3_U1") { + moduleName = "libswft.so.1.0"; +} else if ((plat == "SunOS5.4") || (plat == "SunOS5.5.1")){ + moduleName = "libswft.so"; +} else if ((plat == "HP-UXA.09") || (plat == "HP-UXB.10")){ + moduleName = "libswft.sl"; +} else { + window.alert("Sorry, platform "+plat+" is not supported."); + bAbort = true; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// Installation Begins... +if (!bAbort) { +if (confirm("This script will install and configure a security module, do you want to continue?")) { + // Step 1. Create a version object and a software update object + vi = new netscape.softupdate.VersionInfo(1, 5, 0, 0); + su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module"); + // "Fortezza ... Module" is the logical name of the bundle + + //////////////////////////////////////// + // Step 2. Start the install process + bAbort = false; + err = su.StartInstall("NSfortezza", // NSfortezza is the component folder (logical) + vi, + netscape.softupdate.SoftwareUpdate.FULL_INSTALL); + + bAbort = bAbort || (err !=0); + + if (err == 0) { + //////////////////////////////////////// + // Step 3. Find out the physical location of the Program dir + Folder = su.GetFolder("Program"); + + //////////////////////////////////////// + // Step 4. Install the files. Unpack them and list where they go + err = su.AddSubcomponent("FortezzaLibrary", //component name (logical) + vi, // version info + moduleName, // source file in JAR (physical) + Folder, // target folder (physical) + dir + moduleName, // target path & filename (physical) + this.force); // forces update + bAbort = bAbort || (err !=0); + if (err != 0) window.alert("Add sub err= "+ err); + } + + if (err == 0) { + /// Try installing the init program + err = su.AddSubcomponent("FortezzaInitProg", vi, progName, Folder, progName, this.force); + // don't fail because it didn't install, may just not be part of the package +} + + //////////////////////////////////////// + // Step 5. Unless there was a problem, move files to final location + // and update the Client Version Registry + if (bAbort) { + window.alert("Aborting, Folder="+Folder+" module="+dir+moduleName); + su.AbortInstall(); + } else { + err = su.FinalizeInstall(); + // Platform specific full path + fullpath = Folder + "pkcs11" + sep + vendor + sep + moduleName; + + //////////////////////////////////////// + // Step 6: Call pkcs11.addmodule() to register the newly downloaded module + result = pkcs11.addmodule("Netscape Software FORTEZZA Module", + fullpath, + pkcs11MechanismFlags, + pkcs11CipherFlags); + + if ( result < 0) { + window.alert("New module setup failed. Error code: " + result); + } else { + window.alert("New module setup completed."); + } + } +} +} diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn b/security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn new file mode 100644 index 000000000..cbd49039b --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn @@ -0,0 +1,67 @@ +# +# ***** 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 +LIBRARY_NAME = swft +#LIBRARY_VERSION = 32 + +COPIED_CSRCS = forsock.c \ + fortpk11.c \ + fmutex.c \ + $(NULL) + +CSRCS = \ + $(COPIED_CSRCS) \ + stub.c \ + $(NULL) + +vpath %.c ../../ +INCLUDES = -I../.. + +EXPORTS = + +REQUIRES = dbm + + +DEFINES = -DSWFORT + +GARBAGE = $(COPIED_CSRCS) cryptint.h fmutex.h fortsock.h fpkcs11.h \ + fpkcs11f.h fpkcs11i.h fpkcs11t.h fpkmem.h fpkstrs.h genci.h maci.h + + diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/pk11inst b/security/nss/lib/fortcrypt/swfort/pkcs11/pk11inst new file mode 100755 index 000000000..31d73eb4a --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/pk11inst @@ -0,0 +1,49 @@ +ForwardCompatible { HPUX:10:hppa1.1 Solaris:5.5.1:sparc AIX:4.1:rs6000 } + Platforms { + WINNT::x86 { + ModuleName { "Netscape Software FORTEZZA Module" } + ModuleFile { %root%/pkcs11/netscape/swft32.dll } + DefaultMechanismFlags{0x0000} + DefaultCipherFlags{0x0001} + Files { + swft32.dll { + RelativePath { %root%/pkcs11/netscape/swft32.dll } + } + } + WIN95::x86 { + EquivalentPlatform {WINNT::x86} + } + Solaris:5.5.1:sparc { + ModuleName { "Netscape Software FORTEZZA Module" } + ModuleFile { %root%/pkcs11/netscape/libswft.so } + DefaultMechanismFlags{0x0000} + DefaultCipherFlags{0x0001} + Files { + libswft.so { + RelativePath { %root%/pkcs11/netscape/libswft.so } + } + } + } + AIX:4.1:rs6000 { + ModuleName { "Netscape Software FORTEZZA Module" } + ModuleFile { %root%/pkcs11/netscape/libswft.so } + DefaultMechanismFlags{0x0000} + DefaultCipherFlags{0x0001} + Files { + libswft.so { + RelativePath { %root%/pkcs11/netscape/libswft.so } + } + } + } + HPUX:10:hppa1.1 { + ModuleName { "Netscape Software FORTEZZA Module" } + ModuleFile { %root%/pkcs11/netscape/libswft.sl } + DefaultMechanismFlags{0x0000} + DefaultCipherFlags{0x0001} + Files { + libswft.so { + RelativePath { %root%/pkcs11/netscape/libswft.sl } + } + } + } + } diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c b/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c new file mode 100644 index 000000000..769cc843d --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c @@ -0,0 +1,380 @@ +/* ***** 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 ***** */ +/* + * secport.c - portability interfaces for security libraries + * + * This file abstracts out libc functionality that libsec depends on + * + * NOTE - These are not public interfaces. These stubs are to allow the + * SW FORTEZZA to link with some low level security functions without dragging + * in NSPR. + * + * $Id$ + */ + +#include "seccomon.h" +#include "prmem.h" +#include "prerror.h" +#include "plarena.h" +#include "secerr.h" +#include "prmon.h" +#include "prbit.h" + +unsigned long port_allocFailures; + +/* locations for registering Unicode conversion functions. + * Is this the appropriate location? or should they be + * moved to client/server specific locations? + */ +PORTCharConversionFunc ucs4Utf8ConvertFunc; +PORTCharConversionFunc ucs2Utf8ConvertFunc; +PORTCharConversionWSwapFunc ucs2AsciiConvertFunc; + +void * +PORT_Alloc(size_t bytes) +{ + void *rv; + + /* Always allocate a non-zero amount of bytes */ + rv = (void *)malloc(bytes ? bytes : 1); + if (!rv) { + ++port_allocFailures; + } + return rv; +} + +void * +PORT_Realloc(void *oldptr, size_t bytes) +{ + void *rv; + + rv = (void *)realloc(oldptr, bytes); + if (!rv) { + ++port_allocFailures; + } + return rv; +} + +void * +PORT_ZAlloc(size_t bytes) +{ + void *rv; + + /* Always allocate a non-zero amount of bytes */ + rv = (void *)calloc(1, bytes ? bytes : 1); + if (!rv) { + ++port_allocFailures; + } + return rv; +} + +void +PORT_Free(void *ptr) +{ + if (ptr) { + free(ptr); + } +} + +void +PORT_ZFree(void *ptr, size_t len) +{ + if (ptr) { + memset(ptr, 0, len); + free(ptr); + } +} + +char * +PORT_Strdup(const char *str) +{ + size_t len = PORT_Strlen(str)+1; + char *newstr; + + newstr = (char *)PORT_Alloc(len); + if (newstr) { + PORT_Memcpy(newstr, str, len); + } + return newstr; +} + +void +PORT_SetError(int value) +{ + return; +} + +int +PORT_GetError(void) +{ + return(1); +} + +/********************* Arena code follows *****************************/ + + +PLArenaPool * +PORT_NewArena(unsigned long chunksize) +{ + PLArenaPool *arena; + + arena = (PLArenaPool*)PORT_ZAlloc(sizeof(PLArenaPool)); + if ( arena != NULL ) { + PR_InitArenaPool(arena, "security", chunksize, sizeof(double)); + } + return(arena); +} + +void * +PORT_ArenaAlloc(PLArenaPool *arena, size_t size) +{ + void *p; + + PL_ARENA_ALLOCATE(p, arena, size); + if (p == NULL) { + ++port_allocFailures; + } + + return(p); +} + +void * +PORT_ArenaZAlloc(PLArenaPool *arena, size_t size) +{ + void *p; + + PL_ARENA_ALLOCATE(p, arena, size); + if (p == NULL) { + ++port_allocFailures; + } else { + PORT_Memset(p, 0, size); + } + + return(p); +} + +/* need to zeroize!! */ +void +PORT_FreeArena(PLArenaPool *arena, PRBool zero) +{ + PR_FinishArenaPool(arena); + PORT_Free(arena); +} + +void * +PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize) +{ + PORT_Assert(newsize >= oldsize); + + PL_ARENA_GROW(ptr, arena, oldsize, ( newsize - oldsize ) ); + + return(ptr); +} + +void * +PORT_ArenaMark(PLArenaPool *arena) +{ + void * result; + + result = PL_ARENA_MARK(arena); + return result; +} + +void +PORT_ArenaRelease(PLArenaPool *arena, void *mark) +{ + PL_ARENA_RELEASE(arena, mark); +} + +void +PORT_ArenaUnmark(PLArenaPool *arena, void *mark) +{ + /* do nothing */ +} + +char * +PORT_ArenaStrdup(PLArenaPool *arena,const char *str) { + int len = PORT_Strlen(str)+1; + char *newstr; + + newstr = (char*)PORT_ArenaAlloc(arena,len); + if (newstr) { + PORT_Memcpy(newstr,str,len); + } + return newstr; +} + +/* + * Do not use NSPR stubs for MinGW because they can't resolve references + * to the _imp__PR_XXX symbols. This is merely an expedient hack and not + * the right solution. + */ +#if !(defined(WIN32) && defined(__GNUC__)) +PR_IMPLEMENT(void) +PR_Assert(const char *expr, const char *file, int line) { + return; +} + +PR_IMPLEMENT(void *) +PR_Alloc(PRUint32 bytes) { return malloc(bytes); } + +PR_IMPLEMENT(void *) +PR_Malloc(PRUint32 bytes) { return malloc(bytes); } + +PR_IMPLEMENT(void *) +PR_Calloc(PRUint32 blocks, PRUint32 bytes) { return calloc(blocks,bytes); } + +PR_IMPLEMENT(void) +PR_Free(void *ptr) { free(ptr); } + +PR_IMPLEMENT(void) +PR_SetError(PRErrorCode errorCode, PRInt32 oserr) { return; } + +PR_IMPLEMENT(void) +PR_SetErrorText(PRIntn textLength, const char *text) { return; } +#endif /* ! (WIN32 && GCC) */ + + +/* Old template; want to expunge it eventually. */ +#include "secasn1.h" +#include "secoid.h" + +const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(SECAlgorithmID) }, + { SEC_ASN1_OBJECT_ID, + offsetof(SECAlgorithmID,algorithm), }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, + offsetof(SECAlgorithmID,parameters), }, + { 0, } +}; + +/* + * Do not use NSPR stubs for MinGW because they can't resolve references + * to the _imp__PR_XXX symbols. This is merely an expedient hack and not + * the right solution. + */ +#if !(defined(WIN32) && defined(__GNUC__)) +/* now make the RNG happy */ /* This is not atomic! */ +PR_IMPLEMENT(PRInt32) PR_AtomicIncrement(PRInt32 *val) { return ++(*val); } +/* This is not atomic! */ +PR_IMPLEMENT(PRInt32) PR_AtomicDecrement(PRInt32 *val) { return --(*val); } + +PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks) { return PR_SUCCESS; } + +#include "nssilock.h" +#include "fmutex.h" +PR_IMPLEMENT(PRLock *) +PR_NewLock(void) { + PRLock *lock = NULL; + + FMUTEX_Create((void **)&lock); + + /* if we don't have a lock, FMUTEX can deal with things */ + if (lock == NULL) lock=(PRLock *) 1; + return lock; +} + +PR_IMPLEMENT(void) +PR_DestroyLock(PRLock *lock) { + FMUTEX_Destroy(lock); +} + +PR_IMPLEMENT(void) +PR_Lock(PRLock *lock) { + FMUTEX_Lock(lock); +} + +PR_IMPLEMENT(PRStatus) +PR_Unlock(PRLock *lock) { + FMUTEX_Unlock(lock); + return PR_SUCCESS; +} + +/* this implementation is here to satisfy the PRMonitor use in plarena.c. +** It appears that it doesn't need re-entrant locks. It could have used +** PRLock instead of PRMonitor. So, this implementation just uses +** PRLock for a PRMonitor. +*/ +PR_IMPLEMENT(PRMonitor*) +PR_NewMonitor(void) +{ + return (PRMonitor *) PR_NewLock(); +} + + +PR_IMPLEMENT(void) +PR_EnterMonitor(PRMonitor *mon) +{ + PR_Lock( (PRLock *)mon ); +} + +PR_IMPLEMENT(PRStatus) +PR_ExitMonitor(PRMonitor *mon) +{ + return PR_Unlock( (PRLock *)mon ); +} + +#include "prinit.h" + +/* This is NOT threadsafe. It is merely a pseudo-functional stub. +*/ +PR_IMPLEMENT(PRStatus) PR_CallOnce( + PRCallOnceType *once, + PRCallOnceFN func) +{ + /* This is not really atomic! */ + if (1 == PR_AtomicIncrement(&once->initialized)) { + once->status = (*func)(); + } else { + /* Should wait to be sure that func has finished before returning. */ + } + return once->status; +} + + +/* +** Compute the log of the least power of 2 greater than or equal to n +*/ +PRIntn PR_CeilingLog2(PRUint32 i) { + PRIntn log2; + PR_CEILING_LOG2(log2,i); + return log2; +} +#endif /* ! (WIN32 && GCC) */ + +/********************** end of arena functions ***********************/ + diff --git a/security/nss/lib/fortcrypt/swfort/swfalg.c b/security/nss/lib/fortcrypt/swfort/swfalg.c new file mode 100644 index 000000000..7a53e8e3d --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfalg.c @@ -0,0 +1,509 @@ +/* ***** 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 ***** */ +/* + * Software implementation of FORTEZZA skipjack primatives + */ +#include "maci.h" +#include "seccomon.h" +#include "swforti.h" + +/* + * Xor the IV into the plaintext buffer either just before encryption, or + * just after decryption. + */ +static void +fort_XorIV(unsigned char *obuffer, unsigned char *buffer, unsigned char *iv) { + int i; +#ifdef USE_INT32 + if ((buffer & 0x3) == 0) && ((iv & 0x3) == 0)) { + int32 *ibuffer = (int32 *)buffer; + int32 *iobuffer = (int32 *)obuffer; + int32 *iiv = (int32 *)iv; + + iobuffer[0] = ibuffer[0] ^ iiv[0]; + iobuffer[1] = ibuffer[1] ^ iiv[1]; + return; + } +#endif + + for (i=0; i < SKIPJACK_BLOCK_SIZE; i++) { + obuffer[i] = buffer[i] ^ iv[i]; + } +} + + +/* the F-table for Skipjack */ +unsigned char F[256] = { + 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4, + 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9, + 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e, + 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28, + 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68, + 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53, + 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19, + 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2, + 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b, + 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8, + 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0, + 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90, + 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69, + 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76, + 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20, + 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d, + 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43, + 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18, + 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa, + 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4, + 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87, + 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40, + 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b, + 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5, + 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0, + 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2, + 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1, + 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8, + 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5, + 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac, + 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3, + 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46 +}; + +typedef unsigned char fort_keysched[32*4]; + +/* do the key schedule work once for efficency */ +static void +fort_skipKeySchedule(FORTSkipjackKeyPtr key,fort_keysched keysched) +{ + unsigned char *keyptr = key; + unsigned char *first = keyptr +sizeof(FORTSkipjackKey)-1; + int i; + + keyptr = first; + + for (i=0; i < (32*4); i++) { + keysched[i] = *keyptr--; + if (keyptr < key) keyptr = first; + } + return; +} + +static void +fort_clearShedule(fort_keysched keysched) +{ + PORT_Memset(keysched, 0, sizeof(keysched)); +} + + +static unsigned int +G(fort_keysched cv, int k, unsigned int wordIn) +{ + unsigned char g1, g2, g3, g4, g5, g6; + + g1 = (unsigned char) (wordIn >> 8) & 0xff; + g2 = (unsigned char) wordIn & 0xff; + + g3 = F[g2^cv[4*k]]^g1; + g4 = F[g3^cv[4*k+1]]^g2; + g5 = F[g4^cv[4*k+2]]^g3; + g6 = F[g5^cv[4*k+3]]^g4; + + return ((g5<<8)+g6); +} + +static unsigned int +G1(fort_keysched cv, int k, unsigned int wordIn) +{ + unsigned char g1, g2, g3, g4, g5, g6; + + g5 = (unsigned char) (wordIn >> 8) & 0xff; + g6 = (unsigned char) wordIn & 0xff; + + g4 = F[g5^cv[4*k+3]]^g6; + g3 = F[g4^cv[4*k+2]]^g5; + g2 = F[g3^cv[4*k+1]]^g4; + g1 = F[g2^cv[4*k]]^g3; + + return ((g1<<8)+g2); +} + +static void +ruleA(fort_keysched cv,int round,unsigned int *w) +{ + unsigned int w4; + int i; + + for(i=0; i<8; i++) { + int k = round*16+i; + int counter = k+1; + + w4 = w[4]; + w[4] = w[3]; + w[3] = w[2]; + w[2] = G(cv,k,w[1]); + w[1] = G(cv,k,w[1]) ^ w4 ^ counter; + } + return; +} + +static void +ruleB(fort_keysched cv,int round,unsigned int *w) +{ + unsigned int w4; + int i; + + for(i=0; i<8; i++) { + int k = round*16+i+8; + int counter = k+1; + + w4 = w[4]; + w[4] = w[3]; + w[3] = w[1] ^ w[2] ^ counter; + w[2] = G(cv,k,w[1]); + w[1] = w4; + } + return; +} + +static void +ruleA1(fort_keysched cv,int round,unsigned int *w) +{ + unsigned int w4; + int i; + + for(i=7; i>=0; i--) { + int k = round*16+i; + int counter = k+1; + + w4 = w[4]; + w[4] = w[1] ^ w[2] ^ counter; + w[1] = G1(cv,k,w[2]); + w[2] = w[3]; + w[3] = w4; + } + return; +} + +static void +ruleB1(fort_keysched cv,int round,unsigned int *w) +{ + unsigned int w4; + int i; + + for(i=7; i>=0; i--) { + int k = round*16+i+8; + int counter = k+1; + + w4 = w[4]; + w[4] = w[1]; + w[1] = G1(cv,k,w[2]); + w[2] = G1(cv,k,w[2]) ^ w[3] ^ counter; + w[3] = w4; + } + return; +} + + +static void +fort_doskipD(fort_keysched cv,unsigned char *cipherIn, + unsigned char *plainOut) { + unsigned int w[5]; /* ignore w[0] so the code matches the doc */ + + /* initial byte swap */ + w[1]=(cipherIn[7]<<8)+cipherIn[6]; + w[2]=(cipherIn[5]<<8)+cipherIn[4]; + w[3]=(cipherIn[3]<<8)+cipherIn[2]; + w[4]=(cipherIn[1]<<8)+cipherIn[0]; + + ruleB1(cv,1,w); + ruleA1(cv,1,w); + ruleB1(cv,0,w); + ruleA1(cv,0,w); + + /* final byte swap */ + plainOut[0] = w[4] & 0xff; + plainOut[1] = (w[4] >> 8) & 0xff; + plainOut[2] = w[3] & 0xff; + plainOut[3] = (w[3] >> 8) & 0xff; + plainOut[4] = w[2] & 0xff; + plainOut[5] = (w[2] >> 8) & 0xff; + plainOut[6] = w[1] & 0xff; + plainOut[7] = (w[1] >> 8) & 0xff; + return; +} + +static void +fort_doskipE(fort_keysched cv,unsigned char *cipherIn, + unsigned char *plainOut) { + unsigned int w[5]; /* ignore w[0] so the code matches the doc */ + + /* initial byte swap */ + w[1]=(cipherIn[7]<<8)+cipherIn[6]; + w[2]=(cipherIn[5]<<8)+cipherIn[4]; + w[3]=(cipherIn[3]<<8)+cipherIn[2]; + w[4]=(cipherIn[1]<<8)+cipherIn[0]; + + ruleA(cv,0,w); + ruleB(cv,0,w); + ruleA(cv,1,w); + ruleB(cv,1,w); + + /* final byte swap */ + plainOut[0] = w[4] & 0xff; + plainOut[1] = (w[4] >> 8) & 0xff; + plainOut[2] = w[3] & 0xff; + plainOut[3] = (w[3] >> 8) & 0xff; + plainOut[4] = w[2] & 0xff; + plainOut[5] = (w[2] >> 8) & 0xff; + plainOut[6] = w[1] & 0xff; + plainOut[7] = (w[1] >> 8) & 0xff; + return; +} + +/* Checksums are calculated by encrypted a fixed string with the key, then + * taking 16 bytes of the result from the block */ +static int +fort_CalcKeyChecksum(FORTSkipjackKeyPtr key, unsigned char *sum) { + unsigned char ckdata[8] = { + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }; + unsigned char ckres[8]; + fort_keysched keysched; + + + fort_skipKeySchedule(key,keysched); + + fort_doskipE(keysched,ckdata,ckres); + fort_clearShedule(keysched); + PORT_Memcpy(sum,&ckres[1],2); + return CI_OK; +} + +/* These function actually implements skipjack CBC Decrypt */ +int +fort_skipjackDecrypt(FORTSkipjackKeyPtr key, unsigned char *iv, + unsigned long size, unsigned char *cipherIn, + unsigned char *plainOut) { + unsigned char ivdata1[SKIPJACK_BLOCK_SIZE]; + unsigned char ivdata2[SKIPJACK_BLOCK_SIZE]; + unsigned char *lastiv, *nextiv, *tmpiv; + fort_keysched keysched; + + /* do the key schedule work once for efficency */ + fort_skipKeySchedule(key,keysched); + + /* As we decrypt, we need to save the last block so that we can + * Xor it out of decrypted text to get the real plain text. We actually + * have to save it because cipherIn and plainOut may point to the same + * buffer. */ + lastiv =ivdata1; + nextiv = ivdata2; + PORT_Memcpy(lastiv,iv,SKIPJACK_BLOCK_SIZE); + while (size >= SKIPJACK_BLOCK_SIZE) { + /* save the IV for the next block */ + PORT_Memcpy(nextiv,cipherIn,SKIPJACK_BLOCK_SIZE); + fort_doskipD(keysched,cipherIn,plainOut); + /* xor out the last IV */ + fort_XorIV(plainOut,plainOut,lastiv); + + /* swap the IV buffers */ + tmpiv = lastiv; + lastiv = nextiv; + nextiv =tmpiv; + + /* increment the loop pointers... be sure to get the input, output, + * and size (decrement) each fortdoskipD operates on an entire block*/ + cipherIn += SKIPJACK_BLOCK_SIZE; + plainOut += SKIPJACK_BLOCK_SIZE; + size -= SKIPJACK_BLOCK_SIZE; + } + fort_clearShedule(keysched); /* don't leave the key lying around the stack*/ + if (size != 0) return CI_INV_SIZE; + return CI_OK; +} + +/* These function actually implements skipjack CBC Encrypt */ +int +fort_skipjackEncrypt(FORTSkipjackKeyPtr key, unsigned char *iv, + unsigned long size, unsigned char *plainIn, + unsigned char *cipherOut) { + unsigned char *tmpiv; + fort_keysched keysched; + unsigned char plain[SKIPJACK_BLOCK_SIZE]; + + fort_skipKeySchedule(key,keysched); + tmpiv = iv; + while (size >= SKIPJACK_BLOCK_SIZE) { + /* We Xor into a temp buffer because we don't want to modify plainIn, + * doing so may make the caller very unhappy:). */ + fort_XorIV(plain,plainIn,tmpiv); + fort_doskipE(keysched,plain,cipherOut); + tmpiv = cipherOut; + cipherOut += SKIPJACK_BLOCK_SIZE; + plainIn += SKIPJACK_BLOCK_SIZE; + size -= SKIPJACK_BLOCK_SIZE; + } + fort_clearShedule(keysched); /* don't leave the key lying around the stack*/ + if (size != 0) return CI_INV_SIZE; + return CI_OK; +} + + + +/* + * unwrap is used for key generation and mixing + */ +int +fort_skipjackUnwrap(FORTSkipjackKeyPtr key,unsigned long len, + unsigned char *cipherIn, unsigned char *plainOut) { + unsigned char low[10]; + fort_keysched keysched; + int i,ret; + + /* unwrap can only unwrap 80 bit symetric keys and 160 private keys + * sometimes these values have checksums. When they do, we should verify + * those checksums. */ + switch (len) { + case 20: /* private key */ + case 24: /* private key with checksum */ + ret = fort_skipjackUnwrap(key,len/2,cipherIn,plainOut); + if (ret != CI_OK) return ret; + ret = fort_skipjackUnwrap(key,len/2,&cipherIn[len/2],low); + + /* unmunge the low word */ + for (i=0; i < 10; i++) { + low[i] = low[i] ^ plainOut[i]; + } + + /* the unwrap will fail above because the checkword is on + * low, not low ^ high. + */ + if (ret == CI_CHECKWORD_FAIL) { + unsigned char checksum[2]; + + ret = fort_CalcKeyChecksum(low,checksum); + if (ret != CI_OK) return ret; + if (PORT_Memcmp(checksum,&cipherIn[len-2],2) != 0) { + return CI_CHECKWORD_FAIL; + } + } + if (ret != CI_OK) return ret; + + /* re-order the low word */ + PORT_Memcpy(&plainOut[10],&low[8],2); + PORT_Memcpy(&plainOut[12],&low[0],8); + return CI_OK; + case 10: /* 80 bit skipjack key */ + case 12: /* 80 bit skipjack key with checksum */ + fort_skipKeySchedule(key,keysched); + fort_doskipD(keysched,cipherIn,plainOut); + plainOut[8] = cipherIn[8] ^ plainOut[0]; + plainOut[9] = cipherIn[9] ^ plainOut[1]; + fort_doskipD(keysched,plainOut,plainOut); + fort_clearShedule(keysched); + /* if we have a checkum, verify it */ + if (len == 12) { + unsigned char checksum[2]; + + ret = fort_CalcKeyChecksum(plainOut,checksum); + if (ret != CI_OK) return ret; + if (PORT_Memcmp(checksum,&cipherIn[10],2) != 0) { + return CI_CHECKWORD_FAIL; + } + } + return CI_OK; + default: + break; + } + return CI_INV_SIZE; +} + +/* + * unwrap is used for key generation and mixing + */ +int +fort_skipjackWrap(FORTSkipjackKeyPtr key,unsigned long len, + unsigned char *plainIn, unsigned char *cipherOut) { + unsigned char low[10]; + unsigned char checksum[2]; + fort_keysched keysched; + int i,ret; + + + /* NOTE: length refers to the target in the case of wrap */ + /* Wrap can only Wrap 80 bit symetric keys and 160 private keys + * sometimes these values have checksums. When they do, we should verify + * those checksums. */ + switch (len) { + case 20: /* private key */ + case 24: /* private key with checksum */ + /* re-order the low word */ + PORT_Memcpy(&low[8],&plainIn[10],2); + PORT_Memcpy(&low[0],&plainIn[12],8); + if (len == 24) { + ret = fort_CalcKeyChecksum(low,checksum); + if (ret != CI_OK) return ret; + } + /* munge the low word */ + for (i=0; i < 10; i++) { + low[i] = low[i] ^ plainIn[i]; + } + ret = fort_skipjackWrap(key,len/2,plainIn,cipherOut); + ret = fort_skipjackWrap(key,len/2,low,&cipherOut[len/2]); + if (len == 24) { + PORT_Memcpy(&cipherOut[len - 2], checksum, sizeof(checksum)); + } + + return CI_OK; + case 10: /* 80 bit skipjack key */ + case 12: /* 80 bit skipjack key with checksum */ + + fort_skipKeySchedule(key,keysched); + fort_doskipE(keysched,plainIn,cipherOut); + cipherOut[8] = plainIn[8] ^ cipherOut[0]; + cipherOut[9] = plainIn[9] ^ cipherOut[1]; + fort_doskipE(keysched,cipherOut,cipherOut); + fort_clearShedule(keysched); + /* if we need a checkum, get it */ + if (len == 12) { + ret = fort_CalcKeyChecksum(plainIn,&cipherOut[10]); + if (ret != CI_OK) return ret; + } + return CI_OK; + default: + break; + } + return CI_INV_SIZE; +} + diff --git a/security/nss/lib/fortcrypt/swfort/swflib.c b/security/nss/lib/fortcrypt/swfort/swflib.c new file mode 100644 index 000000000..a6465ff3f --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swflib.c @@ -0,0 +1,1031 @@ +/* ***** 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 ***** */ +/* + * implement the MACI calls as Software Fortezza Calls. + * only do the ones Nescape Needs. This provides a single software slot, + * with 100 key registers, and 50 backup Ra private registers. Since we only + * create one session per slot, this implementation only uses one session. + * One future enhancement may be to try to improve on this for better threading + * support. + */ + +#include "prtypes.h" +#include "prio.h" + +#include "swforti.h" +/*#include "keytlow.h"*/ +/* #include "dh.h" */ +#include "blapi.h" +#include "maci.h" +/* #include "dsa.h" */ +/* #include "hasht.h" */ +#include "secitem.h" +#include "secrng.h" +/*#include "keylow.h" */ +#include "secder.h" + +#if defined(XP_UNIX) || defined(XP_BEOS) +#include <unistd.h> +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + + +/* currently we only support one software token. In the future we can use the + * session to determin which of many possible tokens we are talking about. + * all the calls which need tokens take a pointer to the software token as a + * target. + */ +static FORTSWToken *swtoken = NULL; + +#define SOCKET_ID 1 + + +/* can't change the pin on SW fortezza for now */ +int +MACI_ChangePIN(HSESSION session, int PINType, CI_PIN CI_FAR pOldPIN, + CI_PIN CI_FAR pNewPin) +{ + return CI_INV_STATE; +} + + +/* + * Check pin checks the pin, then logs the user in or out depending on if + * the pin succedes. The General implementation would support both SSO and + * User mode our's only needs User mode. Pins are checked by whether or not + * they can produce our valid Ks for this 'card'. + */ +int +MACI_CheckPIN(HSESSION session, int PINType, CI_PIN CI_FAR pin) +{ + FORTSkipjackKeyPtr Ks; + FORTSWFile *config_file = NULL; + FORTSkipjackKey seed; + unsigned char pinArea[13]; + unsigned char *padPin = NULL; + + /* This SW module can only log in as USER */ + if (PINType != CI_USER_PIN) return CI_INV_TYPE; + + if (swtoken == NULL) return CI_NO_CARD; + /* we can't check a pin if we haven't been initialized yet */ + if (swtoken->config_file == NULL) return CI_NO_CARD; + config_file = swtoken->config_file; + + /* Make sure the pin value meets minimum lengths */ + if (PORT_Strlen((char *)pin) < 12) { + PORT_Memset(pinArea, ' ', sizeof(pinArea)); + PORT_Memcpy(pinArea,pin,PORT_Strlen((char *)pin)); + pinArea[12] = 0; + padPin = pinArea; + } + + /* get the Ks by unwrapping it from the memphrase with the pbe generated + * from the pin */ + Ks = fort_CalculateKMemPhrase(config_file, + &config_file->fortezzaPhrase, (char *)pin, NULL); + + if (Ks == 0) { + Ks = fort_CalculateKMemPhrase(config_file, + &config_file->fortezzaPhrase, (char *)padPin, NULL); + if (Ks == 0) { + PORT_Memset(pinArea, 0, sizeof(pinArea)); + fort_Logout(swtoken); + return CI_FAIL; + } + } + + /* use Ks and hash to verify that pin is correct */ + if (! fort_CheckMemPhrase(config_file, &config_file->fortezzaPhrase, + (char *)pin, Ks) ) { + if ((padPin == NULL) || + ! fort_CheckMemPhrase(config_file, &config_file->fortezzaPhrase, + (char *)padPin, Ks) ) { + PORT_Memset(pinArea, 0, sizeof(pinArea)); + fort_Logout(swtoken); + return CI_FAIL; + } + } + + PORT_Memset(pinArea, 0, sizeof(pinArea)); + + + /* OK, add the random Seed value into the random number generator */ + fort_skipjackUnwrap(Ks,config_file->wrappedRandomSeed.len, + config_file->wrappedRandomSeed.data,seed); + RNG_RandomUpdate(seed,sizeof(seed)); + + /* it is, go ahead and log in */ + swtoken->login = PR_TRUE; + /* Ks is always stored in keyReg[0] when we log in */ + PORT_Memcpy(swtoken->keyReg[0].data, Ks, sizeof (FORTSkipjackKey)); + swtoken->keyReg[0].present = PR_TRUE; + PORT_Memset(Ks, 0, sizeof(FORTSkipjackKey)); + PORT_Free(Ks); + + + return CI_OK; +} + +/* + * close an open socket. Power_Down flag is set when we want to reset the + * cards complete state. + */ +int +MACI_Close(HSESSION session, unsigned int flags, int socket) +{ + if (socket != SOCKET_ID) return CI_BAD_CARD; + if (swtoken == NULL) return CI_BAD_CARD; + + if (flags == CI_POWER_DOWN_FLAG) { + fort_Logout(swtoken); + } + return CI_OK; +} + +/* + * Decrypt keeps track of it's own IV. + */ +int +MACI_Decrypt(HSESSION session, unsigned int size, CI_DATA cipherIn, + CI_DATA plainOut) +{ + int ret; + unsigned char IV[SKIPJACK_BLOCK_SIZE]; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,swtoken->key,PR_TRUE)) != CI_OK) return ret; + + /*fort_AddNoise();*/ + + /* save the IV, before we potentially trash the new one when we decrypt. + * (it's permissible to decrypt into the cipher text buffer by passing the + * same buffers for both cipherIn and plainOut. + */ + PORT_Memcpy(IV,swtoken->IV, sizeof(IV)); + fort_UpdateIV(cipherIn,size,swtoken->IV); + return fort_skipjackDecrypt(swtoken->keyReg[swtoken->key].data, + IV,size,cipherIn,plainOut); +} + +/* + * Clear a key from one of the key registers (indicated by index). + * return an error if no key exists. + */ +int +MACI_DeleteKey(HSESSION session, int index) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + + /* can't delete Ks */ + if (index == 0) return CI_INV_KEY_INDEX; + + if ((ret = fort_KeyOK(swtoken,index,PR_TRUE)) != CI_OK) return ret; + fort_ClearKey(&swtoken->keyReg[index]); + return CI_OK; +} + + +/* + * encrypt some blocks of data and update the IV. + */ +int +MACI_Encrypt(HSESSION session, unsigned int size, CI_DATA plainIn, + CI_DATA cipherOut) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,swtoken->key,PR_TRUE)) != CI_OK) return ret; + + /*fort_AddNoise();*/ + + ret = fort_skipjackEncrypt(swtoken->keyReg[swtoken->key].data, + swtoken->IV,size,plainIn,cipherOut); + fort_UpdateIV(cipherOut,size,swtoken->IV); + + return ret; + +} + +/* + * create a new IV and encode it. + */ + +static char *leafbits="THIS IS NOT LEAF"; + +int +MACI_GenerateIV(HSESSION Session, CI_IV CI_FAR pIV) +{ + int ret; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,swtoken->key,PR_TRUE)) != CI_OK) return ret; + + ret = fort_GenerateRandom(swtoken->IV,SKIPJACK_BLOCK_SIZE); + if (ret != CI_OK) return ret; + + PORT_Memcpy(pIV,leafbits,SKIPJACK_LEAF_SIZE); + PORT_Memcpy(&pIV[SKIPJACK_LEAF_SIZE],swtoken->IV,SKIPJACK_BLOCK_SIZE); + + return CI_OK; +} + + +/* + * create a new Key + */ +int +MACI_GenerateMEK(HSESSION session, int index, int reserved) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,index,PR_FALSE)) != CI_OK) return ret; + + ret = fort_GenerateRandom(swtoken->keyReg[index].data, + sizeof (swtoken->keyReg[index].data)); + if (ret == CI_OK) swtoken->keyReg[index].present = PR_TRUE; + + return ret; +} + +/* + * build a new Ra/ra pair for a KEA exchange. + */ +int +MACI_GenerateRa(HSESSION session, CI_RA CI_FAR pRa) +{ + int ret; + int counter; + int RaLen,raLen; + DSAPrivateKey *privKey = NULL; + PQGParams params; + SECStatus rv; + int crv = CI_EXEC_FAIL; + fortSlotEntry *certEntry = NULL; + unsigned char *unsignedRa = NULL; + unsigned char *unsignedra = NULL; + fortKeyInformation *key_info = NULL; + + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + /* make sure the personality is set */ + if (swtoken->certIndex == 0) return CI_INV_STATE; + + /* pick next Ra circular buffer */ + counter = swtoken->nextRa; + swtoken->nextRa++; + if (swtoken->nextRa >= MAX_RA_SLOTS) swtoken->nextRa = 0; + + /* now get the params for diffie -helman key gen */ + certEntry = fort_GetCertEntry(swtoken->config_file,swtoken->certIndex); + if (certEntry == NULL) return CI_INV_CERT_INDEX; + if (certEntry->exchangeKeyInformation) { + key_info = certEntry->exchangeKeyInformation; + } else { + key_info = certEntry->signatureKeyInformation; + } + if (key_info == NULL) return CI_NO_X; + + /* Generate Diffie Helman key Pair -- but we use DSA key gen to do it */ + rv = SECITEM_CopyItem(NULL,¶ms.prime,&key_info->p); + if (rv != SECSuccess) return CI_EXEC_FAIL; + rv = SECITEM_CopyItem(NULL,¶ms.subPrime,&key_info->q); + if (rv != SECSuccess) return CI_EXEC_FAIL; + rv = SECITEM_CopyItem(NULL,¶ms.base,&key_info->g); + if (rv != SECSuccess) return CI_EXEC_FAIL; + + /* KEA uses DSA like key generation with short DSA keys that have to + * maintain a relationship to q */ + rv = DSA_NewKey(¶ms, &privKey); + SECITEM_FreeItem(¶ms.prime,PR_FALSE); + SECITEM_FreeItem(¶ms.subPrime,PR_FALSE); + SECITEM_FreeItem(¶ms.base,PR_FALSE); + if (rv != SECSuccess) return CI_EXEC_FAIL; + + /* save private key, public key, and param in Ra Circular buffer */ + unsignedRa = privKey->publicValue.data; + RaLen = privKey->publicValue.len; + while ((unsignedRa[0] == 0) && (RaLen > CI_RA_SIZE)) { + unsignedRa++; + RaLen--; + } + if (RaLen > CI_RA_SIZE) goto loser; + + unsignedra = privKey->privateValue.data; + raLen = privKey->privateValue.len; + while ((unsignedra[0] == 0) && (raLen > sizeof(fortRaPrivate))) { + unsignedra++; + raLen--; + } + + if (raLen > sizeof(fortRaPrivate)) goto loser; + + PORT_Memset(swtoken->RaValues[counter].private, 0, sizeof(fortRaPrivate)); + PORT_Memcpy( + &swtoken->RaValues[counter].private[sizeof(fortRaPrivate) - raLen], + unsignedra, raLen); + PORT_Memset(pRa, 0, CI_RA_SIZE); + PORT_Memcpy(&pRa[CI_RA_SIZE-RaLen], unsignedRa, RaLen); + PORT_Memcpy(swtoken->RaValues[counter].public, pRa, CI_RA_SIZE); + crv = CI_OK; + +loser: + PORT_FreeArena(privKey->params.arena, PR_TRUE); + + return crv; +} + + +/* + * return some random data. + */ +int +MACI_GenerateRandom(HSESSION session, CI_RANDOM CI_FAR random) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret; + return fort_GenerateRandom(random,sizeof (CI_RANDOM)); +} + + +static CI_RA Remail = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 +}; + +/* + * build a new Token exchange key using KEA. + */ +int +MACI_GenerateTEK(HSESSION hSession, int flags, int target, + CI_RA CI_FAR Ra, CI_RA CI_FAR Rb, unsigned int YSize, CI_Y CI_FAR pY ) +{ + FORTEZZAPrivateKey *key = NULL; + fortSlotEntry * certEntry; + unsigned char * w = NULL; + SECItem *q; + SECStatus rv; + int ret,i; + PRBool email = PR_TRUE; + SECItem R; /* public */ + SECItem Y; /* public */ + SECItem r; /* private */ + SECItem x; /* private */ + SECItem wItem; /* derived secret */ + fortRaPrivatePtr ra; + FORTSkipjackKey cover_key; + + unsigned char pad[10] = { 0x72, 0xf1, 0xa8, 0x7e, 0x92, + 0x82, 0x41, 0x98, 0xab, 0x0b }; + + /* verify that everything is ok with the token, keys and certs */ + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + /* make sure the personality is set */ + if (swtoken->certIndex == 0) return CI_INV_STATE; + if ((ret = fort_KeyOK(swtoken,target,PR_FALSE)) != CI_OK) return ret; + + /* get the cert from the entry, then look up the key from that cert */ + certEntry = fort_GetCertEntry(swtoken->config_file,swtoken->certIndex); + if (certEntry == NULL) return CI_INV_CERT_INDEX; + key = fort_GetPrivKey(swtoken,fortezzaDHKey,certEntry); + if (key == NULL) return CI_NO_X; + + if (certEntry->exchangeKeyInformation) { + q = &certEntry->exchangeKeyInformation->q; + } else { + q = &certEntry->signatureKeyInformation->q; + } + + email = (PORT_Memcmp(Rb,Remail,sizeof(Rb)) == 0) ? PR_TRUE: PR_FALSE; + + + /* load the common elements */ + Y.data = pY; + Y.len = YSize; + x.data = key->u.dh.privateValue.data; + x.len = key->u.dh.privateValue.len; + + /* now initialize the rest of the values */ + if (flags == CI_INITIATOR_FLAG) { + if (email) { + R.data = Y.data; + R.len = Y.len; + } else { + R.data = Rb; + R.len = sizeof(CI_RA); + } + ra = fort_LookupPrivR(swtoken,Ra); + if (ra == NULL) { + ret = CI_EXEC_FAIL; + goto loser; + } + r.data = ra; + r.len = sizeof(fortRaPrivate); + } else { + R.data = Ra; + R.len = sizeof(CI_RA); + if (email) { + r.data = x.data; + r.len = x.len; + } else { + ra = fort_LookupPrivR(swtoken,Rb); + if (ra == NULL) { + ret = CI_EXEC_FAIL; + goto loser; + } + r.data = ra; + r.len = sizeof(fortRaPrivate); + } + } + + + if (!KEA_Verify(&Y,&key->u.dh.prime,q)) { + ret = CI_EXEC_FAIL; + goto loser; + } + if (!KEA_Verify(&R,&key->u.dh.prime,q)) { + ret = CI_EXEC_FAIL; + goto loser; + } + + /* calculate the base key */ + rv = KEA_Derive(&key->u.dh.prime, &Y, &R, &r, &x, &wItem); + if (rv != SECSuccess) { + ret = CI_EXEC_FAIL; + goto loser; + } + + w = wItem.data; + /* use the skipjack wrapping function to 'mix' the key up */ + for (i=0; i < sizeof(FORTSkipjackKey); i++) + cover_key[i] = pad[i] ^ w[i]; + + ret = fort_skipjackWrap(cover_key,sizeof(FORTSkipjackKey), + &w[sizeof(FORTSkipjackKey)],swtoken->keyReg[target].data); + if (ret != CI_OK) goto loser; + + swtoken->keyReg[target].present = PR_TRUE; + + ret = CI_OK; +loser: + if (w) PORT_Free(w); + if (key) fort_DestroyPrivateKey(key); + + return ret; +} + + +/* + * return the bytes of a certificate. + */ +int +MACI_GetCertificate(HSESSION hSession, int certIndex, + CI_CERTIFICATE CI_FAR cert) +{ + int len; + int ret; + fortSlotEntry *certEntry = NULL; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + + certEntry = fort_GetCertEntry(swtoken->config_file,certIndex); + if (certEntry == NULL) return CI_INV_CERT_INDEX; + + len = certEntry->certificateData.dataEncryptedWithKs.len; + PORT_Memset(cert,0,sizeof(CI_CERTIFICATE)); + PORT_Memcpy(cert, certEntry->certificateData.dataEncryptedWithKs.data,len); + + /* Ks is always stored in keyReg[0] when we log in */ + return fort_skipjackDecrypt(swtoken->keyReg[0].data, + &certEntry->certificateData.dataIV.data[SKIPJACK_LEAF_SIZE], + len,cert,cert); +} + + +/* + * return out sofware configuration bytes. Those field not used by the PKCS #11 + * module may not be filled in exactly. + */ +#define NETSCAPE "Netscape Communications Corp " +#define PRODUCT "Netscape Software FORTEZZA Lib " +#define SOFTWARE "Software FORTEZZA Implementation" + +int +MACI_GetConfiguration(HSESSION hSession, CI_CONFIG_PTR config) +{ + config->LibraryVersion = 0x0100; + config->ManufacturerVersion = 0x0100; + PORT_Memcpy(config->ManufacturerName,NETSCAPE,sizeof(NETSCAPE)); + PORT_Memcpy(config->ProductName,PRODUCT,sizeof(PRODUCT)); + PORT_Memcpy(config->ProcessorType,SOFTWARE,sizeof(SOFTWARE)); + config->UserRAMSize = 0; + config->LargestBlockSize = 0x10000; + config->KeyRegisterCount = KEY_REGISTERS; + config->CertificateCount = + swtoken ? fort_GetCertCount(swtoken->config_file): 0; + config->CryptoCardFlag = 0; + config->ICDVersion = 0; + config->ManufacturerSWVer = 0x0100; + config->DriverVersion = 0x0100; + return CI_OK; +} + +/* + * return a list of all the personalities (up to the value 'EntryCount') + */ +int +MACI_GetPersonalityList(HSESSION hSession, int EntryCount, + CI_PERSON CI_FAR personList[]) +{ + int count; + int i,ret; + FORTSWFile *config_file = NULL; + unsigned char tmp[32]; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + config_file = swtoken->config_file; + + /* search for the index */ + count= fort_GetCertCount(config_file); + + /* don't return more than the user asked for */ + if (count > EntryCount) count = EntryCount; + for (i=0; i < count ;i ++) { + int len, dataLen; + personList[i].CertificateIndex = + config_file->slotEntries[i]->certIndex; + len = config_file->slotEntries[i]->certificateLabel. + dataEncryptedWithKs.len; + if (len > sizeof(tmp)) len = sizeof(tmp); + PORT_Memset(personList[i].CertLabel, ' ', + sizeof(personList[i].CertLabel)); + PORT_Memcpy(tmp, + config_file->slotEntries[i]-> + certificateLabel.dataEncryptedWithKs.data, + len); + /* Ks is always stored in keyReg[0] when we log in */ + ret = fort_skipjackDecrypt(swtoken->keyReg[0].data, + &config_file->slotEntries[i]-> + certificateLabel.dataIV.data[SKIPJACK_LEAF_SIZE],len, + tmp,tmp); + if (ret != CI_OK) return ret; + dataLen = DER_GetInteger(&config_file->slotEntries[i]-> + certificateLabel.length); + if (dataLen > sizeof(tmp)) dataLen = sizeof(tmp); + PORT_Memcpy(personList[i].CertLabel, tmp, dataLen); + personList[i].CertLabel[32] = 0; + personList[i].CertLabel[33] = 0; + personList[i].CertLabel[34] = 0; + personList[i].CertLabel[35] = 0; + } + return CI_OK; +} + + +/* + * get a new session ID. This function is only to make the interface happy, + * the PKCS #11 module only uses one session per token. + */ +int +MACI_GetSessionID(HSESSION *session) +{ + *session = 1; + return CI_OK; +} + +/* + * return the current card state. + */ +int +MACI_GetState(HSESSION hSession, CI_STATE_PTR state) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret; + *state = fort_GetState(swtoken); + return CI_OK; +} + +/* + * return the status. NOTE that KeyRegisterFlags and CertificateFlags are never + * really used by the PKCS #11 module, so they are not implemented. + */ +int +MACI_GetStatus(HSESSION hSession, CI_STATUS_PTR status) +{ + int ret; + FORTSWFile *config_file = NULL; + + if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret; + config_file = swtoken->config_file; + status->CurrentSocket = 1; + status->LockState = swtoken->lock; + PORT_Memcpy(status->SerialNumber, + config_file->serialID.data, config_file->serialID.len); + status->CurrentState = fort_GetState(swtoken); + status->DecryptionMode = CI_CBC64_MODE; + status->EncryptionMode = CI_CBC64_MODE; + status->CurrentPersonality = swtoken->certIndex; + status->KeyRegisterCount = KEY_REGISTERS; + /* our code doesn't use KeyRegisters, which is good, because there's not + * enough of them .... */ + PORT_Memset(status->KeyRegisterFlags,0,sizeof(status->KeyRegisterFlags)); + status->CertificateCount = fort_GetCertCount(config_file); + PORT_Memset(status->CertificateFlags,0,sizeof(status->CertificateFlags)); + PORT_Memset(status->Flags,0,sizeof(status->Flags)); + + return CI_OK; +} + +/* + * add the time call because the PKCS #11 module calls it, but always pretend + * the clock is bad, so it never uses the returned time. + */ +int +MACI_GetTime(HSESSION hSession, CI_TIME CI_FAR time) +{ + return CI_BAD_CLOCK; +} + + +/* This function is copied from NSPR so that the PKCS #11 module can be + * independent of NSPR */ +PRInt32 local_getFileInfo(const char *fn, PRFileInfo *info); + +/* + * initialize the SW module, and return the number of slots we support (1). + */ +int +MACI_Initialize(int CI_FAR *count) +{ + char *filename = NULL; + SECItem file; + FORTSignedSWFile *decode_file = NULL; + PRFileInfo info; + /*PRFileDesc *fd = NULL;*/ + int fd = -1; + PRStatus err; + int ret = CI_OK; + int fcount; + + file.data = NULL; + file.len = 0; + + *count = 1; + + /* allocate swtoken structure */ + swtoken = PORT_ZNew(FORTSWToken); + if (swtoken == NULL) return CI_OUT_OF_MEMORY; + + filename = (char *)fort_LookupFORTEZZAInitFile(); + if (filename == NULL) { + ret = CI_BAD_READ; + goto failed; + } + + fd = open(filename,O_RDONLY|O_BINARY,0); + if (fd < 0) { + ret = CI_BAD_READ; + goto failed; + } + + err = local_getFileInfo(filename,&info); + if ((err != 0) || (info.size == 0)) { + ret = CI_BAD_READ; + goto failed; + } + + file.data = PORT_ZAlloc(info.size); + if (file.data == NULL) { + ret = CI_OUT_OF_MEMORY; + goto failed; + } + + fcount = read(fd,file.data,info.size); + close(fd); fd = -1; + if (fcount != (int)info.size) { + ret = CI_BAD_READ; + goto failed; + } + + file.len = fcount; + + decode_file = FORT_GetSWFile(&file); + if (decode_file == NULL) { + ret = CI_BAD_READ; + goto failed; + } + swtoken->config_file = &decode_file->file; + + RNG_SystemInfoForRNG(); + RNG_FileForRNG(filename); + + +failed: + if (filename) PORT_Free(filename); + if (fd != -1) close(fd); + if (file.data) PORT_Free(file.data); + if (ret != CI_OK) { + if (decode_file) FORT_DestroySignedSWFile(decode_file); + if (swtoken) PORT_Free(swtoken); + swtoken = NULL; + } + + return CI_OK; +} + +/* + * load an IV from an external source. We technically should check it with the + * key we received. + */ +int +MACI_LoadIV(HSESSION session, CI_IV CI_FAR iv) +{ + int ret; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + PORT_Memcpy(swtoken->IV,&iv[SKIPJACK_LEAF_SIZE],SKIPJACK_BLOCK_SIZE); + return CI_OK; +} + +/* implement token lock (should call PR_Monitor here) */ +int +MACI_Lock(HSESSION session, int flags) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + swtoken->lock = 1; + + return CI_OK; +} + +/* open a token. For software there isn't much to do that hasn't already been + * done by initialize. */ +int +MACI_Open(HSESSION session, unsigned int flags, int socket) +{ + if (socket != SOCKET_ID) return CI_NO_CARD; + if (swtoken == NULL) return CI_NO_CARD; + return CI_OK; +} + +/* + * Reset logs out the token... + */ +int +MACI_Reset(HSESSION session) +{ + if (swtoken) fort_Logout(swtoken); + return CI_OK; +} + +/* + * restore and encrypt/decrypt state. NOTE: there is no error checking in this + * or the save function. + */ +int +MACI_Restore(HSESSION session, int type, CI_SAVE_DATA CI_FAR data) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + PORT_Memcpy(swtoken->IV,data, sizeof (swtoken->IV)); + return CI_OK; +} + +/* + * save and encrypt/decrypt state. NOTE: there is no error checking in this + * or the restore function. + */ +int +MACI_Save(HSESSION session, int type,CI_SAVE_DATA CI_FAR data) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + PORT_Memcpy(data,swtoken->IV, sizeof (swtoken->IV)); + return CI_OK; +} + +/* + * picks a token to operate against. In our case there can be only one. + */ +int +MACI_Select(HSESSION session, int socket) +{ + if (socket == SOCKET_ID) return CKR_OK; + return CI_NO_CARD; +} + +/* + * set a register as the key to use for encrypt/decrypt operations. + */ +int +MACI_SetKey(HSESSION session, int index) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,index,PR_TRUE)) != CI_OK) return ret; + + swtoken->key = index; + return CI_OK; +} + +/* + * only CBC64 is supported. Keep setmode for compatibility */ +int +MACI_SetMode(HSESSION session, int type, int mode) +{ + if (mode != CI_CBC64_MODE) return CI_INV_MODE; + return CI_OK; +} + +/* set the personality to use for sign/verify */ +int +MACI_SetPersonality(HSESSION session, int cert) +{ + int ret; + fortSlotEntry *certEntry = NULL; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + + certEntry = fort_GetCertEntry(swtoken->config_file,cert); + if ((certEntry == NULL) || + ((certEntry->exchangeKeyInformation == NULL) && + (certEntry->signatureKeyInformation == NULL)) ) + return CI_INV_CERT_INDEX; + swtoken->certIndex = cert; + return CI_OK; +} + + +/* DSA sign some data */ +int +MACI_Sign(HSESSION session, CI_HASHVALUE CI_FAR hash, CI_SIGNATURE CI_FAR sig) +{ + FORTEZZAPrivateKey *key = NULL; + fortSlotEntry * certEntry = NULL; + int ret = CI_OK; + SECStatus rv; + SECItem signItem; + SECItem hashItem; + unsigned char random[DSA_SUBPRIME_LEN]; + + /* standard checks */ + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + /* make sure the personality is set */ + if (swtoken->certIndex == 0) return CI_INV_STATE; + + /* get the current personality */ + certEntry = fort_GetCertEntry(swtoken->config_file,swtoken->certIndex); + if (certEntry == NULL) return CI_INV_CERT_INDEX; + + /* extract the private key from the personality */ + ret = CI_OK; + key = fort_GetPrivKey(swtoken,fortezzaDSAKey,certEntry); + if (key == NULL) { + ret = CI_NO_X; + goto loser; + } + + /* create a random value for the signature */ + ret = fort_GenerateRandom(random, sizeof(random)); + if (ret != CI_OK) goto loser; + + /* Sign with that private key */ + signItem.data = sig; + signItem.len = DSA_SIGNATURE_LEN; + + hashItem.data = hash; + hashItem.len = SHA1_LENGTH; + + rv = DSA_SignDigestWithSeed(&key->u.dsa, &signItem, &hashItem, random); + if (rv != SECSuccess) { + ret = CI_EXEC_FAIL; + } + + /* clean up */ +loser: + if (key != NULL) fort_DestroyPrivateKey(key); + + return ret; +} + +/* + * clean up after ourselves. + */ +int +MACI_Terminate(HSESSION session) +{ + if (swtoken == NULL) return CI_OUT_OF_MEMORY; + + /* clear all the keys */ + fort_Logout(swtoken); + + FORT_DestroySWFile(swtoken->config_file); + PORT_Free(swtoken); + swtoken = NULL; + return CI_OK; +} + + + +/* implement token unlock (should call PR_Monitor here) */ +int +MACI_Unlock(HSESSION session) +{ + int ret; + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + swtoken->lock = 0; + return CI_OK; +} + +/* + * unwrap a key into our software token. NOTE: this function does not + * verify that the wrapping key is Ks or a TEK. This is because our higher + * level software doesn't try to wrap MEKs with MEKs. If this API was exposed + * generically, then we would have to worry about things like this. + */ +int +MACI_UnwrapKey(HSESSION session, int wrapKey, int target, + CI_KEY CI_FAR keyData) +{ + int ret = CI_OK; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,target,PR_FALSE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,wrapKey,PR_TRUE)) != CI_OK) return ret; + ret = fort_skipjackUnwrap(swtoken->keyReg[wrapKey].data, + sizeof(CI_KEY), keyData, swtoken->keyReg[target].data); + if (ret != CI_OK) goto loser; + + swtoken->keyReg[target].present = PR_TRUE; + +loser: + return ret; +} + +/* + * Wrap a key out of our software token. NOTE: this function does not + * verify that the wrapping key is Ks or a TEK, or that the source key is + * a MEK. This is because our higher level software doesn't try to wrap MEKs + * with MEKs, or wrap out TEKS and Ks. If this API was exposed + * generically, then we would have to worry about things like this. + */ +int +MACI_WrapKey(HSESSION session, int wrapKey, int source, CI_KEY CI_FAR keyData) +{ + int ret; + + if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,source,PR_TRUE)) != CI_OK) return ret; + if ((ret = fort_KeyOK(swtoken,wrapKey,PR_TRUE)) != CI_OK) return ret; + ret = fort_skipjackWrap(swtoken->keyReg[wrapKey].data, + sizeof(CI_KEY), swtoken->keyReg[source].data,keyData); + + return ret; +} + diff --git a/security/nss/lib/fortcrypt/swfort/swfort.h b/security/nss/lib/fortcrypt/swfort/swfort.h new file mode 100644 index 000000000..0d040dd3d --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfort.h @@ -0,0 +1,73 @@ +/* ***** 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 ***** */ +/* + * Software implementation of FORTEZZA skipjack primatives + */ +#ifndef _SWFORT_H_ +#define _SWFORT_H_ + +#include "seccomon.h" +#include "swfortt.h" +/*#include "genci.h"*/ + + +SEC_BEGIN_PROTOS + +FORTSignedSWFile * +FORT_GetSWFile(SECItem *initBits); + +SECStatus +FORT_CheckInitPhrase(FORTSignedSWFile *sw_init_file, char *initMemPhrase); + +SECStatus +FORT_CheckUserPhrase(FORTSignedSWFile *sw_init_file, char *userMemPhrase); + +void +FORT_DestroySWFile(FORTSWFile *file); + +void +FORT_DestroySignedSWFile(FORTSignedSWFile *swfile); + +SECItem * +FORT_GetDERCert(FORTSignedSWFile *swfile, int index); + +SECItem * +FORT_PutSWFile(FORTSignedSWFile *sw_init_file); + + +SEC_END_PROTOS + +#endif diff --git a/security/nss/lib/fortcrypt/swfort/swforti.h b/security/nss/lib/fortcrypt/swfort/swforti.h new file mode 100644 index 000000000..36763d0a5 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swforti.h @@ -0,0 +1,180 @@ +/* ***** 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 ***** */ +/* + * Software implementation of FORTEZZA Skipjack primatives and helper functions. + */ +#ifndef _SWFORTI_H_ +#define _SWFORTI_H_ + +#ifndef RETURN_TYPE +#define RETURN_TYPE int +#endif + +#include "seccomon.h" +#include "swfort.h" +#include "swfortti.h" +#include "maci.h" + + +SEC_BEGIN_PROTOS +/* + * Check to see if the index is ok, and that key is appropriately present or + * absent. + */ +int fort_KeyOK(FORTSWToken *token, int index, PRBool isPresent); + +/* + * clear out a key register + */ +void fort_ClearKey(FORTKeySlot *key); + +/* + * clear out an Ra register + */ +void fort_ClearRaSlot(FORTRaRegisters *ra); + +/* + * provide a helper function to do all the loggin out functions. + * NOTE: Logging in only happens in MACI_CheckPIN + */ +void fort_Logout(FORTSWToken *token); + +/* + * update the new IV value based on the current cipherText (should be the last + * block of the cipher text). + */ +int fort_UpdateIV(unsigned char *cipherText, unsigned int size,unsigned char *IV); + + +/* + * verify that we have a card initialized, and if necessary, logged in. + */ +int fort_CardExists(FORTSWToken *token,PRBool needLogin); + +/* + * walk down the cert slot entries, counting them. + * return that count. + */ +int fort_GetCertCount(FORTSWFile *file); + +/* + * copy an unsigned SECItem to a signed SecItem. (if the high bit is on, + * pad with a leading 0. + */ +SECStatus fort_CopyUnsigned(PRArenaPool *arena, SECItem *to, const SECItem *from); + +/* + * return the private key based on the token and entry. + */ +FORTEZZAPrivateKey *fort_GetPrivKey(FORTSWToken *token,FORTEZZAKeyType keyType,fortSlotEntry *certEntry); + +/* + * Free the key acquired above. + */ +void fort_DestroyPrivateKey(FORTEZZAPrivateKey *key); + +/* + * find a particulare certificate entry from the config + * file. + */ +fortSlotEntry * fort_GetCertEntry(FORTSWFile *file,int index); + +/* + * use the token to termine it's CI_State. + */ +CI_STATE fort_GetState(FORTSWToken *token); + +/* + * find the private ra value for a given public Ra value. + */ +fortRaPrivatePtr fort_LookupPrivR(FORTSWToken *token,CI_RA Ra); + +/* + * go add more noise to the random number generator + */ +void fort_AddNoise(void); + +/* + * Get a random number + */ +int fort_GenerateRandom(unsigned char *buf, int bytes); + + +/* + * We're deep in the bottom of MACI and PKCS #11... We need to + * find our fortezza key file. This function lets us search manual paths to + * find our key file. + */ +char *fort_FindFileInPath(char *path, char *fn); + + +char *fort_LookupFORTEZZAInitFile(void); + + +FORTSkipjackKeyPtr fort_CalculateKMemPhrase(FORTSWFile *file, + fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey); + + +PRBool fort_CheckMemPhrase(FORTSWFile *file, + fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey); + + +/* These function actually implements skipjack CBC64 Decrypt */ +int fort_skipjackDecrypt(FORTSkipjackKeyPtr key, unsigned char *iv, + unsigned long size, unsigned char *cipherIn, + unsigned char *plainOut); + +/* These function actually implements skipjack CBC64 Encrypt */ +int fort_skipjackEncrypt(FORTSkipjackKeyPtr key, unsigned char *iv, + unsigned long size, unsigned char *plainIn, + unsigned char *cipherOut); + +/* + * unwrap is used for key generation and mixing + */ +int fort_skipjackUnwrap(FORTSkipjackKeyPtr key,unsigned long len, + unsigned char *cipherIn, unsigned char *plainOut); + +/* + * unwrap is used for key generation and mixing + */ +int +fort_skipjackWrap(FORTSkipjackKeyPtr key,unsigned long len, + unsigned char *plainIn, unsigned char *cipherOut); + +SEC_END_PROTOS + +#endif diff --git a/security/nss/lib/fortcrypt/swfort/swfortt.h b/security/nss/lib/fortcrypt/swfort/swfortt.h new file mode 100644 index 000000000..daf4be462 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfortt.h @@ -0,0 +1,59 @@ +/* ***** 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 ***** */ +/* + * All the data structures for Software fortezza are internal only. + * The external API for Software fortezza is MACI (which is only used by + * the PKCS #11 module. + */ + +#ifndef _SWFORTT_H_ +#define _SWFORTT_H_ + +/* structure typedefs */ +typedef struct FORTKeySlotStr FORTKeySlot; +typedef struct FORTRaRegistersStr FORTRaRegisters; +typedef struct FORTSWTokenStr FORTSWToken; + +/* Der parsing typedefs */ +typedef struct fortKeyInformationStr fortKeyInformation; +typedef struct fortProtectedDataStr fortProtectedData; +typedef struct fortSlotEntryStr fortSlotEntry; +typedef struct fortProtectedPhraseStr fortProtectedPhrase; +typedef struct FORTSWFileStr FORTSWFile; +typedef struct FORTSignedSWFileStr FORTSignedSWFile; + + +#endif diff --git a/security/nss/lib/fortcrypt/swfort/swfortti.h b/security/nss/lib/fortcrypt/swfort/swfortti.h new file mode 100644 index 000000000..3317a932a --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfortti.h @@ -0,0 +1,179 @@ +/* ***** 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 ***** */ +/* + * All the data structures for Software fortezza are internal only. + * The external API for Software fortezza is MACI (which is only used by + * the PKCS #11 module. + */ + +#ifndef _SWFORTTI_H_ +#define _SWFORTTI_H_ + +#include "maci.h" +#include "seccomon.h" +#include "mcom_db.h" /* really should be included by certt.h */ +#include "certt.h" +/*#include "keyt.h"*/ +#include "blapit.h" +#include "swfortt.h" + + +typedef enum { + fortezzaDSAKey = 0, + fortezzaDHKey = 1 +} FORTEZZAKeyType; + +/* +** Low Level private key object +** This is only used by the raw Crypto engines (crypto), keydb (keydb), +** and PKCS #11. Everyone else uses the high level key structure. +*/ +struct FORTEZZAPrivateKeyStr { + PLArenaPool *arena; + FORTEZZAKeyType keyType; + union { + DSAPrivateKey dsa; + DHPrivateKey dh; + } u; +}; +typedef struct FORTEZZAPrivateKeyStr FORTEZZAPrivateKey; + + +/* the following parameters are tunable. The bigger the key registers are, + * the less likely the PKCS #11 module will thrash. */ +#define KEY_REGISTERS 100 +#define MAX_RA_SLOTS 20 + +/* SKIPJACK algorithm constants */ +#define SKIPJACK_KEY_SIZE 10 +#define SKIPJACK_BLOCK_SIZE 8 +#define SKIPJACK_LEAF_SIZE 16 + +/* private typedefs */ +typedef unsigned char FORTSkipjackKey[SKIPJACK_KEY_SIZE]; +typedef unsigned char *FORTSkipjackKeyPtr; +typedef unsigned char fortRaPrivate[20]; +typedef unsigned char *fortRaPrivatePtr; + +/* save a public/private key pair */ +struct FORTRaRegistersStr { + CI_RA public; + fortRaPrivate private; +}; + +/* FORTEZZA Key Register */ +struct FORTKeySlotStr { + FORTSkipjackKey data; + PRBool present; +}; + +/* structure to hole private key information */ +struct fortKeyInformationStr { + SECItem keyFlags; + SECItem privateKeyWrappedWithKs; + SECItem derPublicKey; + SECItem p; + SECItem g; + SECItem q; +}; + +/* struture to hole Ks wrapped data */ +struct fortProtectedDataStr { + SECItem length; + SECItem dataIV; + SECItem dataEncryptedWithKs; +}; + +/* This structure represents a fortezza personality */ +struct fortSlotEntryStr { + SECItem trusted; + SECItem certificateIndex; + int certIndex; + fortProtectedData certificateLabel; + fortProtectedData certificateData; + fortKeyInformation *exchangeKeyInformation; + fortKeyInformation *signatureKeyInformation; +}; + +/* this structure represents a K value wrapped by a protected pin */ +struct fortProtectedPhraseStr { + SECItem kValueIV; + SECItem wrappedKValue; + SECItem memPhraseIV; + SECItem hashedEncryptedMemPhrase; +}; + + +/* This structure represents all the relevant data stored in a der encoded + * fortezza slot file. */ +struct FORTSWFileStr { + PRArenaPool *arena; + SECItem version; + SECItem derIssuer; + SECItem serialID; + fortProtectedPhrase initMemPhrase; +#define fortezzaPhrase initMemPhrase + fortProtectedPhrase ssoMemPhrase; + fortProtectedPhrase userMemPhrase; + fortProtectedPhrase ssoPinPhrase; + fortProtectedPhrase userPinPhrase; + SECItem wrappedRandomSeed; + fortSlotEntry **slotEntries; +}; + +/* This data structed represents a signed data structure */ +struct FORTSignedSWFileStr { + FORTSWFile file; + CERTSignedData signatureWrap; + FORTSkipjackKeyPtr Kinit; + FORTSkipjackKeyPtr Ks; +}; + + +/* collect all the data that makes up a token */ +struct FORTSWTokenStr { + PRBool login; /* has this token been logged in? */ + int lock; /* the current lock state */ + int certIndex; /* index of the current personality */ + int key; /* currently selected key */ + int nextRa; /* where the next Ra/ra pair will go */ + FORTSWFile *config_file; /* parsed Fortezza Config file */ + unsigned char IV[SKIPJACK_BLOCK_SIZE]; + FORTKeySlot keyReg[KEY_REGISTERS]; /* sw fortezza key slots */ + FORTRaRegisters RaValues[MAX_RA_SLOTS]; /* Ra/ra values */ +}; + +#endif diff --git a/security/nss/lib/fortcrypt/swfort/swfparse.c b/security/nss/lib/fortcrypt/swfort/swfparse.c new file mode 100644 index 000000000..d814004f4 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfparse.c @@ -0,0 +1,542 @@ +/* ***** 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 ***** */ +/* + * The following program decodes the FORTEZZA Init File, and stores the result + * into the fortezza directory. + */ +#include "secasn1.h" +#include "swforti.h" +#include "blapi.h" +#include "secoid.h" +#include "secitem.h" +#include "secder.h" + + +/* + * templates for parsing the FORTEZZA Init File. These were taken from DER + * definitions on SWF Initialization File Format Version 1.0 pp1-3. + */ + +/* Key info structure... There are up to two of these per slot entry */ +static const SEC_ASN1Template fortKeyInfoTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(fortKeyInformation) }, + { SEC_ASN1_INTEGER, + offsetof(fortKeyInformation,keyFlags) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortKeyInformation,privateKeyWrappedWithKs) }, + { SEC_ASN1_ANY , + offsetof(fortKeyInformation, derPublicKey) }, + { SEC_ASN1_OCTET_STRING, offsetof(fortKeyInformation,p) }, + { SEC_ASN1_OCTET_STRING, offsetof(fortKeyInformation,g) }, + { SEC_ASN1_OCTET_STRING, offsetof(fortKeyInformation,q) }, + { 0 } +}; + +/* This is data that has been wrapped by Ks */ +static const SEC_ASN1Template fortProtDataTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(fortProtectedData) }, + { SEC_ASN1_INTEGER, + offsetof(fortProtectedData,length) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedData,dataIV) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedData,dataEncryptedWithKs) }, + { 0 } +}; + +/* DER to describe each Certificate Slot ... there are an arbitrary number */ +static const SEC_ASN1Template fortSlotEntryTemplate[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(fortSlotEntry) }, + { SEC_ASN1_BOOLEAN, + offsetof(fortSlotEntry,trusted) }, + { SEC_ASN1_INTEGER, + offsetof(fortSlotEntry,certificateIndex) }, + { SEC_ASN1_INLINE, + offsetof(fortSlotEntry,certificateLabel), fortProtDataTemplate }, + { SEC_ASN1_INLINE, + offsetof(fortSlotEntry,certificateData), fortProtDataTemplate }, + { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | 0, + offsetof(fortSlotEntry, exchangeKeyInformation), + fortKeyInfoTemplate }, + { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_CONSTRUCTED | 1, + offsetof(fortSlotEntry, signatureKeyInformation), + fortKeyInfoTemplate }, + { 0 } +}; + +/* This data is used to check MemPhrases, and to generate Ks + * each file has two mem phrases, one for SSO, one for User */ +static const SEC_ASN1Template fortProtectedMemPhrase[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(fortProtectedPhrase) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedPhrase,kValueIV) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedPhrase,wrappedKValue) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedPhrase,memPhraseIV) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedPhrase,hashedEncryptedMemPhrase) }, + { 0 } +}; + +/* This data is used to check the Mem Init Phrases, and to generate Kinit + * each file has one mem init phrase, which is used only in transport of + * this file */ +static const SEC_ASN1Template fortMemInitPhrase[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(fortProtectedPhrase) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedPhrase,wrappedKValue) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedPhrase,memPhraseIV) }, + { SEC_ASN1_OCTET_STRING, + offsetof(fortProtectedPhrase,hashedEncryptedMemPhrase) }, + { 0 } +}; + +static const SEC_ASN1Template fortSlotEntriesTemplate[] = { + { SEC_ASN1_SEQUENCE_OF, 0, fortSlotEntryTemplate } +}; + +/* This is the complete file with all it's data, but has not been signed + * yet. */ +static const SEC_ASN1Template fortSwFortezzaInitFileToSign[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(FORTSWFile) }, + { SEC_ASN1_INTEGER, + offsetof(FORTSWFile,version) }, + { SEC_ASN1_ANY, + offsetof(FORTSWFile,derIssuer) }, + { SEC_ASN1_OCTET_STRING, + offsetof(FORTSWFile,serialID) }, + { SEC_ASN1_INLINE, + offsetof(FORTSWFile,initMemPhrase), fortMemInitPhrase }, + { SEC_ASN1_INLINE, + offsetof(FORTSWFile,ssoMemPhrase), fortProtectedMemPhrase }, + { SEC_ASN1_INLINE, + offsetof(FORTSWFile,userMemPhrase), fortProtectedMemPhrase }, + { SEC_ASN1_INLINE, + offsetof(FORTSWFile,ssoPinPhrase), fortProtectedMemPhrase }, + { SEC_ASN1_INLINE, + offsetof(FORTSWFile,userPinPhrase), fortProtectedMemPhrase }, + { SEC_ASN1_OCTET_STRING, + offsetof(FORTSWFile,wrappedRandomSeed) }, + { SEC_ASN1_SEQUENCE_OF, offsetof(FORTSWFile,slotEntries), + fortSlotEntryTemplate }, + /* optional extentions to ignore here... */ + { 0 } +}; + +/* The complete, signed init file */ +static const SEC_ASN1Template fortSwFortezzaInitFile[] = { + { SEC_ASN1_SEQUENCE, + 0, NULL, sizeof(FORTSignedSWFile) }, + { SEC_ASN1_SAVE, + offsetof(FORTSignedSWFile,signatureWrap.data) }, + { SEC_ASN1_INLINE, + offsetof(FORTSignedSWFile,file), + fortSwFortezzaInitFileToSign }, + { SEC_ASN1_INLINE, + offsetof(FORTSignedSWFile,signatureWrap.signatureAlgorithm), + SECOID_AlgorithmIDTemplate }, + { SEC_ASN1_BIT_STRING, + offsetof(FORTSignedSWFile,signatureWrap.signature) }, + { 0 } +}; + +FORTSkipjackKeyPtr +fort_CalculateKMemPhrase(FORTSWFile *file, + fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey) +{ + unsigned char *data = NULL; + unsigned char hashout[SHA1_LENGTH]; + int data_len = prot_phrase->wrappedKValue.len; + int ret; + unsigned int len; + unsigned int version; + unsigned char enc_version[2]; + FORTSkipjackKeyPtr Kout = NULL; + FORTSkipjackKey Kfek; + SHA1Context *sha; + + data = (unsigned char *) PORT_ZAlloc(data_len); + if (data == NULL) goto fail; + + PORT_Memcpy(data,prot_phrase->wrappedKValue.data,data_len); + + /* if it's a real protected mem phrase, it's been wrapped by kinit, which + * was passed to us. */ + if (wrapKey) { + fort_skipjackDecrypt(wrapKey, + &prot_phrase->kValueIV.data[SKIPJACK_LEAF_SIZE],data_len, + data,data); + data_len = sizeof(CI_KEY); + } + + /* now calculate the PBE key for fortezza */ + sha = SHA1_NewContext(); + if (sha == NULL) goto fail; + 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); + SHA1_DestroyContext(sha, PR_TRUE); + PORT_Memcpy(Kfek,hashout,sizeof(FORTSkipjackKey)); + + /* now use that key to unwrap */ + Kout = (FORTSkipjackKeyPtr) PORT_Alloc(sizeof(FORTSkipjackKey)); + ret = fort_skipjackUnwrap(Kfek,data_len,data,Kout); + if (ret != CI_OK) { + PORT_Free(Kout); + Kout = NULL; + } + +fail: + PORT_Memset(&Kfek, 0, sizeof(FORTSkipjackKey)); + if (data) PORT_ZFree(data,data_len); + return Kout; +} + + +PRBool +fort_CheckMemPhrase(FORTSWFile *file, + fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey) +{ + unsigned char *data = NULL; + unsigned char hashout[SHA1_LENGTH]; + int data_len = prot_phrase->hashedEncryptedMemPhrase.len; + unsigned int len; + SHA1Context *sha; + PRBool pinOK = PR_FALSE; + unsigned char cw[4]; + int i; + + + /* first, decrypt the hashed/Encrypted Memphrase */ + data = (unsigned char *) PORT_ZAlloc(data_len); + if (data == NULL) goto failed; + + PORT_Memcpy(data,prot_phrase->hashedEncryptedMemPhrase.data,data_len); + fort_skipjackDecrypt(wrapKey, + &prot_phrase->memPhraseIV.data[SKIPJACK_LEAF_SIZE],data_len, + data,data); + + /* now build the hash for comparisons */ + sha = SHA1_NewContext(); + if (sha == NULL) goto failed; + SHA1_Begin(sha); + SHA1_Update(sha,(unsigned char *)phrase,strlen(phrase)); + SHA1_End(sha,hashout,&len,SHA1_LENGTH); + SHA1_DestroyContext(sha, PR_TRUE); + + /* hashes don't match... must not be the right pass mem */ + if (PORT_Memcmp(data,hashout,len) != 0) goto failed; + + /* 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]; + } + + /* checkword doesn't match, must not be the right pass mem */ + if (PORT_Memcmp(data+len,cw,4) != 0) goto failed; + + /* pased all our test, its OK */ + pinOK = PR_TRUE; + +failed: + PORT_Free(data); + + return pinOK; +} + +/* + * walk through the list of memphrases. This function allows us to use a + * for loop to walk down them. + */ +fortProtectedPhrase * +fort_getNextPhrase( FORTSWFile *file, fortProtectedPhrase *last) +{ + if (last == &file->userMemPhrase) { + return &file->userPinPhrase; + } + /* we can add more test here if we want to support SSO mode someday. */ + + return NULL; +} + +/* + * decode the DER file data into our nice data structures, including turning + * cert indexes into integers. + */ +FORTSignedSWFile * +FORT_GetSWFile(SECItem *initBits) +{ + FORTSignedSWFile *sw_init_file; + PRArenaPool *arena = NULL; + SECStatus rv; + int i, count; + SECItem newInitBits; + + /* get the local arena... be sure to free this at the end */ + + /* get the local arena... be sure to free this at the end */ + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) goto fail; + + sw_init_file = (FORTSignedSWFile *) + PORT_ArenaZAlloc(arena,sizeof(FORTSignedSWFile)); + if (sw_init_file == NULL) goto fail; + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newInitBits, initBits); + if ( rv != SECSuccess ) { + goto fail; + } + + /* ANS1 decode the complete init file */ + rv = SEC_QuickDERDecodeItem(arena,sw_init_file,fortSwFortezzaInitFile,&newInitBits); + if (rv != SECSuccess) { + goto fail; + } + + /* count the certs */ + count = 0; + while (sw_init_file->file.slotEntries[count]) count++; + + for (i=0; i < count; i++) { + /* update the cert Index Pointers */ + sw_init_file->file.slotEntries[i]->certIndex = + DER_GetInteger(&sw_init_file-> + file.slotEntries[i]->certificateIndex ); + } + + /* now start checking the mem phrases and pins, as well as calculating the + * file's 'K' values. First we start with K(init). */ + sw_init_file->file.arena = arena; + + return sw_init_file; + /* OK now that we've read in the init file, and now have Kinit, Ks, and the + * appropriate Pin Phrase, we need to build our database file. */ + +fail: + if (arena) PORT_FreeArena(arena,PR_TRUE); + return NULL; +} + +/* + * Check the init memphrases and the user mem phrases. Remove all the init + * memphrase wrappings. Save the Kinit and Ks values for use. + */ +SECStatus +FORT_CheckInitPhrase(FORTSignedSWFile *sw_init_file, char *initMemPhrase) +{ + SECStatus rv = SECFailure; + + sw_init_file->Kinit = fort_CalculateKMemPhrase(&sw_init_file->file, + &sw_init_file->file.initMemPhrase, initMemPhrase, NULL); + if (sw_init_file->Kinit == NULL) goto fail; + + /* now check the init Mem phrase */ + if (!fort_CheckMemPhrase(&sw_init_file->file, + &sw_init_file->file.initMemPhrase, + initMemPhrase, sw_init_file->Kinit)) { + goto fail; + } + rv = SECSuccess; + +fail: + return rv; +} + + /* now check user user mem phrase and calculate Ks */ +SECStatus +FORT_CheckUserPhrase(FORTSignedSWFile *sw_init_file, char *userMemPhrase) +{ + SECStatus rv = SECFailure; + char tmp_data[13]; + char *padMemPhrase = NULL; + fortProtectedPhrase *phrase_store; + + if (strlen(userMemPhrase) < 12) { + PORT_Memset(tmp_data, ' ', sizeof(tmp_data)); + PORT_Memcpy(tmp_data,userMemPhrase,strlen(userMemPhrase)); + tmp_data[12] = 0; + padMemPhrase = tmp_data; + } + + for (phrase_store = &sw_init_file->file.userMemPhrase; phrase_store; + phrase_store = fort_getNextPhrase(&sw_init_file->file,phrase_store)) { + sw_init_file->Ks = fort_CalculateKMemPhrase(&sw_init_file->file, + phrase_store, userMemPhrase, sw_init_file->Kinit); + + if ((sw_init_file->Ks == NULL) && (padMemPhrase != NULL)) { + sw_init_file->Ks = fort_CalculateKMemPhrase(&sw_init_file->file, + phrase_store, padMemPhrase, sw_init_file->Kinit); + userMemPhrase = padMemPhrase; + } + if (sw_init_file->Ks == NULL) { + continue; + } + + /* now check the User Mem phrase */ + if (fort_CheckMemPhrase(&sw_init_file->file, phrase_store, + userMemPhrase, sw_init_file->Ks)) { + break; + } + PORT_Free(sw_init_file->Ks); + sw_init_file->Ks = NULL; + } + + + if (phrase_store == NULL) goto fail; + + /* strip the Kinit wrapping */ + fort_skipjackDecrypt(sw_init_file->Kinit, + &phrase_store->kValueIV.data[SKIPJACK_LEAF_SIZE], + phrase_store->wrappedKValue.len, phrase_store->wrappedKValue.data, + phrase_store->wrappedKValue.data); + phrase_store->wrappedKValue.len = 12; + + PORT_Memset(phrase_store->kValueIV.data,0,phrase_store->kValueIV.len); + + sw_init_file->file.initMemPhrase = *phrase_store; + sw_init_file->file.ssoMemPhrase = *phrase_store; + sw_init_file->file.ssoPinPhrase = *phrase_store; + sw_init_file->file.userMemPhrase = *phrase_store; + sw_init_file->file.userPinPhrase = *phrase_store; + + + rv = SECSuccess; + +fail: + /* don't keep the pin around */ + PORT_Memset(tmp_data, 0, sizeof(tmp_data)); + return rv; +} + +void +FORT_DestroySWFile(FORTSWFile *file) +{ + PORT_FreeArena(file->arena,PR_FALSE); +} + +void +FORT_DestroySignedSWFile(FORTSignedSWFile *swfile) +{ + FORT_DestroySWFile(&swfile->file); +} + + +SECItem * +FORT_GetDERCert(FORTSignedSWFile *swfile,int index) +{ + SECItem *newItem = NULL; + unsigned char *cert = NULL; + int len,ret; + fortSlotEntry *certEntry = NULL; + + + newItem = PORT_ZNew(SECItem); + if (newItem == NULL) return NULL; + + certEntry = fort_GetCertEntry(&swfile->file,index); + if (certEntry == NULL) { + PORT_Free(newItem); + return NULL; + } + + newItem->len = len = certEntry->certificateData.dataEncryptedWithKs.len; + newItem->data = cert = PORT_ZAlloc(len); + if (cert == NULL) { + PORT_Free(newItem); + return NULL; + } + newItem->len = DER_GetUInteger(&certEntry->certificateData.length); + + + PORT_Memcpy(cert, certEntry->certificateData.dataEncryptedWithKs.data,len); + + /* Ks is always stored in keyReg[0] when we log in */ + ret = fort_skipjackDecrypt(swfile->Ks, + &certEntry->certificateData.dataIV.data[SKIPJACK_LEAF_SIZE], + len,cert,cert); + if (ret != CI_OK) { + SECITEM_FreeItem(newItem,PR_TRUE); + return NULL; + } + return newItem; +} + +/* + * decode the DER file data into our nice data structures, including turning + * cert indexes into integers. + */ +SECItem * +FORT_PutSWFile(FORTSignedSWFile *sw_init_file) +{ + SECItem *outBits, *tmpBits; + + outBits = PORT_ZNew(SECItem); + if (outBits == NULL) goto fail; + + /* ANS1 encode the complete init file */ + tmpBits = SEC_ASN1EncodeItem(NULL,outBits,sw_init_file,fortSwFortezzaInitFile); + if (tmpBits == NULL) { + goto fail; + } + + return outBits; + +fail: + if (outBits) SECITEM_FreeItem(outBits,PR_TRUE); + return NULL; +} diff --git a/security/nss/lib/fortcrypt/swfort/swfutl.c b/security/nss/lib/fortcrypt/swfort/swfutl.c new file mode 100644 index 000000000..85e7f0ca4 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfutl.c @@ -0,0 +1,755 @@ +/* ***** 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 ***** */ +/* + * This File includes utility functions used by cilib. and swfparse.c + */ + +#include "prtypes.h" +#include "prsystem.h" +#include "prio.h" + +#include "swforti.h" +#include "keyt.h" +/* #include "dh.h" */ +#include "maci.h" +#include "secport.h" +#include "secrng.h" +#ifdef XP_OS2 +#include <sys/stat.h> +#endif + +#ifdef XP_WIN +#include <windows.h> +#include <winsock.h> +#include <direct.h> +#endif + +/* no platform seem to agree on where this function is defined */ +static char *local_index(char *source, char target) { + while ((*source != target) && (*source != 0)) { + source++; + } + return (*source != 0) ? source : NULL; +} + +/* + * Check to see if the index is ok, and that key is appropriately present or + * absent. + */ +int +fort_KeyOK(FORTSWToken *token, int index, PRBool isPresent) +{ + if (index < 0) return CI_INV_KEY_INDEX; + if (index >= KEY_REGISTERS) return CI_INV_KEY_INDEX; + + return (token->keyReg[index].present == isPresent) ? CI_OK : + (isPresent ? CI_NO_KEY : CI_REG_IN_USE); +} + +/* + * clear out a key register + */ +void +fort_ClearKey(FORTKeySlot *key) +{ + key->present = PR_FALSE; + PORT_Memset(key->data, 0, sizeof (key->data)); + return; +} + +/* + * clear out an Ra register + */ +void +fort_ClearRaSlot(FORTRaRegisters *ra) +{ + PORT_Memset(ra->public, 0, sizeof(ra->public)); + PORT_Memset(ra->private, 0, sizeof(ra->private)); + return; +} + +/* + * provide a helper function to do all the loggin out functions. + * NOTE: Logining in only happens in MACI_CheckPIN + */ +void +fort_Logout(FORTSWToken *token) +{ + int i; + + /* ditch all the stored keys */ + for (i=0; i < KEY_REGISTERS; i++) { + fort_ClearKey(&token->keyReg[i]); + } + for (i=0; i < MAX_RA_SLOTS; i++) { + fort_ClearRaSlot(&token->RaValues[i]); + } + + /* mark as logged out */ + token->login = PR_FALSE; + token->certIndex = 0; + token->key = 0; + return; +} + +/* + * update the new IV value based on the current cipherText (should be the last + * block of the cipher text). + */ +int +fort_UpdateIV(unsigned char *cipherText, unsigned int size,unsigned char *IV) +{ + if (size == 0) return CI_INV_SIZE; + if ((size & (SKIPJACK_BLOCK_SIZE-1)) != 0) return CI_INV_SIZE; + size -= SKIPJACK_BLOCK_SIZE; + PORT_Memcpy(IV,&cipherText[size],SKIPJACK_BLOCK_SIZE); + return CI_OK; +} + + +/* + * verify that we have a card initialized, and if necessary, logged in. + */ +int +fort_CardExists(FORTSWToken *token,PRBool needLogin) +{ + if (token == NULL ) return CI_LIB_NOT_INIT; + if (token->config_file == NULL) return CI_NO_CARD; + if (needLogin && !token->login) return CI_INV_STATE; + return CI_OK; +} + +/* + * walk down the cert slot entries, counting them. + * return that count. + */ +int +fort_GetCertCount(FORTSWFile *file) +{ + int i; + + if (file->slotEntries == NULL) return 0; + + for (i=0; file->slotEntries[i]; i++) + /* no body */ ; + + return i; +} + +/* + * copy an unsigned SECItem to a signed SecItem. (if the high bit is on, + * pad with a leading 0. + */ +SECStatus +fort_CopyUnsigned(PRArenaPool *arena, SECItem *to, const SECItem *from) +{ + int offset = 0; + + if (from->data && from->len) { + if (from->data[0] & 0x80) offset = 1; + if ( arena ) { + to->data = (unsigned char*) PORT_ArenaZAlloc(arena, + from->len+offset); + } else { + to->data = (unsigned char*) PORT_ZAlloc(from->len+offset); + } + + if (!to->data) { + return SECFailure; + } + PORT_Memcpy(to->data+offset, from->data, from->len); + to->len = from->len+offset; + } else { + to->data = 0; + to->len = 0; + } + return SECSuccess; +} + +/* + * NOTE: these keys do not have the public values, and cannot be used to + * extract the public key from the private key. Since we never do this in + * this code, and this function is static, we're reasonably safe (as long as + * any of your callees do not try to extract the public value as well). + * Also -- the token must be logged in before this function is called. + */ +FORTEZZAPrivateKey * +fort_GetPrivKey(FORTSWToken *token,FORTEZZAKeyType keyType, + fortSlotEntry *certEntry) +{ + FORTEZZAPrivateKey *returnKey = NULL; + SECStatus rv = SECFailure; + PRArenaPool *poolp; + fortKeyInformation *keyInfo = NULL; + unsigned char *keyData; + int len, ret; + + + /* select the right keyinfo */ + switch (keyType) { + case fortezzaDSAKey: + keyInfo = certEntry->signatureKeyInformation; + if (keyInfo == NULL) keyInfo = certEntry->exchangeKeyInformation; + break; + case fortezzaDHKey: + keyInfo = certEntry->exchangeKeyInformation; + if (keyInfo == NULL) keyInfo = certEntry->signatureKeyInformation; + break; + } + + /* if we don't have any key information, blow out of here */ + if (keyInfo == NULL) return NULL; + + poolp = PORT_NewArena(2048); + if(!poolp) { + return NULL; + } + + returnKey = (FORTEZZAPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(FORTEZZAPrivateKey)); + if(!returnKey) { + rv = SECFailure; + goto loser; + } + + returnKey->keyType = keyType; + returnKey->arena = poolp; + + /* + * decrypt the private key + */ + len = keyInfo->privateKeyWrappedWithKs.len; + keyData = PORT_ArenaZAlloc(poolp,len); + if (keyData == NULL) { + rv = SECFailure; + goto loser; + } + /* keys must be 160 bits (20 bytes) if that's not the case the Unwrap will + * fail.. */ + ret = fort_skipjackUnwrap(token->keyReg[0].data, len, + keyInfo->privateKeyWrappedWithKs.data, keyData); + if (ret != CI_OK) { + rv = SECFailure; + goto loser; + } + + switch(keyType) { + case dsaKey: + returnKey->u.dsa.privateValue.data = keyData; + returnKey->u.dsa.privateValue.len = 20; + returnKey->u.dsa.params.arena = poolp; + rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.prime), + &(keyInfo->p)); + if(rv != SECSuccess) break; + rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.subPrime), + &(keyInfo->q)); + if(rv != SECSuccess) break; + rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.base), + &(keyInfo->g)); + if(rv != SECSuccess) break; + break; + case dhKey: + returnKey->u.dh.arena = poolp; + returnKey->u.dh.privateValue.data = keyData; + returnKey->u.dh.privateValue.len = 20; + rv = fort_CopyUnsigned(poolp, &(returnKey->u.dh.prime), + &(keyInfo->p)); + if(rv != SECSuccess) break; + rv = fort_CopyUnsigned(poolp, &(returnKey->u.dh.base), + &(keyInfo->g)); + if(rv != SECSuccess) break; + rv = SECSuccess; + break; + default: + rv = SECFailure; + } + +loser: + + if(rv != SECSuccess) { + PORT_FreeArena(poolp, PR_TRUE); + returnKey = NULL; + } + + return returnKey; +} + + +void +fort_DestroyPrivateKey(FORTEZZAPrivateKey *key) +{ + if (key && key->arena) { + PORT_FreeArena(key->arena, PR_TRUE); + } +} + +/* + * find a particulare certificate entry from the config + * file. + */ +fortSlotEntry * +fort_GetCertEntry(FORTSWFile *file,int index) +{ + /* search for the index */ + int i,count= fort_GetCertCount(file); + + /* make sure the given index exists & has key material */ + for (i=0; i < count ;i ++) { + if (file->slotEntries[i]->certIndex == index) { + return file->slotEntries[i]; + } + } + return NULL; +} + +/* + * use the token to determine it's CI_State. + */ +CI_STATE +fort_GetState(FORTSWToken *token) +{ + /* no file? then the token has not been initialized */ + if (!token->config_file) { + return CI_UNINITIALIZED; + } + /* we're initialized, are we logged in (CI_USER_INITIALIZED is not logged + * in) */ + if (!token->login) { + return CI_USER_INITIALIZED; + } + /* We're logged in, do we have a personality set */ + if (token->certIndex) { + return CI_READY; + } + /* We're logged in, with no personality set */ + return CI_STANDBY; +} + +/* + * find the private ra value for a given public Ra value. + */ +fortRaPrivatePtr +fort_LookupPrivR(FORTSWToken *token,CI_RA Ra) +{ + int i; + + /* probably a more efficient way of doing this would be to search first + * several entries before nextRa (or search backwards from next Ra) + */ + for (i=0; i < MAX_RA_SLOTS; i++) { + if (PORT_Memcmp(token->RaValues[i].public,Ra,CI_RA_SIZE) == 0) { + return token->RaValues[i].private; + } + } + return NULL; +} + +/* + * go add more noise to the random number generator + */ +void +fort_AddNoise(void) +{ + unsigned char seed[20]; + + /* note: GetNoise doesn't always get 20 bytes, but adding more + * random data from the stack doesn't subtract entropy from the + * Random number generator, so just send it all. + */ + RNG_GetNoise(seed,sizeof(seed)); + RNG_RandomUpdate(seed,sizeof(seed)); +} + +/* + * Get a random number + */ +int +fort_GenerateRandom(unsigned char *buf, int bytes) +{ + SECStatus rv; + + fort_AddNoise(); + rv = RNG_GenerateGlobalRandomBytes(buf,bytes); + if (rv != SECSuccess) return CI_EXEC_FAIL; + return CI_OK; +} + +/* + * NOTE: that MAC is missing below. + */ +#if defined (XP_UNIX) || defined (XP_OS2) || defined (XP_BEOS) +#if defined (XP_UNIX) || defined (XP_BEOS) +#define NS_PATH_SEP ':' +#define NS_DIR_SEP '/' +#define NS_DEFAULT_PATH ".:/bin/netscape:/etc/netscape/:/etc" +#endif + +#ifdef XP_OS2 /* for OS/2 */ +#define NS_PATH_SEP ';' +#define NS_DIR_SEP '\\' +#define NS_DEFAULT_PATH ".:\\bin\\netscape:\\etc\\netscape\\:\\etc" +#endif + +PRInt32 +local_getFileInfo(const char *fn, PRFileInfo *info) +{ + PRInt32 rv; + struct stat sb; + + rv = stat(fn, &sb); + if (rv < 0) + return -1; + else if (NULL != info) + { + if (S_IFREG & sb.st_mode) + info->type = PR_FILE_FILE; + else if (S_IFDIR & sb.st_mode) + info->type = PR_FILE_DIRECTORY; + else + info->type = PR_FILE_OTHER; + +#if defined(OSF1) + if (0x7fffffffLL < sb.st_size) + { + return -1; + } +#endif /* defined(OSF1) */ + info->size = sb.st_size; + + } + return rv; +} +#endif /* UNIX, OS/2, and BEOS */ + +#ifdef XP_WIN +#define NS_PATH_SEP ';' +#define NS_DIR_SEP '\\' +#define NS_DEFAULT_PATH ".;c:\\program files\\netscape\\communicator\\program\\pkcs11\\netscape;c:\\netscape\\communicator\\program\\pkcs11\\netscape;c:\\windows\\system" + + +/* + * Since we're a pkcs #11 module, we may get + * loaded into lots of different binaries, each with different or no versions + * of NSPR running... so we copy the one function we need. + */ + +#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\') + +/* + * IsRootDirectory -- + * + * Return PR_TRUE if the pathname 'fn' is a valid root directory, + * else return PR_FALSE. The char buffer pointed to by 'fn' must + * be writable. During the execution of this function, the contents + * of the buffer pointed to by 'fn' may be modified, but on return + * the original contents will be restored. 'buflen' is the size of + * the buffer pointed to by 'fn'. + * + * Root directories come in three formats: + * 1. / or \, meaning the root directory of the current drive. + * 2. C:/ or C:\, where C is a drive letter. + * 3. \\<server name>\<share point name>\ or + * \\<server name>\<share point name>, meaning the root directory + * of a UNC (Universal Naming Convention) name. + */ + +static PRBool +IsRootDirectory(char *fn, size_t buflen) +{ + char *p; + PRBool slashAdded = PR_FALSE; + PRBool rv = PR_FALSE; + + if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') { + return PR_TRUE; + } + + if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2]) + && fn[3] == '\0') { + rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; + return rv; + } + + /* The UNC root directory */ + + if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) { + /* The 'server' part should have at least one character. */ + p = &fn[2]; + if (*p == '\0' || _PR_IS_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the next slash */ + do { + p++; + } while (*p != '\0' && !_PR_IS_SLASH(*p)); + if (*p == '\0') { + return PR_FALSE; + } + + /* The 'share' part should have at least one character. */ + p++; + if (*p == '\0' || _PR_IS_SLASH(*p)) { + return PR_FALSE; + } + + /* look for the final slash */ + do { + p++; + } while (*p != '\0' && !_PR_IS_SLASH(*p)); + if (_PR_IS_SLASH(*p) && p[1] != '\0') { + return PR_FALSE; + } + if (*p == '\0') { + /* + * GetDriveType() doesn't work correctly if the + * path is of the form \\server\share, so we add + * a final slash temporarily. + */ + if ((p + 1) < (fn + buflen)) { + *p++ = '\\'; + *p = '\0'; + slashAdded = PR_TRUE; + } else { + return PR_FALSE; /* name too long */ + } + } + rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE; + /* restore the 'fn' buffer */ + if (slashAdded) { + *--p = '\0'; + } + } + return rv; +} + +PRInt32 +local_getFileInfo(const char *fn, PRFileInfo *info) +{ + HANDLE hFindFile; + WIN32_FIND_DATA findFileData; + char pathbuf[MAX_PATH + 1]; + + if (NULL == fn || '\0' == *fn) { + return -1; + } + + /* + * FindFirstFile() expands wildcard characters. So + * we make sure the pathname contains no wildcard. + */ + if (NULL != strpbrk(fn, "?*")) { + return -1; + } + + hFindFile = FindFirstFile(fn, &findFileData); + if (INVALID_HANDLE_VALUE == hFindFile) { + DWORD len; + char *filePart; + + /* + * FindFirstFile() does not work correctly on root directories. + * It also doesn't work correctly on a pathname that ends in a + * slash. So we first check to see if the pathname specifies a + * root directory. If not, and if the pathname ends in a slash, + * we remove the final slash and try again. + */ + + /* + * If the pathname does not contain ., \, and /, it cannot be + * a root directory or a pathname that ends in a slash. + */ + if (NULL == strpbrk(fn, ".\\/")) { + return -1; + } + len = GetFullPathName(fn, sizeof(pathbuf), pathbuf, + &filePart); + if (len > sizeof(pathbuf)) { + return -1; + } + if (IsRootDirectory(pathbuf, sizeof(pathbuf))) { + info->type = PR_FILE_DIRECTORY; + info->size = 0; + /* + * These timestamps don't make sense for root directories. + */ + info->modifyTime = 0; + info->creationTime = 0; + return 0; + } + if (!((pathbuf[len - 1] == '/') || (pathbuf[len-1] == '\\'))) { + return -1; + } else { + pathbuf[len - 1] = '\0'; + hFindFile = FindFirstFile(pathbuf, &findFileData); + if (INVALID_HANDLE_VALUE == hFindFile) { + return -1; + } + } + } + + FindClose(hFindFile); + + if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + info->type = PR_FILE_DIRECTORY; + } else { + info->type = PR_FILE_FILE; + } + + info->size = findFileData.nFileSizeLow; + + return 0; +} + +#endif /* XP_WIN */ + +#ifdef XP_MAC +#error Need to write fort_FindFileInPath for Mac +#define NS_PATH_SEP ',' +#define NS_DIR_SEP ':' +#define NS_DEFAULT_PATH ",System Folder,System Folder:Netscape f:pkcs11:netscape" +#endif + +#define NETSCAPE_INIT_FILE "nsswft.swf" + +/* + * OK, We're deep in the bottom of MACI and PKCS #11... We need to + * find our fortezza key file. We have no clue of where the our binary lives + * or where our key file lives. This function lets us search manual paths + * to find our key file. + */ +char *fort_FindFileInPath(char *path, char *fn) +{ + char *next; + char *holdData; + char *ret = NULL; + int len = 0; + int fn_len = PORT_Strlen(fn)+1; /* include the NULL */ + PRFileInfo info; + char dirSep = NS_DIR_SEP; + + holdData = PORT_Alloc(strlen(path)+1+fn_len); + + while ((next = local_index(path,NS_PATH_SEP)) != NULL) { + len = next - path; + + PORT_Memcpy(holdData,path,len); + if ((len != 0) && (holdData[len-1] != dirSep)) { + PORT_Memcpy(&holdData[len],&dirSep,1); + len++; + } + PORT_Memcpy(&holdData[len],fn,fn_len); + + if ((local_getFileInfo(holdData,&info) == 0) && + (info.type == PR_FILE_FILE) && (info.size != 0)) { + ret = PORT_Strdup(holdData); + PORT_Free(holdData); + return ret; + } + path = next+1; + } + + len = strlen(path); + PORT_Memcpy(holdData,path,len); + if ((len != 0) && (holdData[len-1] != dirSep)) { + PORT_Memcpy(&holdData[len],&dirSep,1); + len++; + } + PORT_Memcpy(&holdData[len],fn,fn_len); + + if ((local_getFileInfo(holdData,&info) == 0) && + (info.type == PR_FILE_FILE) && (info.size != 0)) { + ret = PORT_Strdup(holdData); + } + PORT_Free(holdData); + return ret; +} + +static char *path_table[] = { + "PATH","LD_LIBRARY_PATH","LIBPATH" +}; + +static int path_table_size = sizeof(path_table)/sizeof(path_table[0]); + +char *fort_LookupFORTEZZAInitFile(void) +{ + char *fname = NULL; +#if defined(XP_UNIX) || defined(XP_WIN) + char *home = NULL; +#endif +#ifdef XP_UNIX + char unix_home[512]; +#endif + int i; + + /* 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")); + strcat(unix_home,"/.netscape"); + fname = fort_FindFileInPath(unix_home,NETSCAPE_INIT_FILE); + if (fname) return fname; + } +#endif +#ifdef XP_WIN + home = getenv("windir"); + if (home) { + fname = fort_FindFileInPath(home,NETSCAPE_INIT_FILE); + if (fname) return fname; + } +#endif + + fname = fort_FindFileInPath(NS_DEFAULT_PATH,NETSCAPE_INIT_FILE); + if (fname) return fname; + + /* now search the system paths */ + for (i=0; i < path_table_size; i++) { + char *path = getenv(path_table[i]); + + if (path != NULL) { + fname = fort_FindFileInPath(path,NETSCAPE_INIT_FILE); + if (fname) return fname; + } + } + + + return NULL; +} diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index 11c0843a8..1805d1c5e 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -188,6 +188,17 @@ endif endif endif +# The blapi functions are defined not only in the freebl shared +# libraries but also in the shared libraries linked with loader.c +# (libsoftokn3.so and libssl3.so). We need to use GNU ld's +# -Bsymbolic option or the equivalent option for other linkers +# to bind the blapi function references in FREEBLVector vector +# (ldvector.c) to the blapi functions defined in the freebl +# shared libraries. +ifeq (,$(filter-out BSD_OS FreeBSD Linux NetBSD, $(OS_TARGET))) + MKSHLIB += -Wl,-Bsymbolic +endif + ifeq ($(OS_TARGET),SunOS) # The -R '$ORIGIN' linker option instructs this library to search for its diff --git a/security/nss/lib/freebl/arcfour-amd64-gas.s b/security/nss/lib/freebl/arcfour-amd64-gas.s index 66daf07ba..e131fd16a 100644 --- a/security/nss/lib/freebl/arcfour-amd64-gas.s +++ b/security/nss/lib/freebl/arcfour-amd64-gas.s @@ -114,3 +114,7 @@ ARCFOUR: ret .L_ARCFOUR_end: .size ARCFOUR,.L_ARCFOUR_end-ARCFOUR + +# Magic indicating no need for an executable stack +.section .note.GNU-stack,"",@progbits +.previous diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c index 563e10438..53949ab94 100644 --- a/security/nss/lib/freebl/ec.c +++ b/security/nss/lib/freebl/ec.c @@ -397,7 +397,7 @@ EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) ); CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) ); CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) ); - CHECK_MPI_OK( mp_to_unsigned_octets(&privKeyVal, privKeyBytes, len) ); + CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) ); /* generate public key */ CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) ); diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h index cba22b2a7..fed21fa52 100644 --- a/security/nss/lib/freebl/ecl/ecl-curve.h +++ b/security/nss/lib/freebl/ecl/ecl-curve.h @@ -117,7 +117,7 @@ static const ECCurveParams ecCurve_NIST_K233 = { "000000000000000000000000000000000000000000000000000000000001", "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", - "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4 + "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4 }; static const ECCurveParams ecCurve_NIST_B233 = { "NIST-B233", ECField_GF2m, 233, @@ -155,7 +155,7 @@ static const ECCurveParams ecCurve_NIST_K409 = { "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", - "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 4 }; static const ECCurveParams ecCurve_NIST_B409 = { diff --git a/security/nss/lib/freebl/ecl/ecl_mult.c b/security/nss/lib/freebl/ecl/ecl_mult.c index 69eae6965..106c7ee42 100644 --- a/security/nss/lib/freebl/ecl/ecl_mult.c +++ b/security/nss/lib/freebl/ecl/ecl_mult.c @@ -162,7 +162,6 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, { mp_err res = MP_OKAY; mp_int precomp[4][4][2]; - mp_digit precomp_arr[ECL_MAX_FIELD_SIZE_DIGITS * 4 * 4 * 2], *t; const mp_int *a, *b; int i, j; int ai, bi, d; @@ -180,23 +179,18 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, } /* initialize precomputation table */ - t = precomp_arr; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - /* x co-ord */ - MP_SIGN(&precomp[i][j][0]) = MP_ZPOS; - MP_ALLOC(&precomp[i][j][0]) = ECL_MAX_FIELD_SIZE_DIGITS; - MP_USED(&precomp[i][j][0]) = 1; - *t = 0; - MP_DIGITS(&precomp[i][j][0]) = t; - t += ECL_MAX_FIELD_SIZE_DIGITS; - /* y co-ord */ - MP_SIGN(&precomp[i][j][1]) = MP_ZPOS; - MP_ALLOC(&precomp[i][j][1]) = ECL_MAX_FIELD_SIZE_DIGITS; - MP_USED(&precomp[i][j][1]) = 1; - *t = 0; - MP_DIGITS(&precomp[i][j][1]) = t; - t += ECL_MAX_FIELD_SIZE_DIGITS; + MP_DIGITS(&precomp[i][j][0]) = 0; + MP_DIGITS(&precomp[i][j][1]) = 0; + } + } + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + MP_CHECKOK( mp_init_size(&precomp[i][j][0], + ECL_MAX_FIELD_SIZE_DIGITS) ); + MP_CHECKOK( mp_init_size(&precomp[i][j][1], + ECL_MAX_FIELD_SIZE_DIGITS) ); } } @@ -298,6 +292,12 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, } CLEANUP: + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + mp_clear(&precomp[i][j][0]); + mp_clear(&precomp[i][j][1]); + } + } return res; } diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c index b98ea9c68..141cc1b7f 100644 --- a/security/nss/lib/freebl/loader.c +++ b/security/nss/lib/freebl/loader.c @@ -125,20 +125,18 @@ static const char * getLibName(void) { return default_name; } #ifdef XP_UNIX #include <unistd.h> -#endif #define BL_MAXSYMLINKS 20 /* * If 'link' is a symbolic link, this function follows the symbolic links * and returns the pathname of the ultimate source of the symbolic links. - * If 'link' is not a symbolic link, this function returns a copy of 'link'. + * If 'link' is not a symbolic link, this function returns NULL. * The caller should call PR_Free to free the string returned by this * function. */ static char* bl_GetOriginalPathname(const char* link) { -#ifdef XP_UNIX char* resolved = NULL; char* input = NULL; PRUint32 iterations = 0; @@ -168,16 +166,13 @@ static char* bl_GetOriginalPathname(const char* link) resolved = tmp; } PR_Free(resolved); - return input; -#else - if (link) { - return PL_strdup(link); - } else { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; + if (iterations == 1 && retlen < 0) { + PR_Free(input); + input = NULL; } -#endif + return input; } +#endif /* XP_UNIX */ /* * We use PR_GetLibraryFilePathname to get the pathname of the loaded @@ -196,16 +191,47 @@ typedef struct { PRLibrary *dlh; } BLLibrary; +/* + * Load the freebl library with the file name 'name' residing in the same + * directory as libsoftoken, whose pathname is 'softokenPath'. + */ +static PRLibrary * +bl_LoadFreeblLibInSoftokenDir(const char *softokenPath, const char *name) +{ + PRLibrary *dlh = NULL; + char *fullName = NULL; + char* c; + PRLibSpec libSpec; + + /* Remove "libsoftokn" from the pathname and add the freebl libname */ + c = strrchr(softokenPath, PR_GetDirectorySeparator()); + if (c) { + size_t softoknPathSize = 1 + c - softokenPath; + fullName = (char*) PORT_Alloc(strlen(name) + softoknPathSize + 1); + if (fullName) { + memcpy(fullName, softokenPath, softoknPathSize); + strcpy(fullName + softoknPathSize, name); +#ifdef DEBUG_LOADER + PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n", + fullName); +#endif + libSpec.type = PR_LibSpec_Pathname; + libSpec.value.pathname = fullName; + dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); + PORT_Free(fullName); + } + } + return dlh; +} + static BLLibrary * bl_LoadLibrary(const char *name) { BLLibrary *lib = NULL; PRFuncPtr fn_addr; char* softokenPath = NULL; - char* fullName = NULL; PRLibSpec libSpec; - libSpec.type = PR_LibSpec_Pathname; lib = PR_NEWZAP(BLLibrary); if (NULL == lib) { PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); @@ -222,38 +248,29 @@ bl_LoadLibrary(const char *name) fn_addr = (PRFuncPtr) &bl_LoadLibrary; softokenPath = PR_GetLibraryFilePathname(softoken, fn_addr); - /* Remove "libsoftokn" from the pathname and add the freebl libname */ if (softokenPath) { - char* c; - char* originalSoftokenPath = bl_GetOriginalPathname(softokenPath); - if (originalSoftokenPath) { - PR_Free(softokenPath); - softokenPath = originalSoftokenPath; - } - c = strrchr(softokenPath, PR_GetDirectorySeparator()); - if (c) { - size_t softoknPathSize = 1 + c - softokenPath; - fullName = (char*) PORT_Alloc(strlen(name) + softoknPathSize + 1); - if (fullName) { - memcpy(fullName, softokenPath, softoknPathSize); - strcpy(fullName + softoknPathSize, name); - } - } - PR_Free(softokenPath); - } - if (fullName) { -#ifdef DEBUG_LOADER - PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n", - fullName); + lib->dlh = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); +#ifdef XP_UNIX + if (!lib->dlh) { + /* + * If softokenPath is a symbolic link, resolve the symbolic + * link and try again. + */ + char* originalSoftokenPath = bl_GetOriginalPathname(softokenPath); + if (originalSoftokenPath) { + PR_Free(softokenPath); + softokenPath = originalSoftokenPath; + lib->dlh = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); + } + } #endif - libSpec.value.pathname = fullName; - lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); - PORT_Free(fullName); + PR_Free(softokenPath); } if (!lib->dlh) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", name); #endif + libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = name; lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); } diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c index f9602c6aa..2ea3ad15e 100644 --- a/security/nss/lib/freebl/mpi/mpi.c +++ b/security/nss/lib/freebl/mpi/mpi.c @@ -4759,6 +4759,8 @@ mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return pos; } /* end mp_to_unsigned_octets() */ /* }}} */ @@ -4797,6 +4799,8 @@ mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return pos; } /* end mp_to_signed_octets() */ /* }}} */ @@ -4832,6 +4836,8 @@ mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return MP_OKAY; } /* end mp_to_fixlen_octets() */ /* }}} */ diff --git a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s index 7515ac20a..86e16e362 100644 --- a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s +++ b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s @@ -416,3 +416,7 @@ ret .size s_mpv_mul_add_vec64, [.-s_mpv_mul_add_vec64] + +# Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits +.previous diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 18245f52d..9ced4592a 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -52,11 +52,11 @@ SEC_BEGIN_PROTOS * The format of the version string should be * "<major version>.<minor version>[.<patch level>] [<Beta>]" */ -#define NSS_VERSION "3.11" +#define NSS_VERSION "3.11.1 Beta" #define NSS_VMAJOR 3 #define NSS_VMINOR 11 -#define NSS_VPATCH 0 -#define NSS_BETA PR_FALSE +#define NSS_VPATCH 1 +#define NSS_BETA PR_TRUE /* diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index 45e7fa552..1da55d59b 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -270,9 +270,9 @@ typedef struct { } ssl3CipherSuiteCfg; #ifdef NSS_ENABLE_ECC -#define ssl_V3_SUITES_IMPLEMENTED 40 +#define ssl_V3_SUITES_IMPLEMENTED 37 #else -#define ssl_V3_SUITES_IMPLEMENTED 26 +#define ssl_V3_SUITES_IMPLEMENTED 23 #endif /* NSS_ENABLE_ECC */ typedef struct sslOptionsStr { |