Wed, 31 Dec 2014 07:16:47 +0100
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) ′ |
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 | } |