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