security/nss/cmd/shlibsign/shlibsign.c

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 * shlibsign creates the checksum (.chk) files for the NSS libraries,
michael@0 7 * libsoftokn3/softokn3 and libfreebl/freebl (platforms can have
michael@0 8 * multiple freebl variants), that contain the NSS cryptograhic boundary.
michael@0 9 *
michael@0 10 * The generated .chk files must be put in the same directory as
michael@0 11 * the NSS libraries they were generated for.
michael@0 12 *
michael@0 13 * When in FIPS 140 mode, the NSS Internal FIPS PKCS #11 Module will
michael@0 14 * compute the checksum for the NSS cryptographic boundary libraries
michael@0 15 * and compare the checksum with the value in .chk file.
michael@0 16 */
michael@0 17
michael@0 18 #ifdef XP_UNIX
michael@0 19 #define USES_LINKS 1
michael@0 20 #endif
michael@0 21
michael@0 22 #include <assert.h>
michael@0 23 #include <stdio.h>
michael@0 24 #include <stdlib.h>
michael@0 25 #include <string.h>
michael@0 26 #include <stdarg.h>
michael@0 27
michael@0 28 #ifdef USES_LINKS
michael@0 29 #include <unistd.h>
michael@0 30 #include <sys/param.h>
michael@0 31 #include <sys/types.h>
michael@0 32 #include <sys/stat.h>
michael@0 33 #endif
michael@0 34
michael@0 35 /* nspr headers */
michael@0 36 #include "prlink.h"
michael@0 37 #include "prprf.h"
michael@0 38 #include "prenv.h"
michael@0 39 #include "plgetopt.h"
michael@0 40 #include "prinit.h"
michael@0 41 #include "prmem.h"
michael@0 42 #include "plstr.h"
michael@0 43 #include "prerror.h"
michael@0 44
michael@0 45 /* softoken headers */
michael@0 46 #include "pkcs11.h"
michael@0 47 #include "pkcs11t.h"
michael@0 48
michael@0 49 /* freebl headers */
michael@0 50 #include "shsign.h"
michael@0 51
michael@0 52 #define NUM_ELEM(array) (sizeof(array)/sizeof(array[0]))
michael@0 53 CK_BBOOL true = CK_TRUE;
michael@0 54 CK_BBOOL false = CK_FALSE;
michael@0 55 static PRBool verbose = PR_FALSE;
michael@0 56
michael@0 57 static void
michael@0 58 usage (const char *program_name)
michael@0 59 {
michael@0 60 PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError);
michael@0 61 PR_fprintf (debug_out,
michael@0 62 "type %s -H for more detail information.\n", program_name);
michael@0 63 PR_fprintf (debug_out,
michael@0 64 "Usage: %s [-v] [-V] [-o outfile] [-d dbdir] [-f pwfile]\n"
michael@0 65 " [-F] [-p pwd] -[P dbprefix ] "
michael@0 66 "-i shared_library_name\n",
michael@0 67 program_name);
michael@0 68 exit(1);
michael@0 69 }
michael@0 70
michael@0 71 static void
michael@0 72 long_usage(const char *program_name)
michael@0 73 {
michael@0 74 PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError);
michael@0 75 PR_fprintf(debug_out, "%s test program usage:\n", program_name);
michael@0 76 PR_fprintf(debug_out, "\t-i <infile> shared_library_name to process\n");
michael@0 77 PR_fprintf(debug_out, "\t-o <outfile> checksum outfile\n");
michael@0 78 PR_fprintf(debug_out, "\t-d <path> database path location\n");
michael@0 79 PR_fprintf(debug_out, "\t-P <prefix> database prefix\n");
michael@0 80 PR_fprintf(debug_out, "\t-f <file> password File : echo pw > file \n");
michael@0 81 PR_fprintf(debug_out, "\t-F FIPS mode\n");
michael@0 82 PR_fprintf(debug_out, "\t-p <pwd> password\n");
michael@0 83 PR_fprintf(debug_out, "\t-v verbose output\n");
michael@0 84 PR_fprintf(debug_out, "\t-V perform Verify operations\n");
michael@0 85 PR_fprintf(debug_out, "\t-? short help message\n");
michael@0 86 PR_fprintf(debug_out, "\t-h short help message\n");
michael@0 87 PR_fprintf(debug_out, "\t-H this help message\n");
michael@0 88 PR_fprintf(debug_out, "\n\n\tNote: Use of FIPS mode requires your ");
michael@0 89 PR_fprintf(debug_out, "library path is using \n");
michael@0 90 PR_fprintf(debug_out, "\t pre-existing libraries with generated ");
michael@0 91 PR_fprintf(debug_out, "checksum files\n");
michael@0 92 PR_fprintf(debug_out, "\t and database in FIPS mode \n");
michael@0 93 exit(1);
michael@0 94 }
michael@0 95
michael@0 96 static char *
michael@0 97 mkoutput(const char *input)
michael@0 98 {
michael@0 99 int in_len = strlen(input);
michael@0 100 char *output = PR_Malloc(in_len+sizeof(SGN_SUFFIX));
michael@0 101 int index = in_len + 1 - sizeof("."SHLIB_SUFFIX);
michael@0 102
michael@0 103 if ((index > 0) &&
michael@0 104 (PL_strncmp(&input[index],
michael@0 105 "."SHLIB_SUFFIX,sizeof("."SHLIB_SUFFIX)) == 0)) {
michael@0 106 in_len = index;
michael@0 107 }
michael@0 108 memcpy(output,input,in_len);
michael@0 109 memcpy(&output[in_len],SGN_SUFFIX,sizeof(SGN_SUFFIX));
michael@0 110 return output;
michael@0 111 }
michael@0 112
michael@0 113 static void
michael@0 114 lperror(const char *string) {
michael@0 115 PRErrorCode errorcode;
michael@0 116
michael@0 117 errorcode = PR_GetError();
michael@0 118 PR_fprintf(PR_STDERR, "%s: %d: %s\n", string, errorcode,
michael@0 119 PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT));
michael@0 120 }
michael@0 121
michael@0 122 static void
michael@0 123 encodeInt(unsigned char *buf, int val)
michael@0 124 {
michael@0 125 buf[3] = (val >> 0) & 0xff;
michael@0 126 buf[2] = (val >> 8) & 0xff;
michael@0 127 buf[1] = (val >> 16) & 0xff;
michael@0 128 buf[0] = (val >> 24) & 0xff;
michael@0 129 return;
michael@0 130 }
michael@0 131
michael@0 132 static PRStatus
michael@0 133 writeItem(PRFileDesc *fd, CK_VOID_PTR pValue,
michael@0 134 CK_ULONG ulValueLen, char *file)
michael@0 135 {
michael@0 136 unsigned char buf[4];
michael@0 137 int bytesWritten;
michael@0 138 if (ulValueLen == 0) {
michael@0 139 PR_fprintf(PR_STDERR, "call to writeItem with 0 bytes of data.\n");
michael@0 140 return PR_FAILURE;
michael@0 141 }
michael@0 142
michael@0 143 encodeInt(buf,ulValueLen);
michael@0 144 bytesWritten = PR_Write(fd,buf, 4);
michael@0 145 if (bytesWritten != 4) {
michael@0 146 lperror(file);
michael@0 147 return PR_FAILURE;
michael@0 148 }
michael@0 149 bytesWritten = PR_Write(fd, pValue, ulValueLen);
michael@0 150 if (bytesWritten != ulValueLen) {
michael@0 151 lperror(file);
michael@0 152 return PR_FAILURE;
michael@0 153 }
michael@0 154 return PR_SUCCESS;
michael@0 155 }
michael@0 156
michael@0 157 static const unsigned char prime[] = { 0x00,
michael@0 158 0x97, 0x44, 0x1d, 0xcc, 0x0d, 0x39, 0x0d, 0x8d,
michael@0 159 0xcb, 0x75, 0xdc, 0x24, 0x25, 0x6f, 0x01, 0x92,
michael@0 160 0xa1, 0x11, 0x07, 0x6b, 0x70, 0xac, 0x73, 0xd7,
michael@0 161 0x82, 0x28, 0xdf, 0xab, 0x82, 0x0c, 0x41, 0x0c,
michael@0 162 0x95, 0xb3, 0x3c, 0x3d, 0xea, 0x8a, 0xe6, 0x44,
michael@0 163 0x0a, 0xb8, 0xab, 0x90, 0x15, 0x41, 0x11, 0xe8,
michael@0 164 0x48, 0x7b, 0x8d, 0xb0, 0x9c, 0xd3, 0xf2, 0x69,
michael@0 165 0x66, 0xff, 0x66, 0x4b, 0x70, 0x2b, 0xbf, 0xfb,
michael@0 166 0xd6, 0x68, 0x85, 0x76, 0x1e, 0x34, 0xaa, 0xc5,
michael@0 167 0x57, 0x6e, 0x23, 0x02, 0x08, 0x60, 0x6e, 0xfd,
michael@0 168 0x67, 0x76, 0xe1, 0x7c, 0xc8, 0xcb, 0x51, 0x77,
michael@0 169 0xcf, 0xb1, 0x3b, 0x00, 0x2e, 0xfa, 0x21, 0xcd,
michael@0 170 0x34, 0x76, 0x75, 0x01, 0x19, 0xfe, 0xf8, 0x5d,
michael@0 171 0x43, 0xc5, 0x34, 0xf3, 0x7a, 0x95, 0xdc, 0xc2,
michael@0 172 0x58, 0x07, 0x19, 0x2f, 0x1d, 0x6f, 0x9a, 0x77,
michael@0 173 0x7e, 0x55, 0xaa, 0xe7, 0x5a, 0x50, 0x43, 0xd3 };
michael@0 174
michael@0 175 static const unsigned char subprime[] = { 0x0,
michael@0 176 0xd8, 0x16, 0x23, 0x34, 0x8a, 0x9e, 0x3a, 0xf5,
michael@0 177 0xd9, 0x10, 0x13, 0x35, 0xaa, 0xf3, 0xf3, 0x54,
michael@0 178 0x0b, 0x31, 0x24, 0xf1 };
michael@0 179
michael@0 180 static const unsigned char base[] = {
michael@0 181 0x03, 0x3a, 0xad, 0xfa, 0x3a, 0x0c, 0xea, 0x0a,
michael@0 182 0x4e, 0x43, 0x32, 0x92, 0xbb, 0x87, 0xf1, 0x11,
michael@0 183 0xc0, 0xad, 0x39, 0x38, 0x56, 0x1a, 0xdb, 0x23,
michael@0 184 0x66, 0xb1, 0x08, 0xda, 0xb6, 0x19, 0x51, 0x42,
michael@0 185 0x93, 0x4f, 0xc3, 0x44, 0x43, 0xa8, 0x05, 0xc1,
michael@0 186 0xf8, 0x71, 0x62, 0x6f, 0x3d, 0xe2, 0xab, 0x6f,
michael@0 187 0xd7, 0x80, 0x22, 0x6f, 0xca, 0x0d, 0xf6, 0x9f,
michael@0 188 0x45, 0x27, 0x83, 0xec, 0x86, 0x0c, 0xda, 0xaa,
michael@0 189 0xd6, 0xe0, 0xd0, 0x84, 0xfd, 0xb1, 0x4f, 0xdc,
michael@0 190 0x08, 0xcd, 0x68, 0x3a, 0x77, 0xc2, 0xc5, 0xf1,
michael@0 191 0x99, 0x0f, 0x15, 0x1b, 0x6a, 0x8c, 0x3d, 0x18,
michael@0 192 0x2b, 0x6f, 0xdc, 0x2b, 0xd8, 0xb5, 0x9b, 0xb8,
michael@0 193 0x2d, 0x57, 0x92, 0x1c, 0x46, 0x27, 0xaf, 0x6d,
michael@0 194 0xe1, 0x45, 0xcf, 0x0b, 0x3f, 0xfa, 0x07, 0xcc,
michael@0 195 0x14, 0x8e, 0xe7, 0xb8, 0xaa, 0xd5, 0xd1, 0x36,
michael@0 196 0x1d, 0x7e, 0x5e, 0x7d, 0xfa, 0x5b, 0x77, 0x1f };
michael@0 197
michael@0 198 static const unsigned char h[] = {
michael@0 199 0x41, 0x87, 0x47, 0x79, 0xd8, 0xba, 0x4e, 0xac,
michael@0 200 0x44, 0x4f, 0x6b, 0xd2, 0x16, 0x5e, 0x04, 0xc6,
michael@0 201 0xc2, 0x29, 0x93, 0x5e, 0xbd, 0xc7, 0xa9, 0x8f,
michael@0 202 0x23, 0xa1, 0xc8, 0xee, 0x80, 0x64, 0xd5, 0x67,
michael@0 203 0x3c, 0xba, 0x59, 0x9a, 0x06, 0x0c, 0xcc, 0x29,
michael@0 204 0x56, 0xc0, 0xb2, 0x21, 0xe0, 0x5b, 0x52, 0xcd,
michael@0 205 0x84, 0x73, 0x57, 0xfd, 0xd8, 0xc3, 0x5b, 0x13,
michael@0 206 0x54, 0xd7, 0x4a, 0x06, 0x86, 0x63, 0x09, 0xa5,
michael@0 207 0xb0, 0x59, 0xe2, 0x32, 0x9e, 0x09, 0xa3, 0x9f,
michael@0 208 0x49, 0x62, 0xcc, 0xa6, 0xf9, 0x54, 0xd5, 0xb2,
michael@0 209 0xc3, 0x08, 0x71, 0x7e, 0xe3, 0x37, 0x50, 0xd6,
michael@0 210 0x7b, 0xa7, 0xc2, 0x60, 0xc1, 0xeb, 0x51, 0x32,
michael@0 211 0xfa, 0xad, 0x35, 0x25, 0x17, 0xf0, 0x7f, 0x23,
michael@0 212 0xe5, 0xa8, 0x01, 0x52, 0xcf, 0x2f, 0xd9, 0xa9,
michael@0 213 0xf6, 0x00, 0x21, 0x15, 0xf1, 0xf7, 0x70, 0xb7,
michael@0 214 0x57, 0x8a, 0xd0, 0x59, 0x6a, 0x82, 0xdc, 0x9c };
michael@0 215
michael@0 216 static const unsigned char seed[] = { 0x00,
michael@0 217 0xcc, 0x4c, 0x69, 0x74, 0xf6, 0x72, 0x24, 0x68,
michael@0 218 0x24, 0x4f, 0xd7, 0x50, 0x11, 0x40, 0x81, 0xed,
michael@0 219 0x19, 0x3c, 0x8a, 0x25, 0xbc, 0x78, 0x0a, 0x85,
michael@0 220 0x82, 0x53, 0x70, 0x20, 0xf6, 0x54, 0xa5, 0x1b,
michael@0 221 0xf4, 0x15, 0xcd, 0xff, 0xc4, 0x88, 0xa7, 0x9d,
michael@0 222 0xf3, 0x47, 0x1c, 0x0a, 0xbe, 0x10, 0x29, 0x83,
michael@0 223 0xb9, 0x0f, 0x4c, 0xdf, 0x90, 0x16, 0x83, 0xa2,
michael@0 224 0xb3, 0xe3, 0x2e, 0xc1, 0xc2, 0x24, 0x6a, 0xc4,
michael@0 225 0x9d, 0x57, 0xba, 0xcb, 0x0f, 0x18, 0x75, 0x00,
michael@0 226 0x33, 0x46, 0x82, 0xec, 0xd6, 0x94, 0x77, 0xc3,
michael@0 227 0x4f, 0x4c, 0x58, 0x1c, 0x7f, 0x61, 0x3c, 0x36,
michael@0 228 0xd5, 0x2f, 0xa5, 0x66, 0xd8, 0x2f, 0xce, 0x6e,
michael@0 229 0x8e, 0x20, 0x48, 0x4a, 0xbb, 0xe3, 0xe0, 0xb2,
michael@0 230 0x50, 0x33, 0x63, 0x8a, 0x5b, 0x2d, 0x6a, 0xbe,
michael@0 231 0x4c, 0x28, 0x81, 0x53, 0x5b, 0xe4, 0xf6, 0xfc,
michael@0 232 0x64, 0x06, 0x13, 0x51, 0xeb, 0x4a, 0x91, 0x9c };
michael@0 233
michael@0 234 static const unsigned int counter=1496;
michael@0 235
michael@0 236 static const unsigned char prime2[] = { 0x00,
michael@0 237 0xa4, 0xc2, 0x83, 0x4f, 0x36, 0xd3, 0x4f, 0xae,
michael@0 238 0xa0, 0xb1, 0x47, 0x43, 0xa8, 0x15, 0xee, 0xad,
michael@0 239 0xa3, 0x98, 0xa3, 0x29, 0x45, 0xae, 0x5c, 0xd9,
michael@0 240 0x12, 0x99, 0x09, 0xdc, 0xef, 0x05, 0xb4, 0x98,
michael@0 241 0x05, 0xaa, 0x07, 0xaa, 0x83, 0x89, 0xd7, 0xba,
michael@0 242 0xd1, 0x25, 0x56, 0x58, 0xd1, 0x73, 0x3c, 0xd0,
michael@0 243 0x91, 0x65, 0xbe, 0x27, 0x92, 0x94, 0x86, 0x95,
michael@0 244 0xdb, 0xcf, 0x07, 0x13, 0xa0, 0x85, 0xd6, 0xaa,
michael@0 245 0x6c, 0x1d, 0x63, 0xbf, 0xdd, 0xdf, 0xbc, 0x30,
michael@0 246 0xeb, 0x42, 0x2f, 0x52, 0x11, 0xec, 0x6e, 0x65,
michael@0 247 0xdf, 0x50, 0xbe, 0x28, 0x3d, 0xa4, 0xec, 0x45,
michael@0 248 0x19, 0x4c, 0x13, 0x0f, 0x59, 0x74, 0x57, 0x69,
michael@0 249 0x99, 0x4f, 0x4a, 0x74, 0x7f, 0x8c, 0x9e, 0xa2,
michael@0 250 0xe7, 0x94, 0xc9, 0x70, 0x70, 0xd0, 0xc4, 0xda,
michael@0 251 0x49, 0x5b, 0x7a, 0x7d, 0xd9, 0x71, 0x7c, 0x3b,
michael@0 252 0xdc, 0xd2, 0x8a, 0x74, 0x5f, 0xce, 0x09, 0xa2,
michael@0 253 0xdb, 0xec, 0xa4, 0xba, 0x75, 0xaa, 0x0a, 0x97,
michael@0 254 0xa6, 0x82, 0x25, 0x90, 0x90, 0x37, 0xe4, 0x40,
michael@0 255 0x05, 0x28, 0x8f, 0x98, 0x8e, 0x68, 0x01, 0xaf,
michael@0 256 0x9b, 0x08, 0x2a, 0x9b, 0xd5, 0xb9, 0x8c, 0x14,
michael@0 257 0xbf, 0xba, 0xcb, 0x5b, 0xda, 0x4c, 0x95, 0xb8,
michael@0 258 0xdf, 0x67, 0xa6, 0x6b, 0x76, 0x8c, 0xad, 0x4f,
michael@0 259 0xfd, 0x6a, 0xd6, 0xcc, 0x62, 0x71, 0x30, 0x30,
michael@0 260 0xc1, 0x29, 0x84, 0xe4, 0x8e, 0x32, 0x51, 0xb6,
michael@0 261 0xea, 0xfa, 0xba, 0x00, 0x99, 0x76, 0xea, 0x86,
michael@0 262 0x90, 0xab, 0x2d, 0xe9, 0xfd, 0x1e, 0x8c, 0xcc,
michael@0 263 0x3c, 0x2b, 0x5d, 0x13, 0x1b, 0x47, 0xb4, 0xf5,
michael@0 264 0x09, 0x74, 0x1d, 0xd4, 0x78, 0xb2, 0x42, 0x19,
michael@0 265 0xd6, 0x24, 0xd1, 0x68, 0xbf, 0x11, 0xf1, 0x38,
michael@0 266 0xa0, 0x44, 0x9c, 0xc6, 0x51, 0x33, 0xaa, 0x42,
michael@0 267 0x93, 0x9e, 0x30, 0x58, 0x9e, 0xc0, 0x70, 0xdf,
michael@0 268 0x7e, 0x64, 0xb1, 0xd8, 0x68, 0x75, 0x98, 0xa7 };
michael@0 269
michael@0 270 static const unsigned char subprime2[] = { 0x00,
michael@0 271 0x8e, 0xab, 0xf4, 0xbe, 0x45, 0xeb, 0xa3, 0x58,
michael@0 272 0x4e, 0x60, 0x15, 0x66, 0x5a, 0x4b, 0x25, 0xcf,
michael@0 273 0x45, 0x77, 0x89, 0x3f, 0x73, 0x34, 0x4a, 0xe0,
michael@0 274 0x9e, 0xac, 0xfd, 0xdc, 0xff, 0x9c, 0x8d, 0xe7 };
michael@0 275
michael@0 276 static const unsigned char base2[] = { 0x00,
michael@0 277 0x8d, 0x72, 0x32, 0x46, 0xa6, 0x5c, 0x80, 0xe3,
michael@0 278 0x43, 0x0a, 0x9e, 0x94, 0x35, 0x86, 0xd4, 0x58,
michael@0 279 0xa1, 0xca, 0x22, 0xb9, 0x73, 0x46, 0x0b, 0xfb,
michael@0 280 0x3e, 0x33, 0xf1, 0xd5, 0xd3, 0xb4, 0x26, 0xbf,
michael@0 281 0x50, 0xd7, 0xf2, 0x09, 0x33, 0x6e, 0xc0, 0x31,
michael@0 282 0x1b, 0x6d, 0x07, 0x70, 0x86, 0xca, 0x57, 0xf7,
michael@0 283 0x0b, 0x4a, 0x63, 0xf0, 0x6f, 0xc8, 0x8a, 0xed,
michael@0 284 0x50, 0x60, 0xf3, 0x11, 0xc7, 0x44, 0xf3, 0xce,
michael@0 285 0x4e, 0x50, 0x42, 0x2d, 0x85, 0x33, 0x54, 0x57,
michael@0 286 0x03, 0x8d, 0xdc, 0x66, 0x4d, 0x61, 0x83, 0x17,
michael@0 287 0x1c, 0x7b, 0x0d, 0x65, 0xbc, 0x8f, 0x2c, 0x19,
michael@0 288 0x86, 0xfc, 0xe2, 0x9f, 0x5d, 0x67, 0xfc, 0xd4,
michael@0 289 0xa5, 0xf8, 0x23, 0xa1, 0x1a, 0xa2, 0xe1, 0x11,
michael@0 290 0x15, 0x84, 0x32, 0x01, 0xee, 0x88, 0xf1, 0x55,
michael@0 291 0x30, 0xe9, 0x74, 0x3c, 0x1a, 0x2b, 0x54, 0x45,
michael@0 292 0x2e, 0x39, 0xb9, 0x77, 0xe1, 0x32, 0xaf, 0x2d,
michael@0 293 0x97, 0xe0, 0x21, 0xec, 0xf5, 0x58, 0xe1, 0xc7,
michael@0 294 0x2e, 0xe0, 0x71, 0x3d, 0x29, 0xa4, 0xd6, 0xe2,
michael@0 295 0x5f, 0x85, 0x9c, 0x05, 0x04, 0x46, 0x41, 0x89,
michael@0 296 0x03, 0x3c, 0xfa, 0xb2, 0xcf, 0xfa, 0xd5, 0x67,
michael@0 297 0xcc, 0xec, 0x68, 0xfc, 0x83, 0xd9, 0x1f, 0x2e,
michael@0 298 0x4e, 0x9a, 0x5e, 0x77, 0xa1, 0xff, 0xe6, 0x6f,
michael@0 299 0x04, 0x8b, 0xf9, 0x6b, 0x47, 0xc6, 0x49, 0xd2,
michael@0 300 0x88, 0x6e, 0x29, 0xa3, 0x1b, 0xae, 0xe0, 0x4f,
michael@0 301 0x72, 0x8a, 0x28, 0x94, 0x0c, 0x1d, 0x8c, 0x99,
michael@0 302 0xa2, 0x6f, 0xf8, 0xba, 0x99, 0x90, 0xc7, 0xe5,
michael@0 303 0xb1, 0x3c, 0x10, 0x34, 0x86, 0x6a, 0x6a, 0x1f,
michael@0 304 0x39, 0x63, 0x58, 0xe1, 0x5e, 0x97, 0x95, 0x45,
michael@0 305 0x40, 0x38, 0x45, 0x6f, 0x02, 0xb5, 0x86, 0x6e,
michael@0 306 0xae, 0x2f, 0x32, 0x7e, 0xa1, 0x3a, 0x34, 0x2c,
michael@0 307 0x1c, 0xd3, 0xff, 0x4e, 0x2c, 0x38, 0x1c, 0xaa,
michael@0 308 0x2e, 0x66, 0xbe, 0x32, 0x3e, 0x3c, 0x06, 0x5f };
michael@0 309
michael@0 310 static const unsigned char h2[] = {
michael@0 311 0x30, 0x91, 0xa1, 0x2e, 0x40, 0xa5, 0x7d, 0xf7,
michael@0 312 0xdc, 0xed, 0xee, 0x05, 0xc2, 0x31, 0x91, 0x37,
michael@0 313 0xda, 0xc5, 0xe3, 0x47, 0xb5, 0x35, 0x4b, 0xfd,
michael@0 314 0x18, 0xb2, 0x7e, 0x67, 0x1e, 0x92, 0x22, 0xe7,
michael@0 315 0xf5, 0x00, 0x71, 0xc0, 0x86, 0x8d, 0x90, 0x31,
michael@0 316 0x36, 0x3e, 0xd0, 0x94, 0x5d, 0x2f, 0x9a, 0x68,
michael@0 317 0xd2, 0xf8, 0x3d, 0x5e, 0x84, 0x42, 0x35, 0xda,
michael@0 318 0x75, 0xdd, 0x05, 0xf0, 0x03, 0x31, 0x39, 0xe5,
michael@0 319 0xfd, 0x2f, 0x5a, 0x7d, 0x56, 0xd8, 0x26, 0xa0,
michael@0 320 0x51, 0x5e, 0x32, 0xb4, 0xad, 0xee, 0xd4, 0x89,
michael@0 321 0xae, 0x01, 0x7f, 0xac, 0x86, 0x98, 0x77, 0x26,
michael@0 322 0x5c, 0x31, 0xd2, 0x5e, 0xbb, 0x7f, 0xf5, 0x4c,
michael@0 323 0x9b, 0xf0, 0xa6, 0x37, 0x34, 0x08, 0x86, 0x6b,
michael@0 324 0xce, 0xeb, 0x85, 0x66, 0x0a, 0x26, 0x8a, 0x14,
michael@0 325 0x92, 0x12, 0x74, 0xf4, 0xf0, 0xcb, 0xb5, 0xfc,
michael@0 326 0x38, 0xd5, 0x1e, 0xa1, 0x2f, 0x4a, 0x1a, 0xca,
michael@0 327 0x66, 0xde, 0x6e, 0xe6, 0x6e, 0x1c, 0xef, 0x50,
michael@0 328 0x41, 0x31, 0x09, 0xe7, 0x4a, 0xb8, 0xa3, 0xaa,
michael@0 329 0x5a, 0x22, 0xbd, 0x63, 0x0f, 0xe9, 0x0e, 0xdb,
michael@0 330 0xb3, 0xca, 0x7e, 0x8d, 0x40, 0xb3, 0x3e, 0x0b,
michael@0 331 0x12, 0x8b, 0xb0, 0x80, 0x4d, 0x6d, 0xb0, 0x54,
michael@0 332 0xbb, 0x4c, 0x1d, 0x6c, 0xa0, 0x5c, 0x9d, 0x91,
michael@0 333 0xb3, 0xbb, 0xd9, 0xfc, 0x60, 0xec, 0xc1, 0xbc,
michael@0 334 0xae, 0x72, 0x3f, 0xa5, 0x4f, 0x36, 0x2d, 0x2c,
michael@0 335 0x81, 0x03, 0x86, 0xa2, 0x03, 0x38, 0x36, 0x8e,
michael@0 336 0xad, 0x1d, 0x53, 0xc6, 0xc5, 0x9e, 0xda, 0x08,
michael@0 337 0x35, 0x4f, 0xb2, 0x78, 0xba, 0xd1, 0x22, 0xde,
michael@0 338 0xc4, 0x6b, 0xbe, 0x83, 0x71, 0x0f, 0xee, 0x38,
michael@0 339 0x4a, 0x9f, 0xda, 0x90, 0x93, 0x6b, 0x9a, 0xf2,
michael@0 340 0xeb, 0x23, 0xfe, 0x41, 0x3f, 0xf1, 0xfc, 0xee,
michael@0 341 0x7f, 0x67, 0xa7, 0xb8, 0xab, 0x29, 0xf4, 0x75,
michael@0 342 0x1c, 0xe9, 0xd1, 0x47, 0x7d, 0x86, 0x44, 0xe2 };
michael@0 343
michael@0 344 static const unsigned char seed2[] = { 0x00,
michael@0 345 0xbc, 0xae, 0xc4, 0xea, 0x4e, 0xd2, 0xed, 0x1c,
michael@0 346 0x8d, 0x48, 0xed, 0xf2, 0xa5, 0xb4, 0x18, 0xba,
michael@0 347 0x00, 0xcb, 0x9c, 0x75, 0x8a, 0x39, 0x94, 0x3b,
michael@0 348 0xd0, 0xd6, 0x01, 0xf7, 0xc1, 0xf5, 0x9d, 0xe5,
michael@0 349 0xe3, 0xb4, 0x1d, 0xf5, 0x30, 0xfe, 0x99, 0xe4,
michael@0 350 0x01, 0xab, 0xc0, 0x88, 0x4e, 0x67, 0x8f, 0xc6,
michael@0 351 0x72, 0x39, 0x2e, 0xac, 0x51, 0xec, 0x91, 0x41,
michael@0 352 0x47, 0x71, 0x14, 0x8a, 0x1d, 0xca, 0x88, 0x15,
michael@0 353 0xea, 0xc9, 0x48, 0x9a, 0x71, 0x50, 0x19, 0x38,
michael@0 354 0xdb, 0x4e, 0x65, 0xd5, 0x13, 0xd8, 0x2a, 0xc4,
michael@0 355 0xcd, 0xfd, 0x0c, 0xe3, 0xc3, 0x60, 0xae, 0x6d,
michael@0 356 0x88, 0xf2, 0x3a, 0xd0, 0x64, 0x73, 0x32, 0x89,
michael@0 357 0xcd, 0x0b, 0xb8, 0xc7, 0xa5, 0x27, 0x84, 0xd5,
michael@0 358 0x83, 0x3f, 0x0e, 0x10, 0x63, 0x10, 0x78, 0xac,
michael@0 359 0x6b, 0x56, 0xb2, 0x62, 0x3a, 0x44, 0x56, 0xc0,
michael@0 360 0xe4, 0x33, 0xd7, 0x63, 0x4c, 0xc9, 0x6b, 0xae,
michael@0 361 0xfb, 0xe2, 0x9b, 0xf4, 0x96, 0xc7, 0xf0, 0x2a,
michael@0 362 0x50, 0xde, 0x86, 0x69, 0x4f, 0x42, 0x4b, 0x1c,
michael@0 363 0x7c, 0xa8, 0x6a, 0xfb, 0x54, 0x47, 0x1b, 0x41,
michael@0 364 0x31, 0x9e, 0x0a, 0xc6, 0xc0, 0xbc, 0x88, 0x7f,
michael@0 365 0x5a, 0x42, 0xa9, 0x82, 0x58, 0x32, 0xb3, 0xeb,
michael@0 366 0x54, 0x83, 0x84, 0x26, 0x92, 0xa6, 0xc0, 0x6e,
michael@0 367 0x2b, 0xa6, 0x82, 0x82, 0x43, 0x58, 0x84, 0x53,
michael@0 368 0x31, 0xcf, 0xd0, 0x0a, 0x11, 0x09, 0x44, 0xc8,
michael@0 369 0x11, 0x36, 0xe0, 0x04, 0x85, 0x2e, 0xd1, 0x29,
michael@0 370 0x6b, 0x7b, 0x00, 0x71, 0x5f, 0xef, 0x7b, 0x7a,
michael@0 371 0x2d, 0x91, 0xf9, 0x84, 0x45, 0x4d, 0xc7, 0xe1,
michael@0 372 0xee, 0xd4, 0xb8, 0x61, 0x3b, 0x13, 0xb7, 0xba,
michael@0 373 0x95, 0x39, 0xf6, 0x3d, 0x89, 0xbd, 0xa5, 0x80,
michael@0 374 0x93, 0xf7, 0xe5, 0x17, 0x05, 0xc5, 0x65, 0xb7,
michael@0 375 0xde, 0xc9, 0x9f, 0x04, 0x87, 0xcf, 0x4f, 0x86,
michael@0 376 0xc3, 0x29, 0x7d, 0xb7, 0x89, 0xbf, 0xe3, 0xde };
michael@0 377
michael@0 378 static const unsigned int counter2=210;
michael@0 379
michael@0 380 struct tuple_str {
michael@0 381 CK_RV errNum;
michael@0 382 const char * errString;
michael@0 383 };
michael@0 384
michael@0 385 typedef struct tuple_str tuple_str;
michael@0 386
michael@0 387 static const tuple_str errStrings[] = {
michael@0 388 {CKR_OK , "CKR_OK "},
michael@0 389 {CKR_CANCEL , "CKR_CANCEL "},
michael@0 390 {CKR_HOST_MEMORY , "CKR_HOST_MEMORY "},
michael@0 391 {CKR_SLOT_ID_INVALID , "CKR_SLOT_ID_INVALID "},
michael@0 392 {CKR_GENERAL_ERROR , "CKR_GENERAL_ERROR "},
michael@0 393 {CKR_FUNCTION_FAILED , "CKR_FUNCTION_FAILED "},
michael@0 394 {CKR_ARGUMENTS_BAD , "CKR_ARGUMENTS_BAD "},
michael@0 395 {CKR_NO_EVENT , "CKR_NO_EVENT "},
michael@0 396 {CKR_NEED_TO_CREATE_THREADS , "CKR_NEED_TO_CREATE_THREADS "},
michael@0 397 {CKR_CANT_LOCK , "CKR_CANT_LOCK "},
michael@0 398 {CKR_ATTRIBUTE_READ_ONLY , "CKR_ATTRIBUTE_READ_ONLY "},
michael@0 399 {CKR_ATTRIBUTE_SENSITIVE , "CKR_ATTRIBUTE_SENSITIVE "},
michael@0 400 {CKR_ATTRIBUTE_TYPE_INVALID , "CKR_ATTRIBUTE_TYPE_INVALID "},
michael@0 401 {CKR_ATTRIBUTE_VALUE_INVALID , "CKR_ATTRIBUTE_VALUE_INVALID "},
michael@0 402 {CKR_DATA_INVALID , "CKR_DATA_INVALID "},
michael@0 403 {CKR_DATA_LEN_RANGE , "CKR_DATA_LEN_RANGE "},
michael@0 404 {CKR_DEVICE_ERROR , "CKR_DEVICE_ERROR "},
michael@0 405 {CKR_DEVICE_MEMORY , "CKR_DEVICE_MEMORY "},
michael@0 406 {CKR_DEVICE_REMOVED , "CKR_DEVICE_REMOVED "},
michael@0 407 {CKR_ENCRYPTED_DATA_INVALID , "CKR_ENCRYPTED_DATA_INVALID "},
michael@0 408 {CKR_ENCRYPTED_DATA_LEN_RANGE , "CKR_ENCRYPTED_DATA_LEN_RANGE "},
michael@0 409 {CKR_FUNCTION_CANCELED , "CKR_FUNCTION_CANCELED "},
michael@0 410 {CKR_FUNCTION_NOT_PARALLEL , "CKR_FUNCTION_NOT_PARALLEL "},
michael@0 411 {CKR_FUNCTION_NOT_SUPPORTED , "CKR_FUNCTION_NOT_SUPPORTED "},
michael@0 412 {CKR_KEY_HANDLE_INVALID , "CKR_KEY_HANDLE_INVALID "},
michael@0 413 {CKR_KEY_SIZE_RANGE , "CKR_KEY_SIZE_RANGE "},
michael@0 414 {CKR_KEY_TYPE_INCONSISTENT , "CKR_KEY_TYPE_INCONSISTENT "},
michael@0 415 {CKR_KEY_NOT_NEEDED , "CKR_KEY_NOT_NEEDED "},
michael@0 416 {CKR_KEY_CHANGED , "CKR_KEY_CHANGED "},
michael@0 417 {CKR_KEY_NEEDED , "CKR_KEY_NEEDED "},
michael@0 418 {CKR_KEY_INDIGESTIBLE , "CKR_KEY_INDIGESTIBLE "},
michael@0 419 {CKR_KEY_FUNCTION_NOT_PERMITTED , "CKR_KEY_FUNCTION_NOT_PERMITTED "},
michael@0 420 {CKR_KEY_NOT_WRAPPABLE , "CKR_KEY_NOT_WRAPPABLE "},
michael@0 421 {CKR_KEY_UNEXTRACTABLE , "CKR_KEY_UNEXTRACTABLE "},
michael@0 422 {CKR_MECHANISM_INVALID , "CKR_MECHANISM_INVALID "},
michael@0 423 {CKR_MECHANISM_PARAM_INVALID , "CKR_MECHANISM_PARAM_INVALID "},
michael@0 424 {CKR_OBJECT_HANDLE_INVALID , "CKR_OBJECT_HANDLE_INVALID "},
michael@0 425 {CKR_OPERATION_ACTIVE , "CKR_OPERATION_ACTIVE "},
michael@0 426 {CKR_OPERATION_NOT_INITIALIZED , "CKR_OPERATION_NOT_INITIALIZED "},
michael@0 427 {CKR_PIN_INCORRECT , "CKR_PIN_INCORRECT "},
michael@0 428 {CKR_PIN_INVALID , "CKR_PIN_INVALID "},
michael@0 429 {CKR_PIN_LEN_RANGE , "CKR_PIN_LEN_RANGE "},
michael@0 430 {CKR_PIN_EXPIRED , "CKR_PIN_EXPIRED "},
michael@0 431 {CKR_PIN_LOCKED , "CKR_PIN_LOCKED "},
michael@0 432 {CKR_SESSION_CLOSED , "CKR_SESSION_CLOSED "},
michael@0 433 {CKR_SESSION_COUNT , "CKR_SESSION_COUNT "},
michael@0 434 {CKR_SESSION_HANDLE_INVALID , "CKR_SESSION_HANDLE_INVALID "},
michael@0 435 {CKR_SESSION_PARALLEL_NOT_SUPPORTED , "CKR_SESSION_PARALLEL_NOT_SUPPORTED "},
michael@0 436 {CKR_SESSION_READ_ONLY , "CKR_SESSION_READ_ONLY "},
michael@0 437 {CKR_SESSION_EXISTS , "CKR_SESSION_EXISTS "},
michael@0 438 {CKR_SESSION_READ_ONLY_EXISTS , "CKR_SESSION_READ_ONLY_EXISTS "},
michael@0 439 {CKR_SESSION_READ_WRITE_SO_EXISTS , "CKR_SESSION_READ_WRITE_SO_EXISTS "},
michael@0 440 {CKR_SIGNATURE_INVALID , "CKR_SIGNATURE_INVALID "},
michael@0 441 {CKR_SIGNATURE_LEN_RANGE , "CKR_SIGNATURE_LEN_RANGE "},
michael@0 442 {CKR_TEMPLATE_INCOMPLETE , "CKR_TEMPLATE_INCOMPLETE "},
michael@0 443 {CKR_TEMPLATE_INCONSISTENT , "CKR_TEMPLATE_INCONSISTENT "},
michael@0 444 {CKR_TOKEN_NOT_PRESENT , "CKR_TOKEN_NOT_PRESENT "},
michael@0 445 {CKR_TOKEN_NOT_RECOGNIZED , "CKR_TOKEN_NOT_RECOGNIZED "},
michael@0 446 {CKR_TOKEN_WRITE_PROTECTED , "CKR_TOKEN_WRITE_PROTECTED "},
michael@0 447 {CKR_UNWRAPPING_KEY_HANDLE_INVALID , "CKR_UNWRAPPING_KEY_HANDLE_INVALID "},
michael@0 448 {CKR_UNWRAPPING_KEY_SIZE_RANGE , "CKR_UNWRAPPING_KEY_SIZE_RANGE "},
michael@0 449 {CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"},
michael@0 450 {CKR_USER_ALREADY_LOGGED_IN , "CKR_USER_ALREADY_LOGGED_IN "},
michael@0 451 {CKR_USER_NOT_LOGGED_IN , "CKR_USER_NOT_LOGGED_IN "},
michael@0 452 {CKR_USER_PIN_NOT_INITIALIZED , "CKR_USER_PIN_NOT_INITIALIZED "},
michael@0 453 {CKR_USER_TYPE_INVALID , "CKR_USER_TYPE_INVALID "},
michael@0 454 {CKR_USER_ANOTHER_ALREADY_LOGGED_IN , "CKR_USER_ANOTHER_ALREADY_LOGGED_IN "},
michael@0 455 {CKR_USER_TOO_MANY_TYPES , "CKR_USER_TOO_MANY_TYPES "},
michael@0 456 {CKR_WRAPPED_KEY_INVALID , "CKR_WRAPPED_KEY_INVALID "},
michael@0 457 {CKR_WRAPPED_KEY_LEN_RANGE , "CKR_WRAPPED_KEY_LEN_RANGE "},
michael@0 458 {CKR_WRAPPING_KEY_HANDLE_INVALID , "CKR_WRAPPING_KEY_HANDLE_INVALID "},
michael@0 459 {CKR_WRAPPING_KEY_SIZE_RANGE , "CKR_WRAPPING_KEY_SIZE_RANGE "},
michael@0 460 {CKR_WRAPPING_KEY_TYPE_INCONSISTENT , "CKR_WRAPPING_KEY_TYPE_INCONSISTENT "},
michael@0 461 {CKR_RANDOM_SEED_NOT_SUPPORTED , "CKR_RANDOM_SEED_NOT_SUPPORTED "},
michael@0 462 {CKR_RANDOM_NO_RNG , "CKR_RANDOM_NO_RNG "},
michael@0 463 {CKR_DOMAIN_PARAMS_INVALID , "CKR_DOMAIN_PARAMS_INVALID "},
michael@0 464 {CKR_BUFFER_TOO_SMALL , "CKR_BUFFER_TOO_SMALL "},
michael@0 465 {CKR_SAVED_STATE_INVALID , "CKR_SAVED_STATE_INVALID "},
michael@0 466 {CKR_INFORMATION_SENSITIVE , "CKR_INFORMATION_SENSITIVE "},
michael@0 467 {CKR_STATE_UNSAVEABLE , "CKR_STATE_UNSAVEABLE "},
michael@0 468 {CKR_CRYPTOKI_NOT_INITIALIZED , "CKR_CRYPTOKI_NOT_INITIALIZED "},
michael@0 469 {CKR_CRYPTOKI_ALREADY_INITIALIZED , "CKR_CRYPTOKI_ALREADY_INITIALIZED "},
michael@0 470 {CKR_MUTEX_BAD , "CKR_MUTEX_BAD "},
michael@0 471 {CKR_MUTEX_NOT_LOCKED , "CKR_MUTEX_NOT_LOCKED "},
michael@0 472 {CKR_FUNCTION_REJECTED , "CKR_FUNCTION_REJECTED "},
michael@0 473 {CKR_VENDOR_DEFINED , "CKR_VENDOR_DEFINED "},
michael@0 474 {0xCE534351 , "CKR_NETSCAPE_CERTDB_FAILED "},
michael@0 475 {0xCE534352 , "CKR_NETSCAPE_KEYDB_FAILED "}
michael@0 476
michael@0 477 };
michael@0 478
michael@0 479 static const CK_ULONG numStrings = sizeof(errStrings) / sizeof(tuple_str);
michael@0 480
michael@0 481 /* Returns constant error string for "CRV".
michael@0 482 * Returns "unknown error" if errNum is unknown.
michael@0 483 */
michael@0 484 static const char *
michael@0 485 CK_RVtoStr(CK_RV errNum) {
michael@0 486 CK_ULONG low = 1;
michael@0 487 CK_ULONG high = numStrings - 1;
michael@0 488 CK_ULONG i;
michael@0 489 CK_RV num;
michael@0 490 static int initDone;
michael@0 491
michael@0 492 /* make sure table is in ascending order.
michael@0 493 * binary search depends on it.
michael@0 494 */
michael@0 495 if (!initDone) {
michael@0 496 CK_RV lastNum = CKR_OK;
michael@0 497 for (i = low; i <= high; ++i) {
michael@0 498 num = errStrings[i].errNum;
michael@0 499 if (num <= lastNum) {
michael@0 500 PR_fprintf(PR_STDERR,
michael@0 501 "sequence error in error strings at item %d\n"
michael@0 502 "error %d (%s)\n"
michael@0 503 "should come after \n"
michael@0 504 "error %d (%s)\n",
michael@0 505 (int) i, (int) lastNum, errStrings[i-1].errString,
michael@0 506 (int) num, errStrings[i].errString);
michael@0 507 }
michael@0 508 lastNum = num;
michael@0 509 }
michael@0 510 initDone = 1;
michael@0 511 }
michael@0 512
michael@0 513 /* Do binary search of table. */
michael@0 514 while (low + 1 < high) {
michael@0 515 i = (low + high) / 2;
michael@0 516 num = errStrings[i].errNum;
michael@0 517 if (errNum == num)
michael@0 518 return errStrings[i].errString;
michael@0 519 if (errNum < num)
michael@0 520 high = i;
michael@0 521 else
michael@0 522 low = i;
michael@0 523 }
michael@0 524 if (errNum == errStrings[low].errNum)
michael@0 525 return errStrings[low].errString;
michael@0 526 if (errNum == errStrings[high].errNum)
michael@0 527 return errStrings[high].errString;
michael@0 528 return "unknown error";
michael@0 529 }
michael@0 530
michael@0 531 static void
michael@0 532 pk11error(const char *string, CK_RV crv) {
michael@0 533 PRErrorCode errorcode;
michael@0 534
michael@0 535 PR_fprintf(PR_STDERR, "%s: 0x%08lX, %-26s\n", string, crv, CK_RVtoStr(crv));
michael@0 536
michael@0 537 errorcode = PR_GetError();
michael@0 538 if (errorcode) {
michael@0 539 PR_fprintf(PR_STDERR, "NSPR error code: %d: %s\n", errorcode,
michael@0 540 PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT));
michael@0 541 }
michael@0 542 }
michael@0 543
michael@0 544 static void
michael@0 545 logIt(const char *fmt, ...) {
michael@0 546 va_list args;
michael@0 547
michael@0 548 if (verbose) {
michael@0 549 va_start (args, fmt);
michael@0 550 vprintf(fmt, args);
michael@0 551 va_end(args);
michael@0 552 }
michael@0 553 }
michael@0 554
michael@0 555 static CK_RV
michael@0 556 softokn_Init(CK_FUNCTION_LIST_PTR pFunctionList, const char * configDir,
michael@0 557 const char * dbPrefix) {
michael@0 558
michael@0 559 CK_RV crv = CKR_OK;
michael@0 560 CK_C_INITIALIZE_ARGS initArgs;
michael@0 561 char *moduleSpec = NULL;
michael@0 562
michael@0 563 initArgs.CreateMutex = NULL;
michael@0 564 initArgs.DestroyMutex = NULL;
michael@0 565 initArgs.LockMutex = NULL;
michael@0 566 initArgs.UnlockMutex = NULL;
michael@0 567 initArgs.flags = CKF_OS_LOCKING_OK;
michael@0 568 if (configDir) {
michael@0 569 moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' "
michael@0 570 "keyPrefix='%s' secmod='secmod.db' flags=ReadOnly ",
michael@0 571 configDir, dbPrefix, dbPrefix);
michael@0 572 } else {
michael@0 573 moduleSpec = PR_smprintf("configdir='' certPrefix='' keyPrefix='' "
michael@0 574 "secmod='' flags=noCertDB, noModDB");
michael@0 575 }
michael@0 576 if (!moduleSpec) {
michael@0 577 PR_fprintf(PR_STDERR, "softokn_Init: out of memory error\n");
michael@0 578 return CKR_HOST_MEMORY;
michael@0 579 }
michael@0 580 logIt("moduleSpec %s\n", moduleSpec);
michael@0 581 initArgs.LibraryParameters = (CK_CHAR_PTR *) moduleSpec;
michael@0 582 initArgs.pReserved = NULL;
michael@0 583
michael@0 584 crv = pFunctionList->C_Initialize(&initArgs);
michael@0 585 if (crv != CKR_OK) {
michael@0 586 pk11error("C_Initialize failed", crv);
michael@0 587 goto cleanup;
michael@0 588 }
michael@0 589
michael@0 590 cleanup:
michael@0 591 if (moduleSpec) {
michael@0 592 PR_smprintf_free(moduleSpec);
michael@0 593 }
michael@0 594
michael@0 595 return crv;
michael@0 596 }
michael@0 597
michael@0 598 static char *
michael@0 599 filePasswd(char *pwFile)
michael@0 600 {
michael@0 601 unsigned char phrase[200];
michael@0 602 PRFileDesc *fd;
michael@0 603 PRInt32 nb;
michael@0 604 int i;
michael@0 605
michael@0 606 if (!pwFile)
michael@0 607 return 0;
michael@0 608
michael@0 609 fd = PR_Open(pwFile, PR_RDONLY, 0);
michael@0 610 if (!fd) {
michael@0 611 lperror(pwFile);
michael@0 612 return NULL;
michael@0 613 }
michael@0 614
michael@0 615 nb = PR_Read(fd, phrase, sizeof(phrase));
michael@0 616
michael@0 617 PR_Close(fd);
michael@0 618 /* handle the Windows EOL case */
michael@0 619 i = 0;
michael@0 620 while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++;
michael@0 621 phrase[i] = '\0';
michael@0 622 if (nb == 0) {
michael@0 623 PR_fprintf(PR_STDERR,"password file contains no data\n");
michael@0 624 return NULL;
michael@0 625 }
michael@0 626 return (char*) PL_strdup((char*)phrase);
michael@0 627 }
michael@0 628
michael@0 629 static void
michael@0 630 checkPath(char *string)
michael@0 631 {
michael@0 632 char *src;
michael@0 633 char *dest;
michael@0 634
michael@0 635 /*
michael@0 636 * windows support convert any back slashes to
michael@0 637 * forward slashes.
michael@0 638 */
michael@0 639 for (src=string, dest=string; *src; src++,dest++) {
michael@0 640 if (*src == '\\') {
michael@0 641 *dest = '/';
michael@0 642 }
michael@0 643 }
michael@0 644 dest--;
michael@0 645 /* if the last char is a / set it to 0 */
michael@0 646 if (*dest == '/')
michael@0 647 *dest = 0;
michael@0 648
michael@0 649 }
michael@0 650
michael@0 651 static CK_SLOT_ID *
michael@0 652 getSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
michael@0 653 CK_ULONG slotIndex) {
michael@0 654 CK_RV crv = CKR_OK;
michael@0 655 CK_SLOT_ID *pSlotList = NULL;
michael@0 656 CK_ULONG slotCount;
michael@0 657
michael@0 658 /* Get slot list */
michael@0 659 crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
michael@0 660 NULL, &slotCount);
michael@0 661 if (crv != CKR_OK) {
michael@0 662 pk11error( "C_GetSlotList failed", crv);
michael@0 663 return NULL;
michael@0 664 }
michael@0 665
michael@0 666 if (slotIndex >= slotCount) {
michael@0 667 PR_fprintf(PR_STDERR, "provided slotIndex is greater than the slot count.");
michael@0 668 return NULL;
michael@0 669 }
michael@0 670
michael@0 671 pSlotList = (CK_SLOT_ID *)PR_Malloc(slotCount * sizeof(CK_SLOT_ID));
michael@0 672 if (!pSlotList) {
michael@0 673 lperror("failed to allocate slot list");
michael@0 674 return NULL;
michael@0 675 }
michael@0 676 crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
michael@0 677 pSlotList, &slotCount);
michael@0 678 if (crv != CKR_OK) {
michael@0 679 pk11error( "C_GetSlotList failed", crv);
michael@0 680 if (pSlotList) PR_Free(pSlotList);
michael@0 681 return NULL;
michael@0 682 }
michael@0 683 return pSlotList;
michael@0 684 }
michael@0 685
michael@0 686 int main(int argc, char **argv)
michael@0 687 {
michael@0 688 PLOptState *optstate;
michael@0 689 char *program_name;
michael@0 690 char *libname = NULL;
michael@0 691 PRLibrary *lib;
michael@0 692 PRFileDesc *fd;
michael@0 693 PRStatus rv = PR_SUCCESS;
michael@0 694 const char *input_file = NULL; /* read/create encrypted data from here */
michael@0 695 char *output_file = NULL; /* write new encrypted data here */
michael@0 696 int bytesRead;
michael@0 697 int bytesWritten;
michael@0 698 unsigned char file_buf[512];
michael@0 699 int count=0;
michael@0 700 int keySize = 0;
michael@0 701 int i;
michael@0 702 PRBool verify = PR_FALSE;
michael@0 703 static PRBool FIPSMODE = PR_FALSE;
michael@0 704 PRBool successful = PR_FALSE;
michael@0 705
michael@0 706 #ifdef USES_LINKS
michael@0 707 int ret;
michael@0 708 struct stat stat_buf;
michael@0 709 char link_buf[MAXPATHLEN+1];
michael@0 710 char *link_file = NULL;
michael@0 711 #endif
michael@0 712
michael@0 713 char *pwd = NULL;
michael@0 714 char *configDir = NULL;
michael@0 715 char *dbPrefix = NULL;
michael@0 716 char *disableUnload = NULL;
michael@0 717
michael@0 718 CK_C_GetFunctionList pC_GetFunctionList;
michael@0 719 CK_TOKEN_INFO tokenInfo;
michael@0 720 CK_FUNCTION_LIST_PTR pFunctionList = NULL;
michael@0 721 CK_RV crv = CKR_OK;
michael@0 722 CK_SESSION_HANDLE hRwSession;
michael@0 723 CK_SLOT_ID *pSlotList = NULL;
michael@0 724 CK_ULONG slotIndex = 0;
michael@0 725 CK_MECHANISM digestmech;
michael@0 726 CK_ULONG digestLen = 0;
michael@0 727 CK_BYTE digest[32]; /* SHA256_LENGTH */
michael@0 728 CK_BYTE sign[64]; /* DSA SIGNATURE LENGTH */
michael@0 729 CK_ULONG signLen = 0 ;
michael@0 730 CK_MECHANISM signMech = {
michael@0 731 CKM_DSA, NULL, 0
michael@0 732 };
michael@0 733
michael@0 734 /*** DSA Key ***/
michael@0 735
michael@0 736 CK_MECHANISM dsaKeyPairGenMech;
michael@0 737 CK_ATTRIBUTE dsaPubKeyTemplate[5];
michael@0 738 CK_ATTRIBUTE dsaPrivKeyTemplate[5];
michael@0 739 CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
michael@0 740 CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
michael@0 741
michael@0 742 CK_BYTE dsaPubKey[384];
michael@0 743 CK_ATTRIBUTE dsaPubKeyValue;
michael@0 744
michael@0 745
michael@0 746 program_name = strrchr(argv[0], '/');
michael@0 747 program_name = program_name ? (program_name + 1) : argv[0];
michael@0 748 optstate = PL_CreateOptState (argc, argv, "i:o:f:Fd:hH?k:p:P:vVs:");
michael@0 749 if (optstate == NULL) {
michael@0 750 lperror("PL_CreateOptState failed");
michael@0 751 return 1;
michael@0 752 }
michael@0 753
michael@0 754 while (PL_GetNextOpt (optstate) == PL_OPT_OK) {
michael@0 755 switch (optstate->option) {
michael@0 756
michael@0 757 case 'd':
michael@0 758 if (!optstate->value) {
michael@0 759 PL_DestroyOptState(optstate);
michael@0 760 usage(program_name);
michael@0 761 }
michael@0 762 configDir = PL_strdup(optstate->value);
michael@0 763 checkPath(configDir);
michael@0 764 break;
michael@0 765
michael@0 766 case 'i':
michael@0 767 if (!optstate->value) {
michael@0 768 PL_DestroyOptState(optstate);
michael@0 769 usage(program_name);
michael@0 770 }
michael@0 771 input_file = optstate->value;
michael@0 772 break;
michael@0 773
michael@0 774 case 'o':
michael@0 775 if (!optstate->value) {
michael@0 776 PL_DestroyOptState(optstate);
michael@0 777 usage(program_name);
michael@0 778 }
michael@0 779 output_file = PL_strdup(optstate->value);
michael@0 780 break;
michael@0 781
michael@0 782 case 'k':
michael@0 783 if (!optstate->value) {
michael@0 784 PL_DestroyOptState(optstate);
michael@0 785 usage(program_name);
michael@0 786 }
michael@0 787 keySize = atoi(optstate->value);
michael@0 788 break;
michael@0 789
michael@0 790 case 'f':
michael@0 791 if (!optstate->value) {
michael@0 792 PL_DestroyOptState(optstate);
michael@0 793 usage(program_name);
michael@0 794 }
michael@0 795 pwd = filePasswd((char *)optstate->value);
michael@0 796 if (!pwd) usage(program_name);
michael@0 797 break;
michael@0 798
michael@0 799 case 'F':
michael@0 800 FIPSMODE = PR_TRUE;
michael@0 801 break;
michael@0 802
michael@0 803 case 'p':
michael@0 804 if (!optstate->value) {
michael@0 805 PL_DestroyOptState(optstate);
michael@0 806 usage(program_name);
michael@0 807 }
michael@0 808 pwd = PL_strdup(optstate->value);
michael@0 809 break;
michael@0 810
michael@0 811 case 'P':
michael@0 812 if (!optstate->value) {
michael@0 813 PL_DestroyOptState(optstate);
michael@0 814 usage(program_name);
michael@0 815 }
michael@0 816 dbPrefix = PL_strdup(optstate->value);
michael@0 817 break;
michael@0 818
michael@0 819 case 'v':
michael@0 820 verbose = PR_TRUE;
michael@0 821 break;
michael@0 822
michael@0 823 case 'V':
michael@0 824 verify = PR_TRUE;
michael@0 825 break;
michael@0 826
michael@0 827 case 'H':
michael@0 828 PL_DestroyOptState(optstate);
michael@0 829 long_usage (program_name);
michael@0 830 return 1;
michael@0 831 break;
michael@0 832
michael@0 833 case 'h':
michael@0 834 case '?':
michael@0 835 default:
michael@0 836 PL_DestroyOptState(optstate);
michael@0 837 usage(program_name);
michael@0 838 return 1;
michael@0 839 break;
michael@0 840 }
michael@0 841 }
michael@0 842 PL_DestroyOptState(optstate);
michael@0 843
michael@0 844 if (!input_file) {
michael@0 845 usage(program_name);
michael@0 846 return 1;
michael@0 847 }
michael@0 848
michael@0 849 /* Get the platform-dependent library name of the
michael@0 850 * NSS cryptographic module.
michael@0 851 */
michael@0 852 libname = PR_GetLibraryName(NULL, "softokn3");
michael@0 853 assert(libname != NULL);
michael@0 854 lib = PR_LoadLibrary(libname);
michael@0 855 assert(lib != NULL);
michael@0 856 PR_FreeLibraryName(libname);
michael@0 857
michael@0 858
michael@0 859 if (FIPSMODE) {
michael@0 860 /* FIPSMODE == FC_GetFunctionList */
michael@0 861 /* library path must be set to an already signed softokn3/freebl */
michael@0 862 pC_GetFunctionList = (CK_C_GetFunctionList)
michael@0 863 PR_FindFunctionSymbol(lib, "FC_GetFunctionList");
michael@0 864 } else {
michael@0 865 /* NON FIPS mode == C_GetFunctionList */
michael@0 866 pC_GetFunctionList = (CK_C_GetFunctionList)
michael@0 867 PR_FindFunctionSymbol(lib, "C_GetFunctionList");
michael@0 868 }
michael@0 869 assert(pC_GetFunctionList != NULL);
michael@0 870
michael@0 871 crv = (*pC_GetFunctionList)(&pFunctionList);
michael@0 872 assert(crv == CKR_OK);
michael@0 873
michael@0 874 if (configDir) {
michael@0 875 if (!dbPrefix) {
michael@0 876 dbPrefix = PL_strdup("");
michael@0 877 }
michael@0 878 crv = softokn_Init(pFunctionList, configDir, dbPrefix);
michael@0 879 if (crv != CKR_OK) {
michael@0 880 logIt("Failed to use provided database directory "
michael@0 881 "will just initialize the volatile certdb.\n");
michael@0 882 crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */
michael@0 883 }
michael@0 884 } else {
michael@0 885 crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */
michael@0 886 }
michael@0 887
michael@0 888 if (crv != CKR_OK) {
michael@0 889 pk11error( "Initiailzing softoken failed", crv);
michael@0 890 goto cleanup;
michael@0 891 }
michael@0 892
michael@0 893 pSlotList = getSlotList(pFunctionList, slotIndex);
michael@0 894 if (pSlotList == NULL) {
michael@0 895 PR_fprintf(PR_STDERR, "getSlotList failed");
michael@0 896 goto cleanup;
michael@0 897 }
michael@0 898
michael@0 899 if ((keySize == 0) || (keySize > 1024)) {
michael@0 900 CK_MECHANISM_INFO mechInfo;
michael@0 901 crv = pFunctionList->C_GetMechanismInfo(pSlotList[slotIndex],
michael@0 902 CKM_DSA, &mechInfo);
michael@0 903 if (crv != CKR_OK) {
michael@0 904 pk11error( "Couldn't get mechanism info for DSA", crv);
michael@0 905 goto cleanup;
michael@0 906 }
michael@0 907
michael@0 908 if (keySize && (mechInfo.ulMaxKeySize < keySize)) {
michael@0 909 PR_fprintf(PR_STDERR,
michael@0 910 "token doesn't support DSA2 (Max key size=%d)\n",
michael@0 911 mechInfo.ulMaxKeySize);
michael@0 912 goto cleanup;
michael@0 913 }
michael@0 914
michael@0 915 if ((keySize == 0) && mechInfo.ulMaxKeySize >=2048 ) {
michael@0 916 keySize = 2048;
michael@0 917 } else {
michael@0 918 keySize = 1024;
michael@0 919 }
michael@0 920 }
michael@0 921
michael@0 922 /* DSA key init */
michael@0 923 if (keySize == 1024) {
michael@0 924 dsaPubKeyTemplate[0].type = CKA_PRIME;
michael@0 925 dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR) &prime;
michael@0 926 dsaPubKeyTemplate[0].ulValueLen = sizeof(prime);
michael@0 927 dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
michael@0 928 dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR) &subprime;
michael@0 929 dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime);
michael@0 930 dsaPubKeyTemplate[2].type = CKA_BASE;
michael@0 931 dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR) &base;
michael@0 932 dsaPubKeyTemplate[2].ulValueLen = sizeof(base);
michael@0 933 digestmech.mechanism = CKM_SHA_1;
michael@0 934 digestmech.pParameter = NULL;
michael@0 935 digestmech.ulParameterLen = 0;
michael@0 936 } else if (keySize == 2048) {
michael@0 937 dsaPubKeyTemplate[0].type = CKA_PRIME;
michael@0 938 dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR) &prime2;
michael@0 939 dsaPubKeyTemplate[0].ulValueLen = sizeof(prime2);
michael@0 940 dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
michael@0 941 dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR) &subprime2;
michael@0 942 dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime2);
michael@0 943 dsaPubKeyTemplate[2].type = CKA_BASE;
michael@0 944 dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR) &base2;
michael@0 945 dsaPubKeyTemplate[2].ulValueLen = sizeof(base2);
michael@0 946 digestmech.mechanism = CKM_SHA256;
michael@0 947 digestmech.pParameter = NULL;
michael@0 948 digestmech.ulParameterLen = 0;
michael@0 949 } else {
michael@0 950 /* future - generate pqg */
michael@0 951 PR_fprintf(PR_STDERR, "Only keysizes 1024 and 2048 are supported");
michael@0 952 goto cleanup;
michael@0 953 }
michael@0 954 dsaPubKeyTemplate[3].type = CKA_TOKEN;
michael@0 955 dsaPubKeyTemplate[3].pValue = &false; /* session object */
michael@0 956 dsaPubKeyTemplate[3].ulValueLen = sizeof(false);
michael@0 957 dsaPubKeyTemplate[4].type = CKA_VERIFY;
michael@0 958 dsaPubKeyTemplate[4].pValue = &true;
michael@0 959 dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
michael@0 960 dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN;
michael@0 961 dsaKeyPairGenMech.pParameter = NULL;
michael@0 962 dsaKeyPairGenMech.ulParameterLen = 0;
michael@0 963 dsaPrivKeyTemplate[0].type = CKA_TOKEN;
michael@0 964 dsaPrivKeyTemplate[0].pValue = &false; /* session object */
michael@0 965 dsaPrivKeyTemplate[0].ulValueLen = sizeof(false);
michael@0 966 dsaPrivKeyTemplate[1].type = CKA_PRIVATE;
michael@0 967 dsaPrivKeyTemplate[1].pValue = &true;
michael@0 968 dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
michael@0 969 dsaPrivKeyTemplate[2].type = CKA_SENSITIVE;
michael@0 970 dsaPrivKeyTemplate[2].pValue = &true;
michael@0 971 dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
michael@0 972 dsaPrivKeyTemplate[3].type = CKA_SIGN,
michael@0 973 dsaPrivKeyTemplate[3].pValue = &true;
michael@0 974 dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
michael@0 975 dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE;
michael@0 976 dsaPrivKeyTemplate[4].pValue = &false;
michael@0 977 dsaPrivKeyTemplate[4].ulValueLen = sizeof(false);
michael@0 978
michael@0 979 crv = pFunctionList->C_OpenSession(pSlotList[slotIndex],
michael@0 980 CKF_RW_SESSION | CKF_SERIAL_SESSION,
michael@0 981 NULL, NULL, &hRwSession);
michael@0 982 if (crv != CKR_OK) {
michael@0 983 pk11error( "Opening a read/write session failed", crv);
michael@0 984 goto cleanup;
michael@0 985 }
michael@0 986
michael@0 987 /* check if a password is needed */
michael@0 988 crv = pFunctionList->C_GetTokenInfo(pSlotList[slotIndex], &tokenInfo);
michael@0 989 if (crv != CKR_OK) {
michael@0 990 pk11error( "C_GetTokenInfo failed", crv);
michael@0 991 goto cleanup;
michael@0 992 }
michael@0 993 if (tokenInfo.flags & CKF_LOGIN_REQUIRED) {
michael@0 994 if (pwd) {
michael@0 995 int pwdLen = strlen((const char*)pwd);
michael@0 996 crv = pFunctionList->C_Login(hRwSession, CKU_USER,
michael@0 997 (CK_UTF8CHAR_PTR) pwd, (CK_ULONG)pwdLen);
michael@0 998 if (crv != CKR_OK) {
michael@0 999 pk11error("C_Login failed", crv);
michael@0 1000 goto cleanup;
michael@0 1001 }
michael@0 1002 } else {
michael@0 1003 PR_fprintf(PR_STDERR, "Please provide the password for the token");
michael@0 1004 goto cleanup;
michael@0 1005 }
michael@0 1006 } else if (pwd) {
michael@0 1007 logIt("A password was provided but the password was not used.\n");
michael@0 1008 }
michael@0 1009
michael@0 1010 /* Generate a DSA key pair */
michael@0 1011 logIt("Generate a DSA key pair ... \n");
michael@0 1012 crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech,
michael@0 1013 dsaPubKeyTemplate,
michael@0 1014 NUM_ELEM(dsaPubKeyTemplate),
michael@0 1015 dsaPrivKeyTemplate,
michael@0 1016 NUM_ELEM(dsaPrivKeyTemplate),
michael@0 1017 &hDSApubKey, &hDSAprivKey);
michael@0 1018 if (crv != CKR_OK) {
michael@0 1019 pk11error("DSA key pair generation failed", crv);
michael@0 1020 goto cleanup;
michael@0 1021 }
michael@0 1022
michael@0 1023 /* open the shared library */
michael@0 1024 fd = PR_OpenFile(input_file,PR_RDONLY,0);
michael@0 1025 if (fd == NULL ) {
michael@0 1026 lperror(input_file);
michael@0 1027 goto cleanup;
michael@0 1028 }
michael@0 1029 #ifdef USES_LINKS
michael@0 1030 ret = lstat(input_file, &stat_buf);
michael@0 1031 if (ret < 0) {
michael@0 1032 perror(input_file);
michael@0 1033 goto cleanup;
michael@0 1034 }
michael@0 1035 if (S_ISLNK(stat_buf.st_mode)) {
michael@0 1036 char *dirpath,*dirend;
michael@0 1037 ret = readlink(input_file, link_buf, sizeof(link_buf) - 1);
michael@0 1038 if (ret < 0) {
michael@0 1039 perror(input_file);
michael@0 1040 goto cleanup;
michael@0 1041 }
michael@0 1042 link_buf[ret] = 0;
michael@0 1043 link_file = mkoutput(input_file);
michael@0 1044 /* get the dirname of input_file */
michael@0 1045 dirpath = PL_strdup(input_file);
michael@0 1046 dirend = strrchr(dirpath, '/');
michael@0 1047 if (dirend) {
michael@0 1048 *dirend = '\0';
michael@0 1049 ret = chdir(dirpath);
michael@0 1050 if (ret < 0) {
michael@0 1051 perror(dirpath);
michael@0 1052 goto cleanup;
michael@0 1053 }
michael@0 1054 }
michael@0 1055 PL_strfree(dirpath);
michael@0 1056 input_file = link_buf;
michael@0 1057 /* get the basename of link_file */
michael@0 1058 dirend = strrchr(link_file, '/');
michael@0 1059 if (dirend) {
michael@0 1060 char * tmp_file = NULL;
michael@0 1061 tmp_file = PL_strdup(dirend +1 );
michael@0 1062 PL_strfree(link_file);
michael@0 1063 link_file = tmp_file;
michael@0 1064 }
michael@0 1065 }
michael@0 1066 #endif
michael@0 1067 if (output_file == NULL) {
michael@0 1068 output_file = mkoutput(input_file);
michael@0 1069 }
michael@0 1070
michael@0 1071 /* compute the digest */
michael@0 1072 memset(digest, 0, sizeof(digest));
michael@0 1073 crv = pFunctionList->C_DigestInit(hRwSession, &digestmech);
michael@0 1074 if (crv != CKR_OK) {
michael@0 1075 pk11error("C_DigestInit failed", crv);
michael@0 1076 goto cleanup;
michael@0 1077 }
michael@0 1078
michael@0 1079 /* Digest the file */
michael@0 1080 while ((bytesRead = PR_Read(fd,file_buf,sizeof(file_buf))) > 0) {
michael@0 1081 crv = pFunctionList->C_DigestUpdate(hRwSession, (CK_BYTE_PTR)file_buf,
michael@0 1082 bytesRead);
michael@0 1083 if (crv != CKR_OK) {
michael@0 1084 pk11error("C_DigestUpdate failed", crv);
michael@0 1085 goto cleanup;
michael@0 1086 }
michael@0 1087 count += bytesRead;
michael@0 1088 }
michael@0 1089
michael@0 1090 /* close the input_File */
michael@0 1091 PR_Close(fd);
michael@0 1092 fd = NULL;
michael@0 1093 if (bytesRead < 0) {
michael@0 1094 lperror("0 bytes read from input file");
michael@0 1095 goto cleanup;
michael@0 1096 }
michael@0 1097
michael@0 1098 digestLen = sizeof(digest);
michael@0 1099 crv = pFunctionList->C_DigestFinal(hRwSession, (CK_BYTE_PTR)digest,
michael@0 1100 &digestLen);
michael@0 1101 if (crv != CKR_OK) {
michael@0 1102 pk11error("C_DigestFinal failed", crv);
michael@0 1103 goto cleanup;
michael@0 1104 }
michael@0 1105
michael@0 1106 if (digestLen != sizeof(digest)) {
michael@0 1107 PR_fprintf(PR_STDERR, "digestLen has incorrect length %lu "
michael@0 1108 "it should be %lu \n",digestLen, sizeof(digest));
michael@0 1109 goto cleanup;
michael@0 1110 }
michael@0 1111
michael@0 1112 /* sign the hash */
michael@0 1113 memset(sign, 0, sizeof(sign));
michael@0 1114 /* SignUpdate */
michael@0 1115 crv = pFunctionList->C_SignInit(hRwSession, &signMech, hDSAprivKey);
michael@0 1116 if (crv != CKR_OK) {
michael@0 1117 pk11error("C_SignInit failed", crv);
michael@0 1118 goto cleanup;
michael@0 1119 }
michael@0 1120
michael@0 1121 signLen = sizeof(sign);
michael@0 1122 crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE * ) digest, digestLen,
michael@0 1123 sign, &signLen);
michael@0 1124 if (crv != CKR_OK) {
michael@0 1125 pk11error("C_Sign failed", crv);
michael@0 1126 goto cleanup;
michael@0 1127 }
michael@0 1128
michael@0 1129 if (signLen != sizeof(sign)) {
michael@0 1130 PR_fprintf(PR_STDERR, "signLen has incorrect length %lu "
michael@0 1131 "it should be %lu \n", signLen, sizeof(sign));
michael@0 1132 goto cleanup;
michael@0 1133 }
michael@0 1134
michael@0 1135 if (verify) {
michael@0 1136 crv = pFunctionList->C_VerifyInit(hRwSession, &signMech, hDSApubKey);
michael@0 1137 if (crv != CKR_OK) {
michael@0 1138 pk11error("C_VerifyInit failed", crv);
michael@0 1139 goto cleanup;
michael@0 1140 }
michael@0 1141 crv = pFunctionList->C_Verify(hRwSession, digest, digestLen,
michael@0 1142 sign, signLen);
michael@0 1143 if (crv != CKR_OK) {
michael@0 1144 pk11error("C_Verify failed", crv);
michael@0 1145 goto cleanup;
michael@0 1146 }
michael@0 1147 }
michael@0 1148
michael@0 1149 if (verbose) {
michael@0 1150 int j;
michael@0 1151 PR_fprintf(PR_STDERR,"Library File: %s %d bytes\n",input_file, count);
michael@0 1152 PR_fprintf(PR_STDERR,"Check File: %s\n",output_file);
michael@0 1153 #ifdef USES_LINKS
michael@0 1154 if (link_file) {
michael@0 1155 PR_fprintf(PR_STDERR,"Link: %s\n",link_file);
michael@0 1156 }
michael@0 1157 #endif
michael@0 1158 PR_fprintf(PR_STDERR," hash: %lu bytes\n", digestLen);
michael@0 1159 #define STEP 10
michael@0 1160 for (i=0; i < (int) digestLen; i += STEP) {
michael@0 1161 PR_fprintf(PR_STDERR," ");
michael@0 1162 for (j=0; j < STEP && (i+j) < (int) digestLen; j++) {
michael@0 1163 PR_fprintf(PR_STDERR," %02x", digest[i+j]);
michael@0 1164 }
michael@0 1165 PR_fprintf(PR_STDERR,"\n");
michael@0 1166 }
michael@0 1167 PR_fprintf(PR_STDERR," signature: %lu bytes\n", signLen);
michael@0 1168 for (i=0; i < (int) signLen; i += STEP) {
michael@0 1169 PR_fprintf(PR_STDERR," ");
michael@0 1170 for (j=0; j < STEP && (i+j) < (int) signLen; j++) {
michael@0 1171 PR_fprintf(PR_STDERR," %02x", sign[i+j]);
michael@0 1172 }
michael@0 1173 PR_fprintf(PR_STDERR,"\n");
michael@0 1174 }
michael@0 1175 }
michael@0 1176
michael@0 1177 /* open the target signature file */
michael@0 1178 fd = PR_Open(output_file,PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,0666);
michael@0 1179 if (fd == NULL ) {
michael@0 1180 lperror(output_file);
michael@0 1181 goto cleanup;
michael@0 1182 }
michael@0 1183
michael@0 1184 /*
michael@0 1185 * we write the key out in a straight binary format because very
michael@0 1186 * low level libraries need to read an parse this file. Ideally we should
michael@0 1187 * just derEncode the public key (which would be pretty simple, and be
michael@0 1188 * more general), but then we'd need to link the ASN.1 decoder with the
michael@0 1189 * freebl libraries.
michael@0 1190 */
michael@0 1191
michael@0 1192 file_buf[0] = NSS_SIGN_CHK_MAGIC1;
michael@0 1193 file_buf[1] = NSS_SIGN_CHK_MAGIC2;
michael@0 1194 file_buf[2] = NSS_SIGN_CHK_MAJOR_VERSION;
michael@0 1195 file_buf[3] = NSS_SIGN_CHK_MINOR_VERSION;
michael@0 1196 encodeInt(&file_buf[4],12); /* offset to data start */
michael@0 1197 encodeInt(&file_buf[8],CKK_DSA);
michael@0 1198 bytesWritten = PR_Write(fd,file_buf, 12);
michael@0 1199 if (bytesWritten != 12) {
michael@0 1200 lperror(output_file);
michael@0 1201 goto cleanup;
michael@0 1202 }
michael@0 1203
michael@0 1204 /* get DSA Public KeyValue */
michael@0 1205 memset(dsaPubKey, 0, sizeof(dsaPubKey));
michael@0 1206 dsaPubKeyValue.type =CKA_VALUE;
michael@0 1207 dsaPubKeyValue.pValue = (CK_VOID_PTR) &dsaPubKey;
michael@0 1208 dsaPubKeyValue.ulValueLen = sizeof(dsaPubKey);
michael@0 1209
michael@0 1210 crv = pFunctionList->C_GetAttributeValue(hRwSession, hDSApubKey,
michael@0 1211 &dsaPubKeyValue, 1);
michael@0 1212 if (crv != CKR_OK && crv != CKR_ATTRIBUTE_TYPE_INVALID) {
michael@0 1213 pk11error("C_GetAttributeValue failed", crv);
michael@0 1214 goto cleanup;
michael@0 1215 }
michael@0 1216
michael@0 1217 /* CKA_PRIME */
michael@0 1218 rv = writeItem(fd,dsaPubKeyTemplate[0].pValue,
michael@0 1219 dsaPubKeyTemplate[0].ulValueLen, output_file);
michael@0 1220 if (rv != PR_SUCCESS) goto cleanup;
michael@0 1221 /* CKA_SUBPRIME */
michael@0 1222 rv = writeItem(fd,dsaPubKeyTemplate[1].pValue,
michael@0 1223 dsaPubKeyTemplate[1].ulValueLen, output_file);
michael@0 1224 if (rv != PR_SUCCESS) goto cleanup;
michael@0 1225 /* CKA_BASE */
michael@0 1226 rv = writeItem(fd,dsaPubKeyTemplate[2].pValue,
michael@0 1227 dsaPubKeyTemplate[2].ulValueLen, output_file);
michael@0 1228 if (rv != PR_SUCCESS) goto cleanup;
michael@0 1229 /* DSA Public Key value */
michael@0 1230 rv = writeItem(fd,dsaPubKeyValue.pValue,
michael@0 1231 dsaPubKeyValue.ulValueLen, output_file);
michael@0 1232 if (rv != PR_SUCCESS) goto cleanup;
michael@0 1233 /* DSA SIGNATURE */
michael@0 1234 rv = writeItem(fd,&sign, signLen, output_file);
michael@0 1235 if (rv != PR_SUCCESS) goto cleanup;
michael@0 1236 PR_Close(fd);
michael@0 1237
michael@0 1238 #ifdef USES_LINKS
michael@0 1239 if (link_file) {
michael@0 1240 (void)unlink(link_file);
michael@0 1241 ret = symlink(output_file, link_file);
michael@0 1242 if (ret < 0) {
michael@0 1243 perror(link_file);
michael@0 1244 goto cleanup;
michael@0 1245 }
michael@0 1246 }
michael@0 1247 #endif
michael@0 1248
michael@0 1249 successful = PR_TRUE;
michael@0 1250
michael@0 1251 cleanup:
michael@0 1252 if (pFunctionList) {
michael@0 1253 /* C_Finalize will automatically logout, close session, */
michael@0 1254 /* and delete the temp objects on the token */
michael@0 1255 crv = pFunctionList->C_Finalize(NULL);
michael@0 1256 if (crv != CKR_OK) {
michael@0 1257 pk11error("C_Finalize failed", crv);
michael@0 1258 }
michael@0 1259 }
michael@0 1260 if (pSlotList) {
michael@0 1261 PR_Free(pSlotList);
michael@0 1262 }
michael@0 1263 if (pwd) {
michael@0 1264 PL_strfree(pwd);
michael@0 1265 }
michael@0 1266 if (configDir) {
michael@0 1267 PL_strfree(configDir);
michael@0 1268 }
michael@0 1269 if (dbPrefix) {
michael@0 1270 PL_strfree(dbPrefix);
michael@0 1271 }
michael@0 1272 if (output_file) { /* allocated by mkoutput function */
michael@0 1273 PL_strfree(output_file);
michael@0 1274 }
michael@0 1275 #ifdef USES_LINKS
michael@0 1276 if (link_file) { /* allocated by mkoutput function */
michael@0 1277 PL_strfree(link_file);
michael@0 1278 }
michael@0 1279 #endif
michael@0 1280
michael@0 1281 disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
michael@0 1282 if (!disableUnload) {
michael@0 1283 PR_UnloadLibrary(lib);
michael@0 1284 }
michael@0 1285 PR_Cleanup();
michael@0 1286
michael@0 1287 if (crv != CKR_OK)
michael@0 1288 return crv;
michael@0 1289
michael@0 1290 return (successful) ? 0 : 1;
michael@0 1291 }

mercurial