clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name shlibsign.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/shlibsign -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/cmd/shlibsign -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c shlibsign.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | #ifdef XP_UNIX |
19 | #define USES_LINKS 1 |
20 | #endif |
21 | |
22 | #define COMPAT_MAJOR 0x01 |
23 | #define COMPAT_MINOR 0x02 |
24 | |
25 | #include <assert.h> |
26 | #include <stdio.h> |
27 | #include <stdlib.h> |
28 | #include <string.h> |
29 | #include <stdarg.h> |
30 | |
31 | #ifdef USES_LINKS |
32 | #include <unistd.h> |
33 | #include <sys/param.h> |
34 | #include <sys/types.h> |
35 | #include <sys/stat.h> |
36 | #endif |
37 | |
38 | |
39 | #include "prlink.h" |
40 | #include "prprf.h" |
41 | #include "prenv.h" |
42 | #include "plgetopt.h" |
43 | #include "prinit.h" |
44 | #include "prmem.h" |
45 | #include "plstr.h" |
46 | #include "prerror.h" |
47 | |
48 | |
49 | #include "pkcs11.h" |
50 | #include "pkcs11t.h" |
51 | |
52 | |
53 | #include "shsign.h" |
54 | |
55 | |
56 | #include "hasht.h" |
57 | |
58 | CK_BBOOL cktrue = CK_TRUE; |
59 | CK_BBOOL ckfalse = CK_FALSE; |
60 | static PRBool verbose = PR_FALSE; |
61 | static PRBool verify = PR_FALSE; |
62 | static PRBool compat = PR_FALSE; |
63 | |
64 | typedef struct HashTableStruct { |
65 | char *name; |
66 | CK_MECHANISM_TYPE hash; |
67 | CK_MECHANISM_TYPE hmac; |
68 | CK_KEY_TYPE keyType; |
69 | HASH_HashType hashType; |
70 | CK_ULONG hashLength; |
71 | } HashTable; |
72 | |
73 | #define CKR_INTERNAL_OUT_FAILURE 0x80111111 |
74 | #define CKR_INTERNAL_IN_FAILURE 0x80222222 |
75 | #define CKM_SHA1 CKM_SHA_1 |
76 | #define CKM_SHA1_HMAC CKM_SHA_1_HMAC |
77 | #define CKK_SHA1_HMAC CKK_SHA_1_HMAC |
78 | #define MKHASH(name, mech) \ |
79 | { \ |
80 | name, CKM_##mech, CKM_##mech##_HMAC, \ |
81 | CKK_##mech##_HMAC, HASH_Alg##mech, mech##_LENGTH \ |
82 | } |
83 | static HashTable hashTable[] = { |
84 | MKHASH("sha-1", SHA1), MKHASH("sha1", SHA1), MKHASH("sha224", SHA224), |
85 | MKHASH("sha256", SHA256), MKHASH("sha384", SHA384), |
86 | MKHASH("sha512", SHA512) |
87 | }; |
88 | static size_t hashTableSize = PR_ARRAY_SIZE(hashTable); |
89 | |
90 | const HashTable * |
91 | findHash(const char *hashName) |
92 | { |
93 | int i; |
94 | |
95 | for (i = 0; i < hashTableSize; i++) { |
96 | if (PL_strcasecmp(hashTable[i].name, hashName) == 0) { |
97 | return &hashTable[i]; |
98 | } |
99 | } |
100 | return NULL; |
101 | } |
102 | |
103 | static void |
104 | usage(const char *program_name) |
105 | { |
106 | int i; |
107 | const char *comma = ""; |
108 | PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError); |
109 | PR_fprintf(debug_out, |
110 | "type %s -H for more detail information.\n", program_name); |
111 | PR_fprintf(debug_out, |
112 | "Usage: %s [-v] [-V] [-o outfile] [-d dbdir] [-f pwfile]\n" |
113 | " [-F] [-p pwd] -[P dbprefix ] [-t hash]" |
114 | " [-D] [-k keysize] [-c]" |
115 | "-i shared_library_name\n", |
116 | program_name); |
117 | PR_fprintf(debug_out, "Valid Hashes: "); |
118 | for (i = 0; i < hashTableSize; i++) { |
119 | PR_fprintf(debug_out, "%s%s", comma, hashTable[i].name); |
120 | comma = ", "; |
121 | } |
122 | PR_fprintf(debug_out, "\n"); |
123 | exit(1); |
124 | } |
125 | |
126 | static void |
127 | long_usage(const char *program_name) |
128 | { |
129 | PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError); |
130 | int i; |
131 | const char *comma = ""; |
132 | PR_fprintf(debug_out, "%s test program usage:\n", program_name); |
133 | PR_fprintf(debug_out, "\t-i <infile> shared_library_name to process\n"); |
134 | PR_fprintf(debug_out, "\t-o <outfile> checksum outfile\n"); |
135 | PR_fprintf(debug_out, "\t-d <path> database path location\n"); |
136 | PR_fprintf(debug_out, "\t-t <hash> Hash for HMAC/or DSA\n"); |
137 | PR_fprintf(debug_out, "\t-D Sign with DSA rather than HMAC\n"); |
138 | PR_fprintf(debug_out, "\t-k <keysize> size of the DSA key\n"); |
139 | PR_fprintf(debug_out, "\t-c Use compatible versions for old NSS\n"); |
140 | PR_fprintf(debug_out, "\t-P <prefix> database prefix\n"); |
141 | PR_fprintf(debug_out, "\t-f <file> password File : echo pw > file \n"); |
142 | PR_fprintf(debug_out, "\t-F FIPS mode\n"); |
143 | PR_fprintf(debug_out, "\t-p <pwd> password\n"); |
144 | PR_fprintf(debug_out, "\t-v verbose output\n"); |
145 | PR_fprintf(debug_out, "\t-V perform Verify operations\n"); |
146 | PR_fprintf(debug_out, "\t-? short help message\n"); |
147 | PR_fprintf(debug_out, "\t-h short help message\n"); |
148 | PR_fprintf(debug_out, "\t-H this help message\n"); |
149 | PR_fprintf(debug_out, "\n\n\tNote: Use of FIPS mode requires your "); |
150 | PR_fprintf(debug_out, "library path is using \n"); |
151 | PR_fprintf(debug_out, "\t pre-existing libraries with generated "); |
152 | PR_fprintf(debug_out, "checksum files\n"); |
153 | PR_fprintf(debug_out, "\t and database in FIPS mode \n"); |
154 | PR_fprintf(debug_out, "Valid Hashes: "); |
155 | for (i = 0; i < hashTableSize; i++) { |
156 | PR_fprintf(debug_out, "%s%s", comma, hashTable[i].name); |
157 | comma = ", "; |
158 | } |
159 | PR_fprintf(debug_out, "\n"); |
160 | exit(1); |
161 | } |
162 | |
163 | static char * |
164 | mkoutput(const char *input) |
165 | { |
166 | int in_len = strlen(input); |
167 | char *output = PR_Malloc(in_len + sizeof(SGN_SUFFIX)); |
168 | int index = in_len + 1 - sizeof("." SHLIB_SUFFIX); |
169 | |
170 | if ((index > 0) && |
171 | (PL_strncmp(&input[index], |
172 | "." SHLIB_SUFFIX, sizeof("." SHLIB_SUFFIX)) == 0)) { |
173 | in_len = index; |
174 | } |
175 | memcpy(output, input, in_len); |
176 | memcpy(&output[in_len], SGN_SUFFIX, sizeof(SGN_SUFFIX)); |
177 | return output; |
178 | } |
179 | |
180 | static void |
181 | lperror(const char *string) |
182 | { |
183 | PRErrorCode errorcode; |
184 | |
185 | errorcode = PR_GetError(); |
186 | PR_fprintf(PR_STDERR, "%s: %d: %s\n", string, errorcode, |
187 | PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT)); |
188 | } |
189 | |
190 | static void |
191 | encodeInt(unsigned char *buf, int val) |
192 | { |
193 | buf[3] = (val >> 0) & 0xff; |
194 | buf[2] = (val >> 8) & 0xff; |
195 | buf[1] = (val >> 16) & 0xff; |
196 | buf[0] = (val >> 24) & 0xff; |
197 | return; |
198 | } |
199 | |
200 | static PRStatus |
201 | writeItem(PRFileDesc *fd, CK_VOID_PTR pValue, CK_ULONG ulValueLen) |
202 | { |
203 | unsigned char buf[4]; |
204 | int bytesWritten; |
205 | if (ulValueLen == 0) { |
206 | PR_fprintf(PR_STDERR, "call to writeItem with 0 bytes of data.\n"); |
207 | return PR_FAILURE; |
208 | } |
209 | |
210 | encodeInt(buf, ulValueLen); |
211 | bytesWritten = PR_Write(fd, buf, 4); |
212 | if (bytesWritten != 4) { |
213 | return PR_FAILURE; |
214 | } |
215 | bytesWritten = PR_Write(fd, pValue, ulValueLen); |
216 | if (bytesWritten < 0 || (CK_ULONG)bytesWritten != ulValueLen) { |
217 | return PR_FAILURE; |
218 | } |
219 | return PR_SUCCESS; |
220 | } |
221 | |
222 | static const unsigned char prime[] = { 0x00, |
223 | 0x97, 0x44, 0x1d, 0xcc, 0x0d, 0x39, 0x0d, 0x8d, |
224 | 0xcb, 0x75, 0xdc, 0x24, 0x25, 0x6f, 0x01, 0x92, |
225 | 0xa1, 0x11, 0x07, 0x6b, 0x70, 0xac, 0x73, 0xd7, |
226 | 0x82, 0x28, 0xdf, 0xab, 0x82, 0x0c, 0x41, 0x0c, |
227 | 0x95, 0xb3, 0x3c, 0x3d, 0xea, 0x8a, 0xe6, 0x44, |
228 | 0x0a, 0xb8, 0xab, 0x90, 0x15, 0x41, 0x11, 0xe8, |
229 | 0x48, 0x7b, 0x8d, 0xb0, 0x9c, 0xd3, 0xf2, 0x69, |
230 | 0x66, 0xff, 0x66, 0x4b, 0x70, 0x2b, 0xbf, 0xfb, |
231 | 0xd6, 0x68, 0x85, 0x76, 0x1e, 0x34, 0xaa, 0xc5, |
232 | 0x57, 0x6e, 0x23, 0x02, 0x08, 0x60, 0x6e, 0xfd, |
233 | 0x67, 0x76, 0xe1, 0x7c, 0xc8, 0xcb, 0x51, 0x77, |
234 | 0xcf, 0xb1, 0x3b, 0x00, 0x2e, 0xfa, 0x21, 0xcd, |
235 | 0x34, 0x76, 0x75, 0x01, 0x19, 0xfe, 0xf8, 0x5d, |
236 | 0x43, 0xc5, 0x34, 0xf3, 0x7a, 0x95, 0xdc, 0xc2, |
237 | 0x58, 0x07, 0x19, 0x2f, 0x1d, 0x6f, 0x9a, 0x77, |
238 | 0x7e, 0x55, 0xaa, 0xe7, 0x5a, 0x50, 0x43, 0xd3 }; |
239 | |
240 | static const unsigned char subprime[] = { 0x0, |
241 | 0xd8, 0x16, 0x23, 0x34, 0x8a, 0x9e, 0x3a, 0xf5, |
242 | 0xd9, 0x10, 0x13, 0x35, 0xaa, 0xf3, 0xf3, 0x54, |
243 | 0x0b, 0x31, 0x24, 0xf1 }; |
244 | |
245 | static const unsigned char base[] = { |
246 | 0x03, 0x3a, 0xad, 0xfa, 0x3a, 0x0c, 0xea, 0x0a, |
247 | 0x4e, 0x43, 0x32, 0x92, 0xbb, 0x87, 0xf1, 0x11, |
248 | 0xc0, 0xad, 0x39, 0x38, 0x56, 0x1a, 0xdb, 0x23, |
249 | 0x66, 0xb1, 0x08, 0xda, 0xb6, 0x19, 0x51, 0x42, |
250 | 0x93, 0x4f, 0xc3, 0x44, 0x43, 0xa8, 0x05, 0xc1, |
251 | 0xf8, 0x71, 0x62, 0x6f, 0x3d, 0xe2, 0xab, 0x6f, |
252 | 0xd7, 0x80, 0x22, 0x6f, 0xca, 0x0d, 0xf6, 0x9f, |
253 | 0x45, 0x27, 0x83, 0xec, 0x86, 0x0c, 0xda, 0xaa, |
254 | 0xd6, 0xe0, 0xd0, 0x84, 0xfd, 0xb1, 0x4f, 0xdc, |
255 | 0x08, 0xcd, 0x68, 0x3a, 0x77, 0xc2, 0xc5, 0xf1, |
256 | 0x99, 0x0f, 0x15, 0x1b, 0x6a, 0x8c, 0x3d, 0x18, |
257 | 0x2b, 0x6f, 0xdc, 0x2b, 0xd8, 0xb5, 0x9b, 0xb8, |
258 | 0x2d, 0x57, 0x92, 0x1c, 0x46, 0x27, 0xaf, 0x6d, |
259 | 0xe1, 0x45, 0xcf, 0x0b, 0x3f, 0xfa, 0x07, 0xcc, |
260 | 0x14, 0x8e, 0xe7, 0xb8, 0xaa, 0xd5, 0xd1, 0x36, |
261 | 0x1d, 0x7e, 0x5e, 0x7d, 0xfa, 0x5b, 0x77, 0x1f |
262 | }; |
263 | |
264 | |
265 | |
266 | |
267 | |
268 | |
269 | |
270 | |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | |
300 | |
301 | |
302 | |
303 | |
304 | |
305 | |
306 | |
307 | static const unsigned char prime2[] = { 0x00, |
308 | 0xa4, 0xc2, 0x83, 0x4f, 0x36, 0xd3, 0x4f, 0xae, |
309 | 0xa0, 0xb1, 0x47, 0x43, 0xa8, 0x15, 0xee, 0xad, |
310 | 0xa3, 0x98, 0xa3, 0x29, 0x45, 0xae, 0x5c, 0xd9, |
311 | 0x12, 0x99, 0x09, 0xdc, 0xef, 0x05, 0xb4, 0x98, |
312 | 0x05, 0xaa, 0x07, 0xaa, 0x83, 0x89, 0xd7, 0xba, |
313 | 0xd1, 0x25, 0x56, 0x58, 0xd1, 0x73, 0x3c, 0xd0, |
314 | 0x91, 0x65, 0xbe, 0x27, 0x92, 0x94, 0x86, 0x95, |
315 | 0xdb, 0xcf, 0x07, 0x13, 0xa0, 0x85, 0xd6, 0xaa, |
316 | 0x6c, 0x1d, 0x63, 0xbf, 0xdd, 0xdf, 0xbc, 0x30, |
317 | 0xeb, 0x42, 0x2f, 0x52, 0x11, 0xec, 0x6e, 0x65, |
318 | 0xdf, 0x50, 0xbe, 0x28, 0x3d, 0xa4, 0xec, 0x45, |
319 | 0x19, 0x4c, 0x13, 0x0f, 0x59, 0x74, 0x57, 0x69, |
320 | 0x99, 0x4f, 0x4a, 0x74, 0x7f, 0x8c, 0x9e, 0xa2, |
321 | 0xe7, 0x94, 0xc9, 0x70, 0x70, 0xd0, 0xc4, 0xda, |
322 | 0x49, 0x5b, 0x7a, 0x7d, 0xd9, 0x71, 0x7c, 0x3b, |
323 | 0xdc, 0xd2, 0x8a, 0x74, 0x5f, 0xce, 0x09, 0xa2, |
324 | 0xdb, 0xec, 0xa4, 0xba, 0x75, 0xaa, 0x0a, 0x97, |
325 | 0xa6, 0x82, 0x25, 0x90, 0x90, 0x37, 0xe4, 0x40, |
326 | 0x05, 0x28, 0x8f, 0x98, 0x8e, 0x68, 0x01, 0xaf, |
327 | 0x9b, 0x08, 0x2a, 0x9b, 0xd5, 0xb9, 0x8c, 0x14, |
328 | 0xbf, 0xba, 0xcb, 0x5b, 0xda, 0x4c, 0x95, 0xb8, |
329 | 0xdf, 0x67, 0xa6, 0x6b, 0x76, 0x8c, 0xad, 0x4f, |
330 | 0xfd, 0x6a, 0xd6, 0xcc, 0x62, 0x71, 0x30, 0x30, |
331 | 0xc1, 0x29, 0x84, 0xe4, 0x8e, 0x32, 0x51, 0xb6, |
332 | 0xea, 0xfa, 0xba, 0x00, 0x99, 0x76, 0xea, 0x86, |
333 | 0x90, 0xab, 0x2d, 0xe9, 0xfd, 0x1e, 0x8c, 0xcc, |
334 | 0x3c, 0x2b, 0x5d, 0x13, 0x1b, 0x47, 0xb4, 0xf5, |
335 | 0x09, 0x74, 0x1d, 0xd4, 0x78, 0xb2, 0x42, 0x19, |
336 | 0xd6, 0x24, 0xd1, 0x68, 0xbf, 0x11, 0xf1, 0x38, |
337 | 0xa0, 0x44, 0x9c, 0xc6, 0x51, 0x33, 0xaa, 0x42, |
338 | 0x93, 0x9e, 0x30, 0x58, 0x9e, 0xc0, 0x70, 0xdf, |
339 | 0x7e, 0x64, 0xb1, 0xd8, 0x68, 0x75, 0x98, 0xa7 }; |
340 | |
341 | static const unsigned char subprime2[] = { 0x00, |
342 | 0x8e, 0xab, 0xf4, 0xbe, 0x45, 0xeb, 0xa3, 0x58, |
343 | 0x4e, 0x60, 0x15, 0x66, 0x5a, 0x4b, 0x25, 0xcf, |
344 | 0x45, 0x77, 0x89, 0x3f, 0x73, 0x34, 0x4a, 0xe0, |
345 | 0x9e, 0xac, 0xfd, 0xdc, 0xff, 0x9c, 0x8d, 0xe7 }; |
346 | |
347 | static const unsigned char base2[] = { 0x00, |
348 | 0x8d, 0x72, 0x32, 0x46, 0xa6, 0x5c, 0x80, 0xe3, |
349 | 0x43, 0x0a, 0x9e, 0x94, 0x35, 0x86, 0xd4, 0x58, |
350 | 0xa1, 0xca, 0x22, 0xb9, 0x73, 0x46, 0x0b, 0xfb, |
351 | 0x3e, 0x33, 0xf1, 0xd5, 0xd3, 0xb4, 0x26, 0xbf, |
352 | 0x50, 0xd7, 0xf2, 0x09, 0x33, 0x6e, 0xc0, 0x31, |
353 | 0x1b, 0x6d, 0x07, 0x70, 0x86, 0xca, 0x57, 0xf7, |
354 | 0x0b, 0x4a, 0x63, 0xf0, 0x6f, 0xc8, 0x8a, 0xed, |
355 | 0x50, 0x60, 0xf3, 0x11, 0xc7, 0x44, 0xf3, 0xce, |
356 | 0x4e, 0x50, 0x42, 0x2d, 0x85, 0x33, 0x54, 0x57, |
357 | 0x03, 0x8d, 0xdc, 0x66, 0x4d, 0x61, 0x83, 0x17, |
358 | 0x1c, 0x7b, 0x0d, 0x65, 0xbc, 0x8f, 0x2c, 0x19, |
359 | 0x86, 0xfc, 0xe2, 0x9f, 0x5d, 0x67, 0xfc, 0xd4, |
360 | 0xa5, 0xf8, 0x23, 0xa1, 0x1a, 0xa2, 0xe1, 0x11, |
361 | 0x15, 0x84, 0x32, 0x01, 0xee, 0x88, 0xf1, 0x55, |
362 | 0x30, 0xe9, 0x74, 0x3c, 0x1a, 0x2b, 0x54, 0x45, |
363 | 0x2e, 0x39, 0xb9, 0x77, 0xe1, 0x32, 0xaf, 0x2d, |
364 | 0x97, 0xe0, 0x21, 0xec, 0xf5, 0x58, 0xe1, 0xc7, |
365 | 0x2e, 0xe0, 0x71, 0x3d, 0x29, 0xa4, 0xd6, 0xe2, |
366 | 0x5f, 0x85, 0x9c, 0x05, 0x04, 0x46, 0x41, 0x89, |
367 | 0x03, 0x3c, 0xfa, 0xb2, 0xcf, 0xfa, 0xd5, 0x67, |
368 | 0xcc, 0xec, 0x68, 0xfc, 0x83, 0xd9, 0x1f, 0x2e, |
369 | 0x4e, 0x9a, 0x5e, 0x77, 0xa1, 0xff, 0xe6, 0x6f, |
370 | 0x04, 0x8b, 0xf9, 0x6b, 0x47, 0xc6, 0x49, 0xd2, |
371 | 0x88, 0x6e, 0x29, 0xa3, 0x1b, 0xae, 0xe0, 0x4f, |
372 | 0x72, 0x8a, 0x28, 0x94, 0x0c, 0x1d, 0x8c, 0x99, |
373 | 0xa2, 0x6f, 0xf8, 0xba, 0x99, 0x90, 0xc7, 0xe5, |
374 | 0xb1, 0x3c, 0x10, 0x34, 0x86, 0x6a, 0x6a, 0x1f, |
375 | 0x39, 0x63, 0x58, 0xe1, 0x5e, 0x97, 0x95, 0x45, |
376 | 0x40, 0x38, 0x45, 0x6f, 0x02, 0xb5, 0x86, 0x6e, |
377 | 0xae, 0x2f, 0x32, 0x7e, 0xa1, 0x3a, 0x34, 0x2c, |
378 | 0x1c, 0xd3, 0xff, 0x4e, 0x2c, 0x38, 0x1c, 0xaa, |
379 | 0x2e, 0x66, 0xbe, 0x32, 0x3e, 0x3c, 0x06, 0x5f }; |
380 | |
381 | |
382 | |
383 | |
384 | |
385 | |
386 | |
387 | |
388 | |
389 | |
390 | |
391 | |
392 | |
393 | |
394 | |
395 | |
396 | |
397 | |
398 | |
399 | |
400 | |
401 | |
402 | |
403 | |
404 | |
405 | |
406 | |
407 | |
408 | |
409 | |
410 | |
411 | |
412 | |
413 | |
414 | |
415 | |
416 | |
417 | |
418 | |
419 | |
420 | |
421 | |
422 | |
423 | |
424 | |
425 | |
426 | |
427 | |
428 | |
429 | |
430 | |
431 | |
432 | |
433 | |
434 | |
435 | |
436 | |
437 | |
438 | |
439 | |
440 | |
441 | |
442 | |
443 | |
444 | |
445 | |
446 | |
447 | |
448 | |
449 | |
450 | |
451 | |
452 | |
453 | |
454 | |
455 | |
456 | struct tuple_str { |
457 | CK_RV errNum; |
458 | const char *errString; |
459 | }; |
460 | |
461 | typedef struct tuple_str tuple_str; |
462 | |
463 | static const tuple_str errStrings[] = { |
464 | { CKR_OK, "CKR_OK " }, |
465 | { CKR_CANCEL, "CKR_CANCEL " }, |
466 | { CKR_HOST_MEMORY, "CKR_HOST_MEMORY " }, |
467 | { CKR_SLOT_ID_INVALID, "CKR_SLOT_ID_INVALID " }, |
468 | { CKR_GENERAL_ERROR, "CKR_GENERAL_ERROR " }, |
469 | { CKR_FUNCTION_FAILED, "CKR_FUNCTION_FAILED " }, |
470 | { CKR_ARGUMENTS_BAD, "CKR_ARGUMENTS_BAD " }, |
471 | { CKR_NO_EVENT, "CKR_NO_EVENT " }, |
472 | { CKR_NEED_TO_CREATE_THREADS, "CKR_NEED_TO_CREATE_THREADS " }, |
473 | { CKR_CANT_LOCK, "CKR_CANT_LOCK " }, |
474 | { CKR_ATTRIBUTE_READ_ONLY, "CKR_ATTRIBUTE_READ_ONLY " }, |
475 | { CKR_ATTRIBUTE_SENSITIVE, "CKR_ATTRIBUTE_SENSITIVE " }, |
476 | { CKR_ATTRIBUTE_TYPE_INVALID, "CKR_ATTRIBUTE_TYPE_INVALID " }, |
477 | { CKR_ATTRIBUTE_VALUE_INVALID, "CKR_ATTRIBUTE_VALUE_INVALID " }, |
478 | { CKR_DATA_INVALID, "CKR_DATA_INVALID " }, |
479 | { CKR_DATA_LEN_RANGE, "CKR_DATA_LEN_RANGE " }, |
480 | { CKR_DEVICE_ERROR, "CKR_DEVICE_ERROR " }, |
481 | { CKR_DEVICE_MEMORY, "CKR_DEVICE_MEMORY " }, |
482 | { CKR_DEVICE_REMOVED, "CKR_DEVICE_REMOVED " }, |
483 | { CKR_ENCRYPTED_DATA_INVALID, "CKR_ENCRYPTED_DATA_INVALID " }, |
484 | { CKR_ENCRYPTED_DATA_LEN_RANGE, "CKR_ENCRYPTED_DATA_LEN_RANGE " }, |
485 | { CKR_FUNCTION_CANCELED, "CKR_FUNCTION_CANCELED " }, |
486 | { CKR_FUNCTION_NOT_PARALLEL, "CKR_FUNCTION_NOT_PARALLEL " }, |
487 | { CKR_FUNCTION_NOT_SUPPORTED, "CKR_FUNCTION_NOT_SUPPORTED " }, |
488 | { CKR_KEY_HANDLE_INVALID, "CKR_KEY_HANDLE_INVALID " }, |
489 | { CKR_KEY_SIZE_RANGE, "CKR_KEY_SIZE_RANGE " }, |
490 | { CKR_KEY_TYPE_INCONSISTENT, "CKR_KEY_TYPE_INCONSISTENT " }, |
491 | { CKR_KEY_NOT_NEEDED, "CKR_KEY_NOT_NEEDED " }, |
492 | { CKR_KEY_CHANGED, "CKR_KEY_CHANGED " }, |
493 | { CKR_KEY_NEEDED, "CKR_KEY_NEEDED " }, |
494 | { CKR_KEY_INDIGESTIBLE, "CKR_KEY_INDIGESTIBLE " }, |
495 | { CKR_KEY_FUNCTION_NOT_PERMITTED, "CKR_KEY_FUNCTION_NOT_PERMITTED " }, |
496 | { CKR_KEY_NOT_WRAPPABLE, "CKR_KEY_NOT_WRAPPABLE " }, |
497 | { CKR_KEY_UNEXTRACTABLE, "CKR_KEY_UNEXTRACTABLE " }, |
498 | { CKR_MECHANISM_INVALID, "CKR_MECHANISM_INVALID " }, |
499 | { CKR_MECHANISM_PARAM_INVALID, "CKR_MECHANISM_PARAM_INVALID " }, |
500 | { CKR_OBJECT_HANDLE_INVALID, "CKR_OBJECT_HANDLE_INVALID " }, |
501 | { CKR_OPERATION_ACTIVE, "CKR_OPERATION_ACTIVE " }, |
502 | { CKR_OPERATION_NOT_INITIALIZED, "CKR_OPERATION_NOT_INITIALIZED " }, |
503 | { CKR_PIN_INCORRECT, "CKR_PIN_INCORRECT " }, |
504 | { CKR_PIN_INVALID, "CKR_PIN_INVALID " }, |
505 | { CKR_PIN_LEN_RANGE, "CKR_PIN_LEN_RANGE " }, |
506 | { CKR_PIN_EXPIRED, "CKR_PIN_EXPIRED " }, |
507 | { CKR_PIN_LOCKED, "CKR_PIN_LOCKED " }, |
508 | { CKR_SESSION_CLOSED, "CKR_SESSION_CLOSED " }, |
509 | { CKR_SESSION_COUNT, "CKR_SESSION_COUNT " }, |
510 | { CKR_SESSION_HANDLE_INVALID, "CKR_SESSION_HANDLE_INVALID " }, |
511 | { CKR_SESSION_PARALLEL_NOT_SUPPORTED, "CKR_SESSION_PARALLEL_NOT_SUPPORTED " }, |
512 | { CKR_SESSION_READ_ONLY, "CKR_SESSION_READ_ONLY " }, |
513 | { CKR_SESSION_EXISTS, "CKR_SESSION_EXISTS " }, |
514 | { CKR_SESSION_READ_ONLY_EXISTS, "CKR_SESSION_READ_ONLY_EXISTS " }, |
515 | { CKR_SESSION_READ_WRITE_SO_EXISTS, "CKR_SESSION_READ_WRITE_SO_EXISTS " }, |
516 | { CKR_SIGNATURE_INVALID, "CKR_SIGNATURE_INVALID " }, |
517 | { CKR_SIGNATURE_LEN_RANGE, "CKR_SIGNATURE_LEN_RANGE " }, |
518 | { CKR_TEMPLATE_INCOMPLETE, "CKR_TEMPLATE_INCOMPLETE " }, |
519 | { CKR_TEMPLATE_INCONSISTENT, "CKR_TEMPLATE_INCONSISTENT " }, |
520 | { CKR_TOKEN_NOT_PRESENT, "CKR_TOKEN_NOT_PRESENT " }, |
521 | { CKR_TOKEN_NOT_RECOGNIZED, "CKR_TOKEN_NOT_RECOGNIZED " }, |
522 | { CKR_TOKEN_WRITE_PROTECTED, "CKR_TOKEN_WRITE_PROTECTED " }, |
523 | { CKR_UNWRAPPING_KEY_HANDLE_INVALID, "CKR_UNWRAPPING_KEY_HANDLE_INVALID " }, |
524 | { CKR_UNWRAPPING_KEY_SIZE_RANGE, "CKR_UNWRAPPING_KEY_SIZE_RANGE " }, |
525 | { CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT" }, |
526 | { CKR_USER_ALREADY_LOGGED_IN, "CKR_USER_ALREADY_LOGGED_IN " }, |
527 | { CKR_USER_NOT_LOGGED_IN, "CKR_USER_NOT_LOGGED_IN " }, |
528 | { CKR_USER_PIN_NOT_INITIALIZED, "CKR_USER_PIN_NOT_INITIALIZED " }, |
529 | { CKR_USER_TYPE_INVALID, "CKR_USER_TYPE_INVALID " }, |
530 | { CKR_USER_ANOTHER_ALREADY_LOGGED_IN, "CKR_USER_ANOTHER_ALREADY_LOGGED_IN " }, |
531 | { CKR_USER_TOO_MANY_TYPES, "CKR_USER_TOO_MANY_TYPES " }, |
532 | { CKR_WRAPPED_KEY_INVALID, "CKR_WRAPPED_KEY_INVALID " }, |
533 | { CKR_WRAPPED_KEY_LEN_RANGE, "CKR_WRAPPED_KEY_LEN_RANGE " }, |
534 | { CKR_WRAPPING_KEY_HANDLE_INVALID, "CKR_WRAPPING_KEY_HANDLE_INVALID " }, |
535 | { CKR_WRAPPING_KEY_SIZE_RANGE, "CKR_WRAPPING_KEY_SIZE_RANGE " }, |
536 | { CKR_WRAPPING_KEY_TYPE_INCONSISTENT, "CKR_WRAPPING_KEY_TYPE_INCONSISTENT " }, |
537 | { CKR_RANDOM_SEED_NOT_SUPPORTED, "CKR_RANDOM_SEED_NOT_SUPPORTED " }, |
538 | { CKR_RANDOM_NO_RNG, "CKR_RANDOM_NO_RNG " }, |
539 | { CKR_DOMAIN_PARAMS_INVALID, "CKR_DOMAIN_PARAMS_INVALID " }, |
540 | { CKR_BUFFER_TOO_SMALL, "CKR_BUFFER_TOO_SMALL " }, |
541 | { CKR_SAVED_STATE_INVALID, "CKR_SAVED_STATE_INVALID " }, |
542 | { CKR_INFORMATION_SENSITIVE, "CKR_INFORMATION_SENSITIVE " }, |
543 | { CKR_STATE_UNSAVEABLE, "CKR_STATE_UNSAVEABLE " }, |
544 | { CKR_CRYPTOKI_NOT_INITIALIZED, "CKR_CRYPTOKI_NOT_INITIALIZED " }, |
545 | { CKR_CRYPTOKI_ALREADY_INITIALIZED, "CKR_CRYPTOKI_ALREADY_INITIALIZED " }, |
546 | { CKR_MUTEX_BAD, "CKR_MUTEX_BAD " }, |
547 | { CKR_MUTEX_NOT_LOCKED, "CKR_MUTEX_NOT_LOCKED " }, |
548 | { CKR_FUNCTION_REJECTED, "CKR_FUNCTION_REJECTED " }, |
549 | { CKR_VENDOR_DEFINED, "CKR_VENDOR_DEFINED " }, |
550 | { 0xCE534351, "CKR_NSS_CERTDB_FAILED " }, |
551 | { 0xCE534352, "CKR_NSS_KEYDB_FAILED " } |
552 | |
553 | }; |
554 | |
555 | static const CK_ULONG numStrings = sizeof(errStrings) / sizeof(tuple_str); |
556 | |
557 | |
558 | |
559 | |
560 | static const char * |
561 | CK_RVtoStr(CK_RV errNum) |
562 | { |
563 | CK_ULONG low = 1; |
564 | CK_ULONG high = numStrings - 1; |
565 | CK_ULONG i; |
566 | CK_RV num; |
567 | static int initDone; |
568 | |
569 | |
570 | |
571 | |
572 | if (!initDone) { |
573 | CK_RV lastNum = CKR_OK; |
574 | for (i = low; i <= high; ++i) { |
575 | num = errStrings[i].errNum; |
576 | if (num <= lastNum) { |
577 | PR_fprintf(PR_STDERR, |
578 | "sequence error in error strings at item %d\n" |
579 | "error %d (%s)\n" |
580 | "should come after \n" |
581 | "error %d (%s)\n", |
582 | (int)i, (int)lastNum, errStrings[i - 1].errString, |
583 | (int)num, errStrings[i].errString); |
584 | } |
585 | lastNum = num; |
586 | } |
587 | initDone = 1; |
588 | } |
589 | |
590 | |
591 | while (low + 1 < high) { |
592 | i = low + (high - low) / 2; |
593 | num = errStrings[i].errNum; |
594 | if (errNum == num) |
595 | return errStrings[i].errString; |
596 | if (errNum < num) |
597 | high = i; |
598 | else |
599 | low = i; |
600 | } |
601 | if (errNum == errStrings[low].errNum) |
602 | return errStrings[low].errString; |
603 | if (errNum == errStrings[high].errNum) |
604 | return errStrings[high].errString; |
605 | return "unknown error"; |
606 | } |
607 | |
608 | static void |
609 | pk11error(const char *string, CK_RV crv) |
610 | { |
611 | PRErrorCode errorcode; |
612 | |
613 | PR_fprintf(PR_STDERR, "%s: 0x%08lX, %-26s\n", string, crv, CK_RVtoStr(crv)); |
614 | |
615 | errorcode = PR_GetError(); |
616 | if (errorcode) { |
617 | PR_fprintf(PR_STDERR, "NSPR error code: %d: %s\n", errorcode, |
618 | PR_ErrorToString(errorcode, PR_LANGUAGE_I_DEFAULT)); |
619 | } |
620 | } |
621 | |
622 | static void |
623 | logIt(const char *fmt, ...) |
624 | { |
625 | va_list args; |
626 | |
627 | if (verbose) { |
628 | va_start(args, fmt); |
629 | vprintf(fmt, args); |
630 | va_end(args); |
631 | } |
632 | } |
633 | |
634 | static CK_RV |
635 | softokn_Init(CK_FUNCTION_LIST_PTR pFunctionList, const char *configDir, |
636 | const char *dbPrefix) |
637 | { |
638 | |
639 | CK_RV crv = CKR_OK; |
640 | CK_C_INITIALIZE_ARGS initArgs; |
641 | char *moduleSpec = NULL; |
642 | |
643 | initArgs.CreateMutex = NULL; |
644 | initArgs.DestroyMutex = NULL; |
645 | initArgs.LockMutex = NULL; |
646 | initArgs.UnlockMutex = NULL; |
647 | initArgs.flags = CKF_OS_LOCKING_OK; |
648 | if (configDir) { |
649 | moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' " |
650 | "keyPrefix='%s' secmod='secmod.db' flags=ReadOnly ", |
651 | configDir, dbPrefix, dbPrefix); |
652 | } else { |
653 | moduleSpec = PR_smprintf("configdir='' certPrefix='' keyPrefix='' " |
654 | "secmod='' flags=noCertDB, noModDB"); |
655 | } |
656 | if (!moduleSpec) { |
657 | PR_fprintf(PR_STDERR, "softokn_Init: out of memory error\n"); |
658 | return CKR_HOST_MEMORY; |
659 | } |
660 | logIt("moduleSpec %s\n", moduleSpec); |
661 | initArgs.LibraryParameters = (CK_CHAR_PTR *)moduleSpec; |
662 | initArgs.pReserved = NULL; |
663 | |
664 | crv = pFunctionList->C_Initialize(&initArgs); |
665 | if (crv != CKR_OK) { |
666 | pk11error("C_Initialize failed", crv); |
667 | goto cleanup; |
668 | } |
669 | |
670 | cleanup: |
671 | if (moduleSpec) { |
672 | PR_smprintf_free(moduleSpec); |
673 | } |
674 | |
675 | return crv; |
676 | } |
677 | |
678 | static char * |
679 | filePasswd(char *pwFile) |
680 | { |
681 | unsigned char phrase[500]; |
682 | PRFileDesc *fd; |
683 | PRInt32 nb; |
684 | int i; |
685 | |
686 | if (!pwFile) |
687 | return 0; |
688 | |
689 | fd = PR_Open(pwFile, PR_RDONLY, 0); |
690 | if (!fd) { |
691 | lperror(pwFile); |
692 | return NULL; |
693 | } |
694 | |
695 | nb = PR_Read(fd, phrase, sizeof(phrase)); |
696 | |
697 | PR_Close(fd); |
698 | |
699 | i = 0; |
700 | while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) |
701 | i++; |
702 | phrase[i] = '\0'; |
703 | if (nb == 0) { |
704 | PR_fprintf(PR_STDERR, "password file contains no data\n"); |
705 | return NULL; |
706 | } |
707 | return (char *)PL_strdup((char *)phrase); |
708 | } |
709 | |
710 | static void |
711 | checkPath(char *string) |
712 | { |
713 | char *src; |
714 | char *dest; |
715 | |
716 | |
717 | |
718 | |
719 | |
720 | for (src = string, dest = string; *src; src++, dest++) { |
721 | if (*src == '\\') { |
722 | *dest = '/'; |
723 | } |
724 | } |
725 | dest--; |
726 | |
727 | if (*dest == '/') |
728 | *dest = 0; |
729 | } |
730 | |
731 | static CK_SLOT_ID * |
732 | getSlotList(CK_FUNCTION_LIST_PTR pFunctionList, |
733 | CK_ULONG slotIndex) |
734 | { |
735 | CK_RV crv = CKR_OK; |
736 | CK_SLOT_ID *pSlotList = NULL; |
737 | CK_ULONG slotCount; |
738 | |
739 | |
740 | crv = pFunctionList->C_GetSlotList(CK_FALSE , |
741 | NULL, &slotCount); |
742 | if (crv != CKR_OK) { |
743 | pk11error("C_GetSlotList failed", crv); |
744 | return NULL; |
745 | } |
746 | |
747 | if (slotIndex >= slotCount) { |
748 | PR_fprintf(PR_STDERR, "provided slotIndex is greater than the slot count."); |
749 | return NULL; |
750 | } |
751 | |
752 | pSlotList = (CK_SLOT_ID *)PR_Malloc(slotCount * sizeof(CK_SLOT_ID)); |
753 | if (!pSlotList) { |
754 | lperror("failed to allocate slot list"); |
755 | return NULL; |
756 | } |
757 | crv = pFunctionList->C_GetSlotList(CK_FALSE , |
758 | pSlotList, &slotCount); |
759 | if (crv != CKR_OK) { |
760 | pk11error("C_GetSlotList failed", crv); |
761 | if (pSlotList) |
762 | PR_Free(pSlotList); |
763 | return NULL; |
764 | } |
765 | return pSlotList; |
766 | } |
767 | |
768 | CK_RV |
769 | shlibSignDSA(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID slot, |
770 | CK_SESSION_HANDLE hRwSession, int keySize, PRFileDesc *ifd, |
771 | PRFileDesc *ofd, const HashTable *hash) |
772 | { |
773 | CK_MECHANISM digestmech; |
774 | CK_ULONG digestLen = 0; |
775 | CK_BYTE digest[HASH_LENGTH_MAX]; |
776 | CK_BYTE sign[64]; |
777 | CK_ULONG signLen = 0; |
778 | CK_ULONG expectedSigLen = sizeof(sign); |
779 | CK_MECHANISM signMech = { |
780 | CKM_DSA, NULL, 0 |
781 | }; |
782 | int bytesRead; |
783 | int bytesWritten; |
784 | unsigned char file_buf[512]; |
785 | NSSSignChkHeader header; |
786 | int count = 0; |
787 | CK_RV crv = CKR_GENERAL_ERROR; |
788 | PRStatus rv = PR_SUCCESS; |
789 | const char *hashName = "sha256"; |
790 | int i; |
791 | |
792 | |
793 | CK_MECHANISM dsaKeyPairGenMech; |
794 | CK_ATTRIBUTE dsaPubKeyTemplate[5]; |
795 | CK_ATTRIBUTE dsaPrivKeyTemplate[5]; |
796 | CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE; |
797 | CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE; |
798 | CK_BYTE dsaPubKey[384]; |
799 | CK_ATTRIBUTE dsaPubKeyValue; |
800 | |
801 | if ((keySize == 0) || (keySize > 1024)) { |
802 | CK_MECHANISM_INFO mechInfo; |
803 | crv = pFunctionList->C_GetMechanismInfo(slot, |
804 | CKM_DSA, &mechInfo); |
805 | if (crv != CKR_OK) { |
806 | pk11error("Couldn't get mechanism info for DSA", crv); |
807 | return crv; |
808 | } |
809 | |
810 | if (keySize && (mechInfo.ulMaxKeySize < keySize)) { |
811 | PR_fprintf(PR_STDERR, |
812 | "token doesn't support DSA2 (Max key size=%d)\n", |
813 | mechInfo.ulMaxKeySize); |
814 | return crv; |
815 | } |
816 | |
817 | if ((keySize == 0) && mechInfo.ulMaxKeySize >= 2048) { |
818 | keySize = 2048; |
819 | } else { |
820 | keySize = 1024; |
821 | } |
822 | } |
823 | |
824 | |
825 | if (keySize == 1024) { |
826 | dsaPubKeyTemplate[0].type = CKA_PRIME; |
827 | dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR)′ |
828 | dsaPubKeyTemplate[0].ulValueLen = sizeof(prime); |
829 | dsaPubKeyTemplate[1].type = CKA_SUBPRIME; |
830 | dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR)&subprime; |
831 | dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime); |
832 | dsaPubKeyTemplate[2].type = CKA_BASE; |
833 | dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR)&base; |
834 | dsaPubKeyTemplate[2].ulValueLen = sizeof(base); |
835 | hashName = "sha-1"; |
836 | expectedSigLen = 32; |
837 | } else if (keySize == 2048) { |
838 | dsaPubKeyTemplate[0].type = CKA_PRIME; |
839 | dsaPubKeyTemplate[0].pValue = (CK_VOID_PTR)&prime2; |
840 | dsaPubKeyTemplate[0].ulValueLen = sizeof(prime2); |
841 | dsaPubKeyTemplate[1].type = CKA_SUBPRIME; |
842 | dsaPubKeyTemplate[1].pValue = (CK_VOID_PTR)&subprime2; |
843 | dsaPubKeyTemplate[1].ulValueLen = sizeof(subprime2); |
844 | dsaPubKeyTemplate[2].type = CKA_BASE; |
845 | dsaPubKeyTemplate[2].pValue = (CK_VOID_PTR)&base2; |
846 | dsaPubKeyTemplate[2].ulValueLen = sizeof(base2); |
847 | digestmech.mechanism = hash ? hash->hash : CKM_SHA256; |
848 | digestmech.pParameter = NULL; |
849 | digestmech.ulParameterLen = 0; |
850 | } else { |
851 | PR_fprintf(PR_STDERR, "Only keysizes 1024 and 2048 are supported"); |
852 | return CKR_GENERAL_ERROR; |
853 | } |
854 | if (hash == NULL) { |
855 | hash = findHash(hashName); |
856 | } |
857 | if (hash == NULL) { |
858 | PR_fprintf(PR_STDERR, |
859 | "Internal error, couldn't find hash '%s' in table.\n", |
860 | hashName); |
861 | return CKR_GENERAL_ERROR; |
862 | } |
863 | digestmech.mechanism = hash->hash; |
864 | digestmech.pParameter = NULL; |
865 | digestmech.ulParameterLen = 0; |
866 | dsaPubKeyTemplate[3].type = CKA_TOKEN; |
867 | dsaPubKeyTemplate[3].pValue = &ckfalse; |
868 | dsaPubKeyTemplate[3].ulValueLen = sizeof(ckfalse); |
869 | dsaPubKeyTemplate[4].type = CKA_VERIFY; |
870 | dsaPubKeyTemplate[4].pValue = &cktrue; |
871 | dsaPubKeyTemplate[4].ulValueLen = sizeof(cktrue); |
872 | dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN; |
873 | dsaKeyPairGenMech.pParameter = NULL; |
874 | dsaKeyPairGenMech.ulParameterLen = 0; |
875 | dsaPrivKeyTemplate[0].type = CKA_TOKEN; |
876 | dsaPrivKeyTemplate[0].pValue = &ckfalse; |
877 | dsaPrivKeyTemplate[0].ulValueLen = sizeof(ckfalse); |
878 | dsaPrivKeyTemplate[1].type = CKA_PRIVATE; |
879 | dsaPrivKeyTemplate[1].pValue = &cktrue; |
880 | dsaPrivKeyTemplate[1].ulValueLen = sizeof(cktrue); |
881 | dsaPrivKeyTemplate[2].type = CKA_SENSITIVE; |
882 | dsaPrivKeyTemplate[2].pValue = &cktrue; |
883 | dsaPrivKeyTemplate[2].ulValueLen = sizeof(cktrue); |
884 | dsaPrivKeyTemplate[3].type = CKA_SIGN, |
885 | dsaPrivKeyTemplate[3].pValue = &cktrue; |
886 | dsaPrivKeyTemplate[3].ulValueLen = sizeof(cktrue); |
887 | dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE; |
888 | dsaPrivKeyTemplate[4].pValue = &ckfalse; |
889 | dsaPrivKeyTemplate[4].ulValueLen = sizeof(ckfalse); |
890 | |
891 | |
892 | logIt("Generate a DSA key pair ... \n"); |
893 | crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech, |
894 | dsaPubKeyTemplate, |
895 | PR_ARRAY_SIZE(dsaPubKeyTemplate), |
896 | dsaPrivKeyTemplate, |
897 | PR_ARRAY_SIZE(dsaPrivKeyTemplate), |
898 | &hDSApubKey, &hDSAprivKey); |
899 | if (crv != CKR_OK) { |
900 | pk11error("DSA key pair generation failed", crv); |
901 | return crv; |
902 | } |
903 | |
904 | |
905 | memset(digest, 0, sizeof(digest)); |
906 | crv = pFunctionList->C_DigestInit(hRwSession, &digestmech); |
907 | if (crv != CKR_OK) { |
908 | pk11error("C_DigestInit failed", crv); |
909 | return crv; |
910 | } |
911 | |
912 | |
913 | while ((bytesRead = PR_Read(ifd, file_buf, sizeof(file_buf))) > 0) { |
914 | crv = pFunctionList->C_DigestUpdate(hRwSession, (CK_BYTE_PTR)file_buf, |
915 | bytesRead); |
916 | if (crv != CKR_OK) { |
917 | pk11error("C_DigestUpdate failed", crv); |
918 | return crv; |
919 | } |
920 | count += bytesRead; |
921 | } |
922 | |
923 | if (bytesRead < 0) { |
924 | lperror("0 bytes read from input file"); |
925 | return CKR_INTERNAL_IN_FAILURE; |
926 | } |
927 | |
928 | digestLen = sizeof(digest); |
929 | crv = pFunctionList->C_DigestFinal(hRwSession, (CK_BYTE_PTR)digest, |
930 | &digestLen); |
931 | if (crv != CKR_OK) { |
932 | pk11error("C_DigestFinal failed", crv); |
933 | return crv; |
934 | } |
935 | |
936 | if (digestLen != hash->hashLength) { |
937 | PR_fprintf(PR_STDERR, "digestLen has incorrect length %lu " |
938 | "it should be %lu \n", |
939 | digestLen, sizeof(digest)); |
940 | return crv; |
941 | } |
942 | |
943 | |
944 | memset(sign, 0, sizeof(sign)); |
945 | |
946 | crv = pFunctionList->C_SignInit(hRwSession, &signMech, hDSAprivKey); |
947 | if (crv != CKR_OK) { |
948 | pk11error("C_SignInit failed", crv); |
949 | return crv; |
950 | } |
951 | |
952 | signLen = sizeof(sign); |
953 | crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE *)digest, digestLen, |
954 | sign, &signLen); |
955 | if (crv != CKR_OK) { |
956 | pk11error("C_Sign failed", crv); |
957 | return crv; |
958 | } |
959 | |
960 | if (signLen != expectedSigLen) { |
961 | PR_fprintf(PR_STDERR, "signLen has incorrect length %lu " |
962 | "it should be %lu \n", |
963 | signLen, expectedSigLen); |
964 | return crv; |
965 | } |
966 | |
967 | if (verify) { |
968 | crv = pFunctionList->C_VerifyInit(hRwSession, &signMech, hDSApubKey); |
969 | if (crv != CKR_OK) { |
970 | pk11error("C_VerifyInit failed", crv); |
971 | return crv; |
972 | } |
973 | crv = pFunctionList->C_Verify(hRwSession, digest, digestLen, |
974 | sign, signLen); |
975 | if (crv != CKR_OK) { |
976 | pk11error("C_Verify failed", crv); |
977 | return crv; |
978 | } |
979 | } |
980 | |
981 | if (verbose) { |
982 | int j; |
983 | PR_fprintf(PR_STDERR, "Library File Size: %d bytes\n", count); |
984 | PR_fprintf(PR_STDERR, " hash: %lu bytes\n", digestLen); |
985 | #define STEP 10 |
986 | for (i = 0; i < (int)digestLen; i += STEP) { |
987 | PR_fprintf(PR_STDERR, " "); |
988 | for (j = 0; j < STEP && (i + j) < (int)digestLen; j++) { |
989 | PR_fprintf(PR_STDERR, " %02x", digest[i + j]); |
990 | } |
991 | PR_fprintf(PR_STDERR, "\n"); |
992 | } |
993 | PR_fprintf(PR_STDERR, " signature: %lu bytes\n", signLen); |
994 | for (i = 0; i < (int)signLen; i += STEP) { |
995 | PR_fprintf(PR_STDERR, " "); |
996 | for (j = 0; j < STEP && (i + j) < (int)signLen; j++) { |
997 | PR_fprintf(PR_STDERR, " %02x", sign[i + j]); |
998 | } |
999 | PR_fprintf(PR_STDERR, "\n"); |
1000 | } |
1001 | } |
1002 | |
1003 | |
1004 | |
1005 | |
1006 | |
1007 | |
1008 | |
1009 | |
1010 | |
1011 | header.magic1 = NSS_SIGN_CHK_MAGIC1; |
1012 | header.magic2 = NSS_SIGN_CHK_MAGIC2; |
1013 | header.majorVersion = compat ? COMPAT_MAJOR : NSS_SIGN_CHK_MAJOR_VERSION; |
1014 | header.minorVersion = compat ? COMPAT_MINOR : NSS_SIGN_CHK_MINOR_VERSION; |
1015 | encodeInt(header.offset, sizeof(header)); |
1016 | encodeInt(header.type, CKK_DSA); |
1017 | bytesWritten = PR_Write(ofd, &header, sizeof(header)); |
1018 | if (bytesWritten != sizeof(header)) { |
1019 | return CKR_INTERNAL_OUT_FAILURE; |
1020 | } |
1021 | |
1022 | |
1023 | memset(dsaPubKey, 0, sizeof(dsaPubKey)); |
1024 | dsaPubKeyValue.type = CKA_VALUE; |
1025 | dsaPubKeyValue.pValue = (CK_VOID_PTR)&dsaPubKey; |
1026 | dsaPubKeyValue.ulValueLen = sizeof(dsaPubKey); |
1027 | |
1028 | crv = pFunctionList->C_GetAttributeValue(hRwSession, hDSApubKey, |
1029 | &dsaPubKeyValue, 1); |
1030 | if (crv != CKR_OK && crv != CKR_ATTRIBUTE_TYPE_INVALID) { |
1031 | pk11error("C_GetAttributeValue failed", crv); |
1032 | return crv; |
1033 | } |
1034 | |
1035 | |
1036 | rv = writeItem(ofd, dsaPubKeyTemplate[0].pValue, |
1037 | dsaPubKeyTemplate[0].ulValueLen); |
1038 | if (rv != PR_SUCCESS) { |
1039 | return CKR_INTERNAL_OUT_FAILURE; |
1040 | } |
1041 | |
1042 | rv = writeItem(ofd, dsaPubKeyTemplate[1].pValue, |
1043 | dsaPubKeyTemplate[1].ulValueLen); |
1044 | if (rv != PR_SUCCESS) { |
1045 | return CKR_INTERNAL_OUT_FAILURE; |
1046 | } |
1047 | |
1048 | rv = writeItem(ofd, dsaPubKeyTemplate[2].pValue, |
1049 | dsaPubKeyTemplate[2].ulValueLen); |
1050 | if (rv != PR_SUCCESS) { |
1051 | return CKR_INTERNAL_OUT_FAILURE; |
1052 | } |
1053 | |
1054 | rv = writeItem(ofd, dsaPubKeyValue.pValue, |
1055 | dsaPubKeyValue.ulValueLen); |
1056 | if (rv != PR_SUCCESS) { |
1057 | return CKR_INTERNAL_OUT_FAILURE; |
1058 | } |
1059 | |
1060 | rv = writeItem(ofd, &sign, signLen); |
1061 | if (rv != PR_SUCCESS) { |
1062 | return CKR_INTERNAL_OUT_FAILURE; |
1063 | } |
1064 | |
1065 | return CKR_OK; |
1066 | } |
1067 | |
1068 | CK_RV |
1069 | shlibSignHMAC(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID slot, |
1070 | CK_SESSION_HANDLE hRwSession, int keySize, PRFileDesc *ifd, |
1071 | PRFileDesc *ofd, const HashTable *hash) |
1072 | { |
1073 | CK_MECHANISM hmacMech = { 0, NULL, 0 }; |
1074 | CK_MECHANISM hmacKeyGenMech = { 0, NULL, 0 }; |
1075 | CK_BYTE keyBuf[HASH_LENGTH_MAX]; |
1076 | CK_ULONG keyLen = 0; |
1077 | CK_BYTE sign[HASH_LENGTH_MAX]; |
1078 | CK_ULONG signLen = 0; |
1079 | int bytesRead; |
1080 | int bytesWritten; |
1081 | unsigned char file_buf[512]; |
1082 | NSSSignChkHeader header; |
1083 | int count = 0; |
1084 | CK_RV crv = CKR_GENERAL_ERROR; |
1085 | PRStatus rv = PR_SUCCESS; |
1086 | int i; |
1087 | |
1088 | |
1089 | CK_ATTRIBUTE hmacKeyTemplate[7]; |
1090 | CK_ATTRIBUTE hmacKeyValue; |
1091 | CK_OBJECT_HANDLE hHMACKey = CK_INVALID_HANDLE; |
1092 | |
1093 | if (hash == NULL) { |
| |
1094 | hash = findHash("sha256"); |
| 50 | | Value assigned to 'hash' | |
|
1095 | } |
1096 | if (hash == NULL) { |
| 51 | | Assuming 'hash' is equal to NULL | |
|
| |
1097 | PR_fprintf(PR_STDERR, |
1098 | "Internal error:Could find sha256 entry in table.\n"); |
1099 | } |
1100 | |
1101 | hmacKeyTemplate[0].type = CKA_TOKEN; |
1102 | hmacKeyTemplate[0].pValue = &ckfalse; |
1103 | hmacKeyTemplate[0].ulValueLen = sizeof(ckfalse); |
1104 | hmacKeyTemplate[1].type = CKA_PRIVATE; |
1105 | hmacKeyTemplate[1].pValue = &cktrue; |
1106 | hmacKeyTemplate[1].ulValueLen = sizeof(cktrue); |
1107 | hmacKeyTemplate[2].type = CKA_SENSITIVE; |
1108 | hmacKeyTemplate[2].pValue = &ckfalse; |
1109 | hmacKeyTemplate[2].ulValueLen = sizeof(cktrue); |
1110 | hmacKeyTemplate[3].type = CKA_SIGN; |
1111 | hmacKeyTemplate[3].pValue = &cktrue; |
1112 | hmacKeyTemplate[3].ulValueLen = sizeof(cktrue); |
1113 | hmacKeyTemplate[4].type = CKA_EXTRACTABLE; |
1114 | hmacKeyTemplate[4].pValue = &ckfalse; |
1115 | hmacKeyTemplate[4].ulValueLen = sizeof(ckfalse); |
1116 | hmacKeyTemplate[5].type = CKA_VALUE_LEN; |
1117 | hmacKeyTemplate[5].pValue = (void *)&hash->hashLength; |
1118 | hmacKeyTemplate[5].ulValueLen = sizeof(hash->hashLength); |
1119 | hmacKeyTemplate[6].type = CKA_KEY_TYPE; |
1120 | hmacKeyTemplate[6].pValue = (void *)&hash->keyType; |
1121 | hmacKeyTemplate[6].ulValueLen = sizeof(hash->keyType); |
1122 | hmacKeyGenMech.mechanism = CKM_GENERIC_SECRET_KEY_GEN; |
1123 | hmacMech.mechanism = hash->hmac; |
| 53 | | Access to field 'hmac' results in a dereference of a null pointer (loaded from variable 'hash') |
|
1124 | |
1125 | |
1126 | logIt("Generate an HMAC key ... \n"); |
1127 | crv = pFunctionList->C_GenerateKey(hRwSession, &hmacKeyGenMech, |
1128 | hmacKeyTemplate, |
1129 | PR_ARRAY_SIZE(hmacKeyTemplate), |
1130 | &hHMACKey); |
1131 | if (crv != CKR_OK) { |
1132 | pk11error("HMAC key generation failed", crv); |
1133 | return crv; |
1134 | } |
1135 | |
1136 | |
1137 | memset(sign, 0, sizeof(sign)); |
1138 | crv = pFunctionList->C_SignInit(hRwSession, &hmacMech, hHMACKey); |
1139 | if (crv != CKR_OK) { |
1140 | pk11error("C_SignInit failed", crv); |
1141 | return crv; |
1142 | } |
1143 | |
1144 | |
1145 | while ((bytesRead = PR_Read(ifd, file_buf, sizeof(file_buf))) > 0) { |
1146 | crv = pFunctionList->C_SignUpdate(hRwSession, (CK_BYTE_PTR)file_buf, |
1147 | bytesRead); |
1148 | if (crv != CKR_OK) { |
1149 | pk11error("C_SignUpdate failed", crv); |
1150 | return crv; |
1151 | } |
1152 | count += bytesRead; |
1153 | } |
1154 | |
1155 | if (bytesRead < 0) { |
1156 | lperror("0 bytes read from input file"); |
1157 | return CKR_INTERNAL_IN_FAILURE; |
1158 | } |
1159 | |
1160 | signLen = sizeof(sign); |
1161 | crv = pFunctionList->C_SignFinal(hRwSession, (CK_BYTE_PTR)sign, |
1162 | &signLen); |
1163 | if (crv != CKR_OK) { |
1164 | pk11error("C_SignFinal failed", crv); |
1165 | return crv; |
1166 | } |
1167 | |
1168 | if (signLen != hash->hashLength) { |
1169 | PR_fprintf(PR_STDERR, "digestLen has incorrect length %lu " |
1170 | "it should be %lu \n", |
1171 | signLen, hash->hashLength); |
1172 | return crv; |
1173 | } |
1174 | |
1175 | memset(keyBuf, 0, sizeof(keyBuf)); |
1176 | hmacKeyValue.type = CKA_VALUE; |
1177 | hmacKeyValue.pValue = (CK_VOID_PTR)&keyBuf; |
1178 | hmacKeyValue.ulValueLen = sizeof(keyBuf); |
1179 | |
1180 | crv = pFunctionList->C_GetAttributeValue(hRwSession, hHMACKey, |
1181 | &hmacKeyValue, 1); |
1182 | if (crv != CKR_OK && crv != CKR_ATTRIBUTE_TYPE_INVALID) { |
1183 | pk11error("C_GetAttributeValue failed", crv); |
1184 | return crv; |
1185 | } |
1186 | keyLen = hmacKeyValue.ulValueLen; |
1187 | |
1188 | if (verbose) { |
1189 | int j; |
1190 | PR_fprintf(PR_STDERR, "Library File Size: %d bytes\n", count); |
1191 | PR_fprintf(PR_STDERR, " key: %lu bytes\n", keyLen); |
1192 | #define STEP 10 |
1193 | for (i = 0; i < (int)keyLen; i += STEP) { |
1194 | PR_fprintf(PR_STDERR, " "); |
1195 | for (j = 0; j < STEP && (i + j) < (int)keyLen; j++) { |
1196 | PR_fprintf(PR_STDERR, " %02x", keyBuf[i + j]); |
1197 | } |
1198 | PR_fprintf(PR_STDERR, "\n"); |
1199 | } |
1200 | PR_fprintf(PR_STDERR, " signature: %lu bytes\n", signLen); |
1201 | for (i = 0; i < (int)signLen; i += STEP) { |
1202 | PR_fprintf(PR_STDERR, " "); |
1203 | for (j = 0; j < STEP && (i + j) < (int)signLen; j++) { |
1204 | PR_fprintf(PR_STDERR, " %02x", sign[i + j]); |
1205 | } |
1206 | PR_fprintf(PR_STDERR, "\n"); |
1207 | } |
1208 | } |
1209 | |
1210 | |
1211 | |
1212 | |
1213 | |
1214 | |
1215 | |
1216 | |
1217 | |
1218 | header.magic1 = NSS_SIGN_CHK_MAGIC1; |
1219 | header.magic2 = NSS_SIGN_CHK_MAGIC2; |
1220 | header.majorVersion = NSS_SIGN_CHK_MAJOR_VERSION; |
1221 | header.minorVersion = NSS_SIGN_CHK_MINOR_VERSION; |
1222 | encodeInt(header.offset, sizeof(header)); |
1223 | encodeInt(header.type, NSS_SIGN_CHK_FLAG_HMAC | hash->hashType); |
1224 | bytesWritten = PR_Write(ofd, &header, sizeof(header)); |
1225 | if (bytesWritten != sizeof(header)) { |
1226 | return CKR_INTERNAL_OUT_FAILURE; |
1227 | } |
1228 | |
1229 | |
1230 | rv = writeItem(ofd, keyBuf, keyLen); |
1231 | if (rv != PR_SUCCESS) { |
1232 | return CKR_INTERNAL_OUT_FAILURE; |
1233 | } |
1234 | |
1235 | rv = writeItem(ofd, &sign, signLen); |
1236 | if (rv != PR_SUCCESS) { |
1237 | return CKR_INTERNAL_OUT_FAILURE; |
1238 | } |
1239 | |
1240 | return CKR_OK; |
1241 | } |
1242 | |
1243 | int |
1244 | main(int argc, char **argv) |
1245 | { |
1246 | PLOptState *optstate; |
1247 | char *program_name; |
1248 | char *libname = NULL; |
1249 | PRLibrary *lib = NULL; |
1250 | PRFileDesc *ifd = NULL; |
1251 | PRFileDesc *ofd = NULL; |
1252 | const char *input_file = NULL; |
1253 | char *output_file = NULL; |
1254 | unsigned int keySize = 0; |
1255 | static PRBool FIPSMODE = PR_FALSE; |
1256 | static PRBool useDSA = PR_FALSE; |
1257 | PRBool successful = PR_FALSE; |
1258 | const HashTable *hash = NULL; |
1259 | |
1260 | #ifdef USES_LINKS |
1261 | int ret; |
1262 | struct stat stat_buf; |
1263 | char link_buf[MAXPATHLEN + 1]; |
1264 | char *link_file = NULL; |
1265 | #endif |
1266 | |
1267 | char *pwd = NULL; |
1268 | char *configDir = NULL; |
1269 | char *dbPrefix = NULL; |
1270 | char *disableUnload = NULL; |
1271 | |
1272 | CK_C_GetFunctionList pC_GetFunctionList; |
1273 | CK_TOKEN_INFO tokenInfo; |
1274 | CK_FUNCTION_LIST_PTR pFunctionList = NULL; |
1275 | CK_RV crv = CKR_OK; |
1276 | CK_SESSION_HANDLE hRwSession; |
1277 | CK_SLOT_ID *pSlotList = NULL; |
1278 | CK_ULONG slotIndex = 0; |
1279 | |
1280 | program_name = strrchr(argv[0], '/'); |
1281 | program_name = program_name ? (program_name + 1) : argv[0]; |
| 1 | Assuming 'program_name' is non-null | |
|
| |
1282 | optstate = PL_CreateOptState(argc, argv, "i:o:f:Fd:hH?k:p:P:vVs:t:Dc"); |
1283 | if (optstate == NULL) { |
| 3 | | Assuming 'optstate' is not equal to NULL | |
|
| |
1284 | lperror("PL_CreateOptState failed"); |
1285 | return 1; |
1286 | } |
1287 | |
1288 | while (PL_GetNextOpt(optstate) == PL_OPT_OK) { |
| 5 | | Assuming the condition is true | |
|
| 6 | | Loop condition is true. Entering loop body | |
|
| 10 | | Execution continues on line 1288 | |
|
| 11 | | Assuming the condition is false | |
|
| 12 | | Loop condition is false. Execution continues on line 1397 | |
|
1289 | switch (optstate->option) { |
| 7 | | Control jumps to 'case 105:' at line 1308 | |
|
1290 | |
1291 | case 'd': |
1292 | if (!optstate->value) { |
1293 | PL_DestroyOptState(optstate); |
1294 | usage(program_name); |
1295 | } |
1296 | configDir = PL_strdup(optstate->value); |
1297 | checkPath(configDir); |
1298 | break; |
1299 | |
1300 | case 'D': |
1301 | useDSA = PR_TRUE; |
1302 | break; |
1303 | |
1304 | case 'c': |
1305 | compat = PR_TRUE; |
1306 | break; |
1307 | |
1308 | case 'i': |
1309 | if (!optstate->value) { |
| 8 | | Assuming field 'value' is non-null | |
|
| |
1310 | PL_DestroyOptState(optstate); |
1311 | usage(program_name); |
1312 | } |
1313 | input_file = optstate->value; |
1314 | break; |
1315 | |
1316 | case 'o': |
1317 | if (!optstate->value) { |
1318 | PL_DestroyOptState(optstate); |
1319 | usage(program_name); |
1320 | } |
1321 | output_file = PL_strdup(optstate->value); |
1322 | break; |
1323 | |
1324 | case 'k': |
1325 | if (!optstate->value) { |
1326 | PL_DestroyOptState(optstate); |
1327 | usage(program_name); |
1328 | } |
1329 | keySize = atoi(optstate->value); |
1330 | break; |
1331 | |
1332 | case 'f': |
1333 | if (!optstate->value) { |
1334 | PL_DestroyOptState(optstate); |
1335 | usage(program_name); |
1336 | } |
1337 | pwd = filePasswd((char *)optstate->value); |
1338 | if (!pwd) |
1339 | usage(program_name); |
1340 | break; |
1341 | |
1342 | case 'F': |
1343 | FIPSMODE = PR_TRUE; |
1344 | break; |
1345 | |
1346 | case 'p': |
1347 | if (!optstate->value) { |
1348 | PL_DestroyOptState(optstate); |
1349 | usage(program_name); |
1350 | } |
1351 | pwd = PL_strdup(optstate->value); |
1352 | break; |
1353 | |
1354 | case 'P': |
1355 | if (!optstate->value) { |
1356 | PL_DestroyOptState(optstate); |
1357 | usage(program_name); |
1358 | } |
1359 | dbPrefix = PL_strdup(optstate->value); |
1360 | break; |
1361 | |
1362 | case 't': |
1363 | if (!optstate->value) { |
1364 | PL_DestroyOptState(optstate); |
1365 | usage(program_name); |
1366 | } |
1367 | hash = findHash(optstate->value); |
1368 | if (hash == NULL) { |
1369 | PR_fprintf(PR_STDERR, "Invalid hash '%s'\n", |
1370 | optstate->value); |
1371 | usage(program_name); |
1372 | } |
1373 | break; |
1374 | case 'v': |
1375 | verbose = PR_TRUE; |
1376 | break; |
1377 | |
1378 | case 'V': |
1379 | verify = PR_TRUE; |
1380 | break; |
1381 | |
1382 | case 'H': |
1383 | PL_DestroyOptState(optstate); |
1384 | long_usage(program_name); |
1385 | return 1; |
1386 | break; |
1387 | |
1388 | case 'h': |
1389 | case '?': |
1390 | default: |
1391 | PL_DestroyOptState(optstate); |
1392 | usage(program_name); |
1393 | return 1; |
1394 | break; |
1395 | } |
1396 | } |
1397 | PL_DestroyOptState(optstate); |
1398 | |
1399 | if (!input_file) { |
| |
1400 | usage(program_name); |
1401 | return 1; |
1402 | } |
1403 | |
1404 | |
1405 | |
1406 | |
1407 | libname = PR_GetLibraryName(NULL, "softokn3"); |
1408 | assert(libname != NULL); |
| 14 | | Assuming 'libname' is not equal to null | |
|
| |
1409 | if (!libname) { |
| |
1410 | PR_fprintf(PR_STDERR, "getting softokn3 failed"); |
1411 | goto cleanup; |
1412 | } |
1413 | lib = PR_LoadLibrary(libname); |
1414 | assert(lib != NULL); |
| 17 | | Assuming 'lib' is not equal to null | |
|
| |
1415 | if (!lib) { |
| |
1416 | PR_fprintf(PR_STDERR, "loading softokn3 failed"); |
1417 | goto cleanup; |
1418 | } |
1419 | PR_FreeLibraryName(libname); |
1420 | |
1421 | if (FIPSMODE) { |
| |
1422 | |
1423 | |
1424 | pC_GetFunctionList = (CK_C_GetFunctionList) |
1425 | PR_FindFunctionSymbol(lib, "FC_GetFunctionList"); |
1426 | } else { |
1427 | |
1428 | pC_GetFunctionList = (CK_C_GetFunctionList) |
1429 | PR_FindFunctionSymbol(lib, "C_GetFunctionList"); |
1430 | } |
1431 | assert(pC_GetFunctionList != NULL); |
| 21 | | Assuming 'pC_GetFunctionList' is not equal to null | |
|
| |
1432 | if (!pC_GetFunctionList) { |
| |
1433 | PR_fprintf(PR_STDERR, "getting function list failed"); |
1434 | goto cleanup; |
1435 | } |
1436 | |
1437 | crv = (*pC_GetFunctionList)(&pFunctionList); |
1438 | assert(crv == CKR_OK); |
| 24 | | Assuming 'crv' is equal to 0 | |
|
| |
1439 | if (crv != CKR_OK) { |
| |
1440 | PR_fprintf(PR_STDERR, "loading function list failed"); |
1441 | goto cleanup; |
1442 | } |
1443 | |
1444 | if (configDir) { |
| |
1445 | if (!dbPrefix) { |
1446 | dbPrefix = PL_strdup(""); |
1447 | } |
1448 | crv = softokn_Init(pFunctionList, configDir, dbPrefix); |
1449 | if (crv != CKR_OK) { |
1450 | logIt("Failed to use provided database directory " |
1451 | "will just initialize the volatile certdb.\n"); |
1452 | crv = softokn_Init(pFunctionList, NULL, NULL); |
1453 | } |
1454 | } else { |
1455 | crv = softokn_Init(pFunctionList, NULL, NULL); |
1456 | } |
1457 | |
1458 | if (crv != CKR_OK) { |
| |
1459 | pk11error("Initiailzing softoken failed", crv); |
1460 | goto cleanup; |
1461 | } |
1462 | |
1463 | pSlotList = getSlotList(pFunctionList, slotIndex); |
1464 | if (pSlotList == NULL) { |
| |
1465 | PR_fprintf(PR_STDERR, "getSlotList failed"); |
1466 | goto cleanup; |
1467 | } |
1468 | |
1469 | crv = pFunctionList->C_OpenSession(pSlotList[slotIndex], |
1470 | CKF_RW_SESSION | CKF_SERIAL_SESSION, |
1471 | NULL, NULL, &hRwSession); |
1472 | if (crv != CKR_OK) { |
| 30 | | Assuming 'crv' is equal to CKR_OK | |
|
| |
1473 | pk11error("Opening a read/write session failed", crv); |
1474 | goto cleanup; |
1475 | } |
1476 | |
1477 | |
1478 | crv = pFunctionList->C_GetTokenInfo(pSlotList[slotIndex], &tokenInfo); |
1479 | if (crv != CKR_OK) { |
| 32 | | Assuming 'crv' is equal to CKR_OK | |
|
| |
1480 | pk11error("C_GetTokenInfo failed", crv); |
1481 | goto cleanup; |
1482 | } |
1483 | if (tokenInfo.flags & CKF_LOGIN_REQUIRED) { |
| 34 | | Assuming the condition is false | |
|
| |
1484 | if (pwd) { |
1485 | int pwdLen = strlen((const char *)pwd); |
1486 | crv = pFunctionList->C_Login(hRwSession, CKU_USER, |
1487 | (CK_UTF8CHAR_PTR)pwd, (CK_ULONG)pwdLen); |
1488 | if (crv != CKR_OK) { |
1489 | pk11error("C_Login failed", crv); |
1490 | goto cleanup; |
1491 | } |
1492 | } else { |
1493 | PR_fprintf(PR_STDERR, "Please provide the password for the token"); |
1494 | goto cleanup; |
1495 | } |
1496 | } else if (pwd) { |
| |
1497 | logIt("A password was provided but the password was not used.\n"); |
1498 | } |
1499 | |
1500 | |
1501 | ifd = PR_OpenFile(input_file, PR_RDONLY, 0); |
1502 | if (ifd == NULL) { |
| 37 | | Assuming 'ifd' is not equal to NULL | |
|
| |
1503 | lperror(input_file); |
1504 | goto cleanup; |
1505 | } |
1506 | #ifdef USES_LINKS |
1507 | ret = lstat(input_file, &stat_buf); |
1508 | if (ret < 0) { |
| |
| |
1509 | perror(input_file); |
1510 | goto cleanup; |
1511 | } |
1512 | if (S_ISLNK(stat_buf.st_mode)) { |
| 41 | | Assuming the condition is false | |
|
| |
1513 | char *dirpath, *dirend; |
1514 | ret = readlink(input_file, link_buf, sizeof(link_buf) - 1); |
1515 | if (ret < 0) { |
1516 | perror(input_file); |
1517 | goto cleanup; |
1518 | } |
1519 | link_buf[ret] = 0; |
1520 | link_file = mkoutput(input_file); |
1521 | |
1522 | dirpath = PL_strdup(input_file); |
1523 | dirend = strrchr(dirpath, '/'); |
1524 | if (dirend) { |
1525 | *dirend = '\0'; |
1526 | ret = chdir(dirpath); |
1527 | if (ret < 0) { |
1528 | perror(dirpath); |
1529 | goto cleanup; |
1530 | } |
1531 | } |
1532 | PL_strfree(dirpath); |
1533 | input_file = link_buf; |
1534 | |
1535 | dirend = strrchr(link_file, '/'); |
1536 | if (dirend) { |
1537 | char *tmp_file = NULL; |
1538 | tmp_file = PL_strdup(dirend + 1); |
1539 | PL_strfree(link_file); |
1540 | link_file = tmp_file; |
1541 | } |
1542 | } |
1543 | #endif |
1544 | if (output_file == NULL) { |
| |
1545 | output_file = mkoutput(input_file); |
1546 | } |
1547 | |
1548 | if (verbose) { |
| |
1549 | PR_fprintf(PR_STDERR, "Library File: %s\n", input_file); |
1550 | PR_fprintf(PR_STDERR, "Check File: %s\n", output_file); |
1551 | #ifdef USES_LINKS |
1552 | if (link_file) { |
1553 | PR_fprintf(PR_STDERR, "Link: %s\n", link_file); |
1554 | } |
1555 | #endif |
1556 | } |
1557 | |
1558 | |
1559 | ofd = PR_Open(output_file, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0666); |
1560 | if (ofd == NULL) { |
| 45 | | Assuming 'ofd' is not equal to NULL | |
|
| |
1561 | lperror(output_file); |
1562 | goto cleanup; |
1563 | } |
1564 | |
1565 | if (useDSA) { |
| |
1566 | crv = shlibSignDSA(pFunctionList, pSlotList[slotIndex], hRwSession, |
1567 | keySize, ifd, ofd, hash); |
1568 | } else { |
1569 | crv = shlibSignHMAC(pFunctionList, pSlotList[slotIndex], hRwSession, |
| 48 | | Calling 'shlibSignHMAC' | |
|
1570 | keySize, ifd, ofd, hash); |
1571 | } |
1572 | if (crv == CKR_INTERNAL_OUT_FAILURE) { |
1573 | lperror(output_file); |
1574 | } |
1575 | if (crv == CKR_INTERNAL_IN_FAILURE) { |
1576 | lperror(input_file); |
1577 | } |
1578 | |
1579 | PR_Close(ofd); |
1580 | ofd = NULL; |
1581 | |
1582 | PR_Close(ifd); |
1583 | ifd = NULL; |
1584 | |
1585 | #ifdef USES_LINKS |
1586 | if (link_file) { |
1587 | (void)unlink(link_file); |
1588 | ret = symlink(output_file, link_file); |
1589 | if (ret < 0) { |
1590 | perror(link_file); |
1591 | goto cleanup; |
1592 | } |
1593 | } |
1594 | #endif |
1595 | successful = PR_TRUE; |
1596 | |
1597 | cleanup: |
1598 | if (pFunctionList) { |
1599 | |
1600 | |
1601 | crv = pFunctionList->C_Finalize(NULL); |
1602 | if (crv != CKR_OK) { |
1603 | pk11error("C_Finalize failed", crv); |
1604 | } |
1605 | } |
1606 | if (pSlotList) { |
1607 | PR_Free(pSlotList); |
1608 | } |
1609 | if (pwd) { |
1610 | PL_strfree(pwd); |
1611 | } |
1612 | if (configDir) { |
1613 | PL_strfree(configDir); |
1614 | } |
1615 | if (dbPrefix) { |
1616 | PL_strfree(dbPrefix); |
1617 | } |
1618 | if (output_file) { |
1619 | PL_strfree(output_file); |
1620 | } |
1621 | #ifdef USES_LINKS |
1622 | if (link_file) { |
1623 | PL_strfree(link_file); |
1624 | } |
1625 | #endif |
1626 | if (ifd) { |
1627 | PR_Close(ifd); |
1628 | } |
1629 | if (ofd) { |
1630 | PR_Close(ofd); |
1631 | } |
1632 | |
1633 | disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD"); |
1634 | if (!disableUnload && lib) { |
1635 | PR_UnloadLibrary(lib); |
1636 | } |
1637 | PR_Cleanup(); |
1638 | |
1639 | if (crv != CKR_OK) |
1640 | return crv; |
1641 | |
1642 | return (successful) ? 0 : 1; |
1643 | } |